diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java index a07b78b17f..9520a06943 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java @@ -37,9 +37,6 @@ import org.gradle.api.file.FileCollection; import org.gradle.api.file.ProjectLayout; import org.gradle.api.file.RegularFileProperty; -import org.gradle.api.java.archives.Attributes; -import org.gradle.api.java.archives.ManifestException; -import org.gradle.api.java.archives.ManifestMergeSpec; import org.gradle.api.java.archives.internal.DefaultManifest; import org.gradle.api.model.ObjectFactory; import org.gradle.api.provider.ListProperty; @@ -66,7 +63,6 @@ import aQute.lib.io.IO; import aQute.lib.strings.Strings; import aQute.lib.utf8properties.UTF8Properties; -import groovy.lang.Closure; /** * BundleTaskExtension for Gradle. @@ -100,7 +96,6 @@ public class BundleTaskExtension { private final ConfigurableFileCollection classpath; private final Provider bnd; private final MapProperty properties; - private final EffectiveManifest effectiveManifest; /** * The bndfile property. @@ -216,12 +211,6 @@ public BundleTaskExtension(org.gradle.api.tasks.bundling.Jar task) { classpath(mainSourceSet.getCompileClasspath()); properties = objects.mapProperty(String.class, Object.class) .convention(Maps.of("project", "__convention__")); - // Wrap manifest - org.gradle.api.java.archives.Manifest manifest = task.getManifest(); - effectiveManifest = new EffectiveManifest(manifest); - if (manifest != null) { - task.setManifest(effectiveManifest); - } // need to programmatically add to inputs since @InputFiles in a // extension is not processed task.getInputs() @@ -367,6 +356,8 @@ public void execute(Task t) { File buildDir = unwrapFile(getLayout().getBuildDirectory()); File buildFile = getBuildFile(); FileCollection sourcepath = getAllSource().filter(file -> file.exists()); + Optional taskManifest = Optional + .ofNullable(getTask().getManifest()); // create Builder Properties gradleProperties = new BeanProperties(); gradleProperties.putAll(unwrap(getProperties())); @@ -379,14 +370,14 @@ public void execute(Task t) { try (Writer writer = IO.writer(temporaryBndFile)) { // write any task manifest entries into the tmp bnd // file - Optional properties = Optional.ofNullable(getTask().getManifest()) - .map(manifest -> MapStream.ofNullable(manifest.getEffectiveManifest() + Optional properties = taskManifest.map(manifest -> MapStream + .ofNullable(manifest.getEffectiveManifest() .getAttributes()) - .filterKey(key -> !Objects.equals(key, "Manifest-Version")) - .mapValue(Object::toString) - .collect(MapStream.toMap((k1, k2) -> { - throw new IllegalStateException("Duplicate key " + k1); - }, UTF8Properties::new))); + .filterKey(key -> !Objects.equals(key, "Manifest-Version")) + .mapValue(Object::toString) + .collect(MapStream.toMap((k1, k2) -> { + throw new IllegalStateException("Duplicate key " + k1); + }, UTF8Properties::new))); if (properties.isPresent()) { properties.get() .replaceHere(projectDir) @@ -514,8 +505,15 @@ public void execute(Task t) { builtJar.write(archiveFile); long now = System.currentTimeMillis(); archiveFile.setLastModified(now); - // Set effective manifest to generated manifest - effectiveManifest.setEffectiveManifest(builtJar.getManifest()); + // Set effective manifest from generated manifest + Manifest builtManifest = builtJar.getManifest(); + taskManifest.ifPresent( + manifest -> manifest.from(mergeManifest(builtManifest), merge -> merge.eachEntry(details -> { + if (details.getMergeValue() == null) { + // exclude if entry not in merge manifest + details.exclude(); + } + }))); logReport(builder, getTask().getLogger()); if (!builder.isOk()) { failTask("Bundle " + archiveFileName + " has errors", archiveFile); @@ -526,6 +524,14 @@ public void execute(Task t) { } } + private org.gradle.api.java.archives.Manifest mergeManifest(Manifest builtManifest) { + org.gradle.api.java.archives.Manifest mergeManifest = new DefaultManifest(null); + mergeManifest.attributes(new AttributesMap(builtManifest.getMainAttributes())); + builtManifest.getEntries() + .forEach((section, attrs) -> mergeManifest.attributes(new AttributesMap(attrs), section)); + return mergeManifest; + } + private void failTask(String msg, File archiveFile) { IO.delete(archiveFile); throw new GradleException(msg); @@ -537,80 +543,6 @@ private boolean isEmpty(String header) { } } - static final class EffectiveManifest implements org.gradle.api.java.archives.Manifest { - final org.gradle.api.java.archives.Manifest delegate; - Manifest effectiveManifest; - - EffectiveManifest(org.gradle.api.java.archives.Manifest delegate) { - this.delegate = delegate; - this.effectiveManifest = null; - } - - void setEffectiveManifest(Manifest effectiveManifest) { - this.effectiveManifest = effectiveManifest; - } - - @Override - public org.gradle.api.java.archives.Manifest attributes(Map attributes) throws ManifestException { - delegate.attributes(attributes); - return this; - } - - @Override - public org.gradle.api.java.archives.Manifest attributes(Map attributes, String sectionName) - throws ManifestException { - delegate.attributes(attributes, sectionName); - return this; - } - - @Override - public org.gradle.api.java.archives.Manifest from(Object... mergePath) { - delegate.from(mergePath); - return this; - } - - @Override - public org.gradle.api.java.archives.Manifest from(Object mergePath, Closure closure) { - delegate.from(mergePath, closure); - return this; - } - - @Override - public org.gradle.api.java.archives.Manifest from(Object mergePath, Action action) { - delegate.from(mergePath, action); - return this; - } - - @Override - public Attributes getAttributes() { - return delegate.getAttributes(); - } - - @Override - public org.gradle.api.java.archives.Manifest getEffectiveManifest() { - Manifest effectiveManifest = this.effectiveManifest; - if (effectiveManifest == null) { - return delegate.getEffectiveManifest(); - } - org.gradle.api.java.archives.Manifest result = new DefaultManifest(null); - result.attributes(new AttributesMap(effectiveManifest.getMainAttributes())); - effectiveManifest.getEntries() - .forEach((section, attrs) -> result.attributes(new AttributesMap(attrs), section)); - return result; - } - - @Override - public Map getSections() { - return delegate.getSections(); - } - - @Override - public org.gradle.api.java.archives.Manifest writeTo(Object path) { - getEffectiveManifest().writeTo(path); - return this; - } - } - static final class AttributesMap extends AbstractMap { final java.util.jar.Attributes source;