[英]Custom manifest added multiple times in -post-jar in a common dependency
I have a multi-module native Netbeans Java EE project. 我有一个多模块本机Netbeans Java EE项目。 In it I have a Java Class Library
project that is used by multiple other projects which in turn are packaged into the root .ear
project. 在其中,我有一个Java Class Library
项目,该项目由多个其他项目使用,这些项目又打包到根.ear
项目中。
I'm adding the "build timestamp" and the "build user" attributes to a custom manifest using the library's build.xml
: 我正在使用库的build.xml
将“ build timestamp”和“ build user”属性添加到自定义清单中:
<target name="-post-jar">
<jar destfile="${dist.jar}" update="true">
<manifest>
When I "clean and build" the root project, each project that refers the library calls: 当我“清理并构建”根项目时,引用该库的每个项目都将调用:
<ant antfile="${call.script}" target="jar">
And my -post-jar
target is called multiple times. 我的-post-jar
目标被多次调用。 This wouldn't be a problem, but sometimes the second invocation of the <jar>
task fails with Unable to rename old file
(probably due to Netbeans scanning the files in background, but I can't tell for sure). 这不会有问题,但是有时<jar>
任务的第二次调用因Unable to rename old file
而失败(可能是由于Netbeans在后台扫描文件,但我不能确定)。
There are repeating pairs of Building jar
and Updating jar
messages in Ant's output. Ant的输出中有重复的Building jar
和Updating jar
消息对。 However, if I remove my -post-jar
target, the second invocation of the jar
target does nothing, because it thinks that the jar is up to date and I see only one Building jar
message. 但是,如果删除我的-post-jar
目标,则第二次调用jar
目标不会执行任何操作,因为它认为该jar是最新的,并且我仅看到一条Building jar
消息。
How do I mark the updated jar up to date, so the second invocation of the jar
target does nothing? 如何将更新的jar标记为最新,因此jar
目标的第二次调用什么都不做?
There's a github repo that demonstrates the problem. 有一个github仓库展示了这个问题。
I haven't found a way to not re-generate the manifest every time, but I found a way to make the generated file look the same as the zipped file (and we know that the <jar>
task doesn't repack when the contents are the same). 我没有找到不每次都重新生成清单的方法,但是我找到了一种使生成的文件看起来与压缩文件相同的方法(而且我们知道<jar>
任务不会在重新打包时重新打包)。内容相同)。
Instead of updating the zipped manifest in -post-jar
I now update the source file in -pre-jar
. 相反,在更新压缩清单的-post-jar
我现在更新的源文件-pre-jar
。 This way the final version of the manifest is zipped and since its contents don't change during build, subsequent <jar>
invocations update nothing. 这样,清单的最终版本将被压缩,并且由于其内容在构建期间不会更改,因此后续的<jar>
调用不会更新任何内容。
It worth mentioning that before adding the attributes Main-Class
, Profile
, etc. the build-impl.xml
of Netbeans creates an empy manifest template, if the user doesn't provide a valid path in the manifest.file=
property. 值得一提的是,如果用户未在manifest.file=
属性中提供有效路径,则在添加属性Main-Class
, Profile
等build-impl.xml
,Netbeans的build-impl.xml
将创建一个empy清单模板。 The addition happens after -pre-jar
, however the existence of the user-provided manifest is checked much earlier, during the init
target and the result is saved to the manifest.available
property. 添加发生在 -pre-jar
,但是会在init
目标期间更早地检查用户提供的清单的存在,并将结果保存到manifest.available
属性。
My manifest template is not a static file. 我的清单模板不是静态文件。 It contains the "build timestamp" and the "build user" attributes. 它包含“构建时间戳记”和“构建用户”属性。 Therefore the file doesn't exist during the init
target, so I had to add the following line at the beginning of my build.xml
: 因此,在init
目标期间该文件不存在,因此我必须在build.xml
的开头添加以下行:
<property name="manifest.available" value="true"/><!-- It will be available by the time we need it -->
Secondly, manifest.file
still has to be set and I set it in project.properties
(there's no UI for that setting yet and I wonder how it would behave in the presence of the variable in path) 其次, manifest.file
仍然必须设置,我在project.properties
设置它(该设置还没有UI,我想知道在路径中存在变量时它的行为如何)
manifest.file=${build.dir}/manifest.tmp
Next, I overwrite the manifest template in the -pre-jar
target: 接下来,我覆盖-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>
After that, the new problem became obvious: the timestamp was different for each invocation of 此后,新问题变得显而易见:每次调用的时间戳都不同
<ant antfile="mylib/build.xml" target="jar">
in the multi-module project and Ant had to repack the jar with the new timestamp in the manifest. 在多模块项目中,Ant必须用清单中的新时间戳重新打包jar。 I solved this by defining the timestamp property in every project's build.xml
. 我通过在每个项目的build.xml
定义timestamp属性来解决此问题。 Although the properties are not inherited due to inheritall="false"
, Netbeans allows for overcoming that: 尽管由于inheritall="false"
而未继承属性,但Netbeans允许克服以下情况:
<property name="transfer.current.time" value="${current.time}"/>
This mechanism is broken in Java EE projects, but the workaround is simple: 该机制在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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.