在公共依赖项中的 -post-jar 中多次添加自定义清单
Custom manifest added multiple times in -post-jar in a common dependency
我有一个多模块原生 Netbeans Java EE 项目。在其中我有一个 Java Class Library
项目,该项目被多个其他项目使用,这些项目又被打包到根 .ear
项目中。
我正在使用库的 build.xml
:
将 "build timestamp" 和 "build user" 属性添加到自定义清单
<target name="-post-jar">
<jar destfile="${dist.jar}" update="true">
<manifest>
当我"clean and build"根项目时,引用库的每个项目调用:
<ant antfile="${call.script}" target="jar">
我的 -post-jar
目标被多次调用。这不是问题,但有时 <jar>
任务的第二次调用会因 Unable to rename old file
而失败(可能是由于 Netbeans 在后台扫描文件,但我不能确定)。
Ant 的输出中有重复的 Building jar
和 Updating jar
消息对。但是,如果我删除我的 -post-jar
目标,第二次调用 jar
目标不会执行任何操作,因为它认为 jar 是最新的并且我只看到一个 Building jar
消息。
如何将更新的 jar 标记为最新,以便 jar
目标的第二次调用不执行任何操作?
有一个 github repo 证明了这个问题。
我还没有找到一种方法不是每次都重新生成清单,但我找到了一种方法使生成的文件看起来与压缩文件相同(我们知道当内容相同时 <jar>
任务不会重新打包。
我现在更新 -pre-jar
中的源文件,而不是更新 -post-jar
中的压缩清单。通过这种方式,清单的最终版本被压缩,并且由于其内容在构建期间不会更改,因此后续 <jar>
调用不会更新任何内容。
值得一提的是,在添加属性Main-Class
、Profile
等之前,Netbeans的build-impl.xml
会创建一个empy清单模板,如果用户没有提供有效的manifest.file=
属性 中的路径。添加发生在 -pre-jar
之后,但是在 init
目标期间会更早地检查用户提供的清单是否存在,并将结果保存到 manifest.available
属性.
我的清单模板不是静态文件。它包含 "build timestamp" 和 "build user" 属性。因此该文件在 init
目标期间不存在,因此我不得不在 build.xml
:
的开头添加以下行
<property name="manifest.available" value="true"/><!-- It will be available by the time we need it -->
其次,manifest.file
仍然需要设置,我将其设置为 project.properties
(该设置还没有 UI,我想知道它在存在的情况下会如何表现路径中的变量)
manifest.file=${build.dir}/manifest.tmp
接下来,我覆盖 -pre-jar
目标中的清单模板:
<tstamp>
<format property="current.time" pattern="HH:mm:ss" locale="de,DE"/>
</tstamp>
<target name="-pre-jar" >
<manifest file="${manifest.file}">
<attribute name="MyApp-built-time" value="${current.time}"/>
<attribute name="MyApp-built-by" value="${user.name}"/>
</manifest>
之后,新问题变得明显:每次调用的时间戳都不一样
<ant antfile="mylib/build.xml" target="jar">
在多模块项目中,Ant 必须使用清单中的新时间戳重新打包 jar。我通过在每个项目的 build.xml
中定义时间戳 属性 来解决这个问题。尽管由于 inheritall="false"
而无法继承属性,但 Netbeans 允许克服以下问题:
<property name="transfer.current.time" value="${current.time}"/>
此机制在 Java 个 EE 项目中被破坏,但解决方法很简单:
<presetdef name="ant">
<!-- workaround transfer.* not working in Java EE projects -->
<ant>
<propertyset>
<propertyref prefix="transfer."/>
<mapper from="transfer.*" to="*" type="glob"/>
</propertyset>
</ant>
</presetdef>
我有一个多模块原生 Netbeans Java EE 项目。在其中我有一个 Java Class Library
项目,该项目被多个其他项目使用,这些项目又被打包到根 .ear
项目中。
我正在使用库的 build.xml
:
<target name="-post-jar">
<jar destfile="${dist.jar}" update="true">
<manifest>
当我"clean and build"根项目时,引用库的每个项目调用:
<ant antfile="${call.script}" target="jar">
我的 -post-jar
目标被多次调用。这不是问题,但有时 <jar>
任务的第二次调用会因 Unable to rename old file
而失败(可能是由于 Netbeans 在后台扫描文件,但我不能确定)。
Ant 的输出中有重复的 Building jar
和 Updating jar
消息对。但是,如果我删除我的 -post-jar
目标,第二次调用 jar
目标不会执行任何操作,因为它认为 jar 是最新的并且我只看到一个 Building jar
消息。
如何将更新的 jar 标记为最新,以便 jar
目标的第二次调用不执行任何操作?
有一个 github repo 证明了这个问题。
我还没有找到一种方法不是每次都重新生成清单,但我找到了一种方法使生成的文件看起来与压缩文件相同(我们知道当内容相同时 <jar>
任务不会重新打包。
我现在更新 -pre-jar
中的源文件,而不是更新 -post-jar
中的压缩清单。通过这种方式,清单的最终版本被压缩,并且由于其内容在构建期间不会更改,因此后续 <jar>
调用不会更新任何内容。
值得一提的是,在添加属性Main-Class
、Profile
等之前,Netbeans的build-impl.xml
会创建一个empy清单模板,如果用户没有提供有效的manifest.file=
属性 中的路径。添加发生在 -pre-jar
之后,但是在 init
目标期间会更早地检查用户提供的清单是否存在,并将结果保存到 manifest.available
属性.
我的清单模板不是静态文件。它包含 "build timestamp" 和 "build user" 属性。因此该文件在 init
目标期间不存在,因此我不得不在 build.xml
:
<property name="manifest.available" value="true"/><!-- It will be available by the time we need it -->
其次,manifest.file
仍然需要设置,我将其设置为 project.properties
(该设置还没有 UI,我想知道它在存在的情况下会如何表现路径中的变量)
manifest.file=${build.dir}/manifest.tmp
接下来,我覆盖 -pre-jar
目标中的清单模板:
<tstamp>
<format property="current.time" pattern="HH:mm:ss" locale="de,DE"/>
</tstamp>
<target name="-pre-jar" >
<manifest file="${manifest.file}">
<attribute name="MyApp-built-time" value="${current.time}"/>
<attribute name="MyApp-built-by" value="${user.name}"/>
</manifest>
之后,新问题变得明显:每次调用的时间戳都不一样
<ant antfile="mylib/build.xml" target="jar">
在多模块项目中,Ant 必须使用清单中的新时间戳重新打包 jar。我通过在每个项目的 build.xml
中定义时间戳 属性 来解决这个问题。尽管由于 inheritall="false"
而无法继承属性,但 Netbeans 允许克服以下问题:
<property name="transfer.current.time" value="${current.time}"/>
此机制在 Java 个 EE 项目中被破坏,但解决方法很简单:
<presetdef name="ant">
<!-- workaround transfer.* not working in Java EE projects -->
<ant>
<propertyset>
<propertyref prefix="transfer."/>
<mapper from="transfer.*" to="*" type="glob"/>
</propertyset>
</ant>
</presetdef>