Launch4j wrapper is rebuilt every time jar changes even with dontWrapJar enabled
maikelsteneker opened this issue · comments
I'm using the following combination of properties for my launch4j task:
dontWrapJar = true
jarTask = executable.get()
The task executable
is a custom task that produces a jar file.
Note that the dontWrapJar
option implies that if the JAR changes, there's no need for the launch4j wrapper to change. However, when running gradle executable createExe
, the createExe
(launch4j) task rebuilds every time the jar has changed:
Task ':createExe' is not up-to-date because:
Input property '$1' file project/build/test.jar has changed.
Is there a way to change this behaviour?
dontWrapJar
option implies that if the JAR changes, there's no need for the launch4j wrapper to change
Actually, if the path to JAR file changes (this includes filename change), exe needs to be changed as well. But, even if we would track the change of JAR output path and content separately, it won't help to avoid task rebuild, because exe creation is not the only thing createExe
task does. If dontWrapJar=true
it also by default copies JAR (and all other runtimeClasspath dependencies) into libraryDir
(so, changes to the JAR content would require its recopying).
Default copying behavior may be disabled by setting the copyConfigurable
property, but it doesn't make sense if dontWrapJar=true
(unless you also specify libraryDir
pointing to the original JAR parent folder).
So, this optimization is applicable only for the very specific configuration, and the trickiest part here is to determine whether JAR output is still present in copyConfigurable
(in that case dependency on JAR content should be preserved), which could hold various types of input files representations (completely disabling input dependency on JAR contents for dontWrapJar=true
and any non-default copyConfigurable
would be a breaking change).
This probably could be implemented by extracting copying operations from createExe
into a separate task and depending on it.
This way dependency on input from jarTask
may be declared as:
def jar = jarTask.outputs.files.singleFile
if (getDontWrapJar() && !copyingTask.outputs.files.contains(jar)) {
inputs.property("jarPath", jar.toPath())
} else {
inputs.files(jar)
}
As @naftalmm put it very well. I don't think such special cases are worth the hassle.