I need to modify Manifest file during the assembly of WAR file. I need to add a list of all files on a class path to avoid java.io.IOException: CreateProcess error=206, The filename or extension is too long
exception being thrown when I want to execute this java file on Windows machine.
Declared directly in build script this task does the work.
task pathingWar(type: War) { getArchiveAppendix().set("pathing") doFirst { manifest { attributes "Class-Path": sourceSets.main.runtimeClasspath.files.collect { project.uri(it) }.join(" ") } } }
However I wanted to create a standalone task in buildSrc directory like in the code below. War gets created with the pathing appendix in name, but there is no additional Class-Path
property inside MANIFEST.MF
file even if classpathFiles
variable holds required values while debugging the execution of the task.
class PathingWar extends War { PathingWar() { getArchiveAppendix().set("pathing") } @TaskAction def setManifestTask() { def classpathFiles = ((SourceSet)((SourceSetContainer) getProject().getExtensions().getByName("sourceSets")) .getByName("main")).getRuntimeClasspath().getFiles().collect {project.uri(it)}.join(" ") setManifest(getManifest().attributes(["Class-Path": classpathFiles])) } }
Attributes won’t be set to the Manifest, what did I missed when translating logic from build script to custom task?
Update
After further inspection I see that when setManifestTask()
annotated with @TaskAction
is being executed is already being too late. At this point war is generated under the build/libs
folder. I need another way of configuring the manifest. I don’t know which other approach to use.
Advertisement
Answer
I tried to set manifest Class-Path attribute in the doFirst{}
block so that it would be set as first action and similar like in the original script without a success. Still jar was generated before closure in doFirst
was executed.
After I read the following answer https://stackoverflow.com/a/16413207/978302 I understood I shouldn’t be overriding functionality of a War task. Instead I have to configure it with available inputs and result will be generated behind the scenes.
Final solution doesn’t contain any actions defined. Only additional configuration for:
- archivaAppendix
- manifest
Task definition:
class PathingWar extends War { PathingWar() { getArchiveAppendix().set("pathing") manifest { def classpathFiles = ((SourceSet) ((SourceSetContainer) getProject().getExtensions().getByName("sourceSets")) .getByName("main")).getRuntimeClasspath().getFiles().collect { project.uri(it) }.join(" ") attributes "Class-Path": classpathFiles } } }
BTW: I still don’t understand why the task defined in script works as expected.