How to edit and merge two Manifest.MF files with gradle?

Hello everyone, I have a question concerning the Manifest file of a subproject. I wanted to use an existing Manifest.MF file and add a few information from a second Manifest file to the original one which are needed later for a tycho build and also delete a few entries. Is there a build in way of gradle to perform such a process?

I am currently using the method from your example:

task buildMF( type: Jar ) {

manifest {

from( ‘META-INF/MANIFEST.MF’, ‘BUILD-META/MANIFEST.MF’ ) {

eachEntry { details ->

if (details.baseValue != details.mergeValue) {

details.value = baseValue

}

}

}

}

jar.manifest.writeTo("$buildDir/MANIFESTO.MF") }

However I get the following error:

  • What went wrong: Could not copy MANIFEST.MF to ‘/Users/Uni/de.prob.core.rodin/build/tmp/buildMF/MANIFEST.MF’.

  • Try: Run with --info or --debug option to get more log output.

  • Exception is: org.gradle.api.GradleException: Could not copy MANIFEST.MF to ‘/Users/Uni/de.prob.core.rodin/build/tmp/buildMF/MANIFEST.MF’.

at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:68)

at org.gradle.api.internal.file.collections.MapFileTree$FileVisitDetailsImpl.getFile(MapFileTree.java:133)

at org.gradle.api.internal.file.AbstractFileTree$1.visitFile(AbstractFileTree.java:39)

at org.gradle.api.internal.file.AbstractFileTree$FilteredFileTree$1.visitFile(AbstractFileTree.java:145)

at org.gradle.api.internal.file.collections.MapFileTree$Visit.visit(MapFileTree.java:103)

at org.gradle.api.internal.file.collections.MapFileTree.visit(MapFileTree.java:70)

at org.gradle.api.internal.file.collections.FileTreeAdapter.visit(FileTreeAdapter.java:96)

at org.gradle.api.internal.file.AbstractFileTree$FilteredFileTree.visit(AbstractFileTree.java:136)

at org.gradle.api.internal.file.AbstractFileTree.getFiles(AbstractFileTree.java:37)

at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:39)

at org.gradle.api.internal.file.AbstractFileCollection.iterator(AbstractFileCollection.java:60)

at org.gradle.api.internal.changedetection.DefaultFileSnapshotter.snapshot(DefaultFileSnapshotter.java:42)

at org.gradle.api.internal.changedetection.InputFilesChangedUpToDateRule.create(InputFilesChangedUpToDateRule.java:35)

at org.gradle.api.internal.changedetection.CompositeUpToDateRule.create(CompositeUpToDateRule.java:35)

at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateRepository$HistoricExecution.calcCurrentState(DefaultTaskArtifactStateRepository.java:80)

at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateRepository$HistoricExecution.isUpToDate(DefaultTaskArtifactStateRepository.java:88)

at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.isUpToDate(DefaultTaskArtifactStateRepository.java:128)

at org.gradle.api.internal.changedetection.ShortCircuitTaskArtifactStateRepository$ShortCircuitArtifactState.isUpToDate(ShortCircuitTaskArtifactStateRepository.java:77)

at org.gradle.api.internal.changedetection.FileCacheBroadcastTaskArtifactStateRepository$1.isUpToDate(FileCacheBroadcastTaskArtifactStateRepository.java:37)

at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:44)

at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:57)

at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:41)

at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)

at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:52)

at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:42)

at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:247)

at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.executeTask(DefaultTaskPlanExecutor.java:52)

at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.processTask(DefaultTaskPlanExecutor.java:38)

at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:30)

at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:83)

at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)

at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)

at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)

at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)

at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter$1.run(TaskCacheLockHandlingBuildExecuter.java:31)

at org.gradle.cache.internal.DefaultCacheAccess$2.create(DefaultCacheAccess.java:118)

at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:133)

at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:116)

at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:129)

at org.gradle.api.internal.changedetection.DefaultTaskArtifactStateCacheAccess.useCache(DefaultTaskArtifactStateCacheAccess.java:79)

at org.gradle.api.internal.changedetection.TaskCacheLockHandlingBuildExecuter.execute(TaskCacheLockHandlingBuildExecuter.java:29)

at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)

at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)

at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)

at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)

at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)

at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)

at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:158)

at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113)

at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81)

at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:38)

at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:39)

at org.gradle.launcher.exec.InProcessGradleLauncherActionExecuter.execute(InProcessGradleLauncherActionExecuter.java:25)

at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)

at org.gradle.launcher.cli.ActionAdapter.execute(ActionAdapter.java:30)

at org.gradle.launcher.cli.ActionAdapter.execute(ActionAdapter.java:22)

at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:200)

at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:173)

at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)

at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:138)

at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)

at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)

at org.gradle.launcher.Main.doAction(Main.java:48)

at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)

at org.gradle.launcher.Main.main(Main.java:39)

at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50)

at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32)

at org.gradle.launcher.GradleMain.main(GradleMain.java:26) Caused by: org.codehaus.groovy.runtime.InvokerInvocationException: org.gradle.api.internal.MissingMethodException: Could not find method eachEntry() for arguments [build_7nt2k4hjubpj7d3l7jdt5lakn6$_run_closure3_closure8_closure9_closure10@271e83e] on project ‘:de.prob.core.rodin’.

at org.gradle.api.internal.file.collections.MapFileTree$FileVisitDetailsImpl.copyTo(MapFileTree.java:151)

at org.gradle.api.internal.file.AbstractFileTreeElement.copyFile(AbstractFileTreeElement.java:82)

at org.gradle.api.internal.file.AbstractFileTreeElement.copyTo(AbstractFileTreeElement.java:63)

… 67 more Caused by: org.gradle.api.internal.MissingMethodException: Could not find method eachEntry() for arguments [build_7nt2k4hjubpj7d3l7jdt5lakn6$_run_closure3_closure8_closure9_closure10@271e83e] on project ‘:de.prob.core.rodin’.

at org.gradle.api.internal.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:68)

at org.gradle.api.internal.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:56)

at org.gradle.api.internal.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:172)

at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:83)

at build_7nt2k4hjubpj7d3l7jdt5lakn6$_run_closure3_closure8_closure9.doCall(/Users/Uni/de.prob.core.rodin/build.gradle:45)

at build_7nt2k4hjubpj7d3l7jdt5lakn6$_run_closure3_closure8_closure9.doCall(/Users/Uni/de.prob.core.rodin/build.gradle)

at org.gradle.api.internal.file.AbstractFileResolver.unpack(AbstractFileResolver.java:176)

at org.gradle.api.internal.file.AbstractFileResolver.convertObjectToFile(AbstractFileResolver.java:160)

at org.gradle.api.internal.file.BaseDirFileResolver.doResolve(BaseDirFileResolver.java:71)

at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:57)

at org.gradle.api.internal.file.AbstractFileResolver.resolve(AbstractFileResolver.java:53)

at org.gradle.api.java.archives.internal.DefaultManifest.read(DefaultManifest.java:203)

at org.gradle.api.java.archives.internal.DefaultManifest.(DefaultManifest.java:52)

at org.gradle.api.java.archives.internal.DefaultManifestMergeSpec.createManifest(DefaultManifestMergeSpec.java:116)

at org.gradle.api.java.archives.internal.DefaultManifestMergeSpec.merge(DefaultManifestMergeSpec.java:55)

at org.gradle.api.java.archives.internal.DefaultManifest.getEffectiveManifestInternal(DefaultManifest.java:144)

at org.gradle.api.java.archives.internal.DefaultManifest.getEffectiveManifest(DefaultManifest.java:138)

at org.gradle.api.java.archives.internal.DefaultManifest.writeTo(DefaultManifest.java:152)

at org.gradle.api.java.archives.internal.DefaultManifest.writeTo(DefaultManifest.java:36)

at org.gradle.api.java.archives.Manifest$writeTo$0.call(Unknown Source)

at org.gradle.api.tasks.bundling.Jar$_closure1_closure3.doCall(Jar.groovy:48)

… 70 more

BUILD FAILED

Thank you very much in advance for any help!

manifest.from works with resource files that live in your project structure. Looking at your build it seems that you expect the manifest.from work with manifests included in the jar.

jar.manifest.from(“path/relative/to/project”, “src/main/resources/META-INF/MANIFEST.MF”)

I think the exception should be better on the Gradle side.

Hope that helps!

Actually I just wanted two Manifest Scripts from my workspace to be merged, unfortunately it still doesn’t work.

The task looks now like this:

task buildMF( type: Jar ) {

manifest {

from( ‘META-INF/MANIFEST.MF’ , ‘BUILD-META/MANIFEST.MF’){

eachEntry{ details ->

if (details.baseValue != details.mergeValue) {

details.value = baseValue

}

}

}

}

}

Output:

FAILURE: Build failed with an exception.

  • What went wrong: Could not copy MANIFEST.MF to ‘/Users/Mike/prob2Current/prob2/de.prob.core.rodin/build/tmp/buildMF/MANIFEST.MF’.

I am very sorry but I can’t find the mistake. Thank you very much for your help!

I tried the following code from the gradle samples folder on two different computers

task barJar(type: Jar) {

manifest {

from(‘src/config/javabasemanifest.txt’, ‘src/config/libbasemanifest.txt’) {

eachEntry { details ->

if (details.baseValue != details.mergeValue) {

details.value = baseValue

}

if (details.key == ‘foo’) {

details.exclude()

}

}

}

} }

and I still get the same error:

FAILURE: Build failed with an exception.

  • What went wrong: Could not copy MANIFEST.MF to ‘/Users/Uni/prob2/prob2Current/prob2/de.prob.core.rodin/build/tmp/barJar/MANIFEST.MF’.

However when I just use this code snippet;

task barJar(type: Jar) {

manifest {

from(‘src/config/javabasemanifest.txt’, ‘src/config/libbasemanifest.txt’)

} }

it works, and merges the two files. But as soon as I want to edit the merge behavior I get the same error mentioned above again.

Is there anything else which needs to be implemented to edit the merge behavior?

Again I’m very sorry for the trouble but for some reason it won’t work.