Maven Assembly Plugin
  1. Maven Assembly Plugin
  2. MASSEMBLY-450

manifestEntries ignored when manfestFile is specified

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.2-beta-4
    • Fix Version/s: None
    • Component/s: manifest
    • Labels:
      None
    • Number of attachments :
      1

      Description

      The maven jar plugin supports the behavior of manifestEntries overriding the manifestFile as indicated here:

      http://maven.apache.org/guides/mini/guide-manifest.html

      However, within the maven assembly plugin, if manifestFile is specified, manifestEntries is ignored.

      Reproduction
      ============

      > unzip example.zip
      > cd example
      > mvn package
      > cd target
      > unzip example-4.2-plugin.jar
      > cat META-INF/MANFEST
      

      Results:

      Manifest-Version: 1.0
      Archiver-Version: Plexus Archiver
      Created-By: 14.0-b16 (Sun Microsystems Inc.)
      Bundle-ManifestVersion: 2
      Bundle-Name: example
      Bundle-SymbolicName: example; singleton:=true
      Bundle-Version: 1.0
      

      Expected:

      Manifest-Version: 1.0
      Archiver-Version: Plexus Archiver
      Created-By: 14.0-b16 (Sun Microsystems Inc.)
      Bundle-ManifestVersion: 2
      Bundle-Name: example
      Bundle-SymbolicName: example; singleton:=true
      Bundle-Version: 4.2
      

      The problem appears to be in the class ManifestConfigurationFinalizer:

      if ( manifestFile != null )
      {
         ...
         manifest = new Manifest( manifestFileReader );
         ...
      }
      else
      {
         manifest = mavenArchiver.getManifest( project, archiveConfiguration.getManifest() );
      }
      

      I believe the fix is to change to the following (this already handles merging the manifest file with the configured manifestEntries)

      manifest = mavenArchiver.getManifest( project, archiveConfiguration );
      

        Issue Links

          Activity

          Hide
          Mirko Raner added a comment -

          I'm struggling with the same issue. I have an existing MANIFEST.MF file with a dummy version number, and I'd like to use the actual Maven build version in the final manifest instead:

          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
          <archive>
          <manifestFile>META-INF/MANIFEST.MF</manifestFile>
          <manifestEntries>
          <Bundle-Version>$

          {version}

          </Bundle-Version>
          </manifestEntries>
          </archive>
          </configuration>

          I'm not entirely convinced that it was a good choice to have the presence of a <manifestFile> element override other directives, such as <manifestEntries>. I think that intuitively most developers would expect both elements to be honored and the entries to be merged in a reasonable way. Changing this behavior would obviously break existing POMs out there that rely on the <manifestFile>overrides<manifestEntries> semantics, though I would venture that the presence of both elements in a POM very likely indicates that indeed the contents of both elements were desired in the final manifest.
          If changing the behavior is not an option I suggest to introduce another element that allows the user to specify a merge behavior instead of an override behavior.

          Show
          Mirko Raner added a comment - I'm struggling with the same issue. I have an existing MANIFEST.MF file with a dummy version number, and I'd like to use the actual Maven build version in the final manifest instead: <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestFile>META-INF/MANIFEST.MF</manifestFile> <manifestEntries> <Bundle-Version>$ {version} </Bundle-Version> </manifestEntries> </archive> </configuration> I'm not entirely convinced that it was a good choice to have the presence of a <manifestFile> element override other directives, such as <manifestEntries>. I think that intuitively most developers would expect both elements to be honored and the entries to be merged in a reasonable way. Changing this behavior would obviously break existing POMs out there that rely on the <manifestFile> overrides <manifestEntries> semantics, though I would venture that the presence of both elements in a POM very likely indicates that indeed the contents of both elements were desired in the final manifest. If changing the behavior is not an option I suggest to introduce another element that allows the user to specify a merge behavior instead of an override behavior.
          Hide
          Hesham Saleh added a comment - - edited

          Facing the same problem in both Maven 2.2.1 (rdebian-4) and 3.0.3 using the maven-jar-plugin 2.3.2. I am also convinced that an option to force overwriting a pre-existent value should be provided.

          Show
          Hesham Saleh added a comment - - edited Facing the same problem in both Maven 2.2.1 (rdebian-4) and 3.0.3 using the maven-jar-plugin 2.3.2. I am also convinced that an option to force overwriting a pre-existent value should be provided.
          Hide
          boxu added a comment -

          we can do like this:
          1. in pom.xml add this comment
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <configuration>
          <archive>
          <manifestFile>META-INF/MANIFEST.MF</manifestFile>
          <manifestEntries>
          <Bundle-Version>$

          {version}

          </Bundle-Version>
          </manifestEntries>
          </archive>
          </configuration>

          2. delete the Bundle-Version in your MANIFEST.MF file

          Show
          boxu added a comment - we can do like this: 1. in pom.xml add this comment <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestFile>META-INF/MANIFEST.MF</manifestFile> <manifestEntries> <Bundle-Version>$ {version} </Bundle-Version> </manifestEntries> </archive> </configuration> 2. delete the Bundle-Version in your MANIFEST.MF file
          Hide
          Hesham Saleh added a comment - - edited

          After some tracking, maven-jar-plugin depends on maven-archiver, which uses plexus-archiver internally to build archives. I found the following lines in plexus-archiver:JarArchiver.java:createManifest:

          JdkManifestFactory.merge( finalManifest, filesetManifest, false );
          JdkManifestFactory.merge( finalManifest, configuredManifest, false );
          JdkManifestFactory.merge( finalManifest, manifest, !mergeManifestsMain );
          

          These lines seem the responsible for the issue in hand, however, there is a comment prceeding this block which declares that "Precedence: manifestFile wins over inline manifest, over manifests read from the filesets over the original manifest.". Which is a bit strange, why would a supplied file have more precedence than supplied configuration ?)

          To cut a long debugging story shorter on anyone who intends to dig through this, here are some facts:

          • The original MANIFEST file is represented by the variable manifest in the above code
          • Any additional parameters supplied through manifestEntries entry in the POM, is set at configuredManifest (This happens by maven-archiver:MavenArchiver.java:createArchive)
          • The POM's XML configuration (manifestEntries and manifestFile) are binded by the maven-jar-plugin to an object of MavenArchiveConfiguration, this config object is supplied "as is" to the previously mentioned maven-archiver:MavenArchiver.java:createArchive method.

          I was successfully able to reach the desired results by a small change in maven-archiver shown in the following patch:

          hesham@hesham-work-laptop ~/dev/maven $ cat diff-maven-archiver 
          Index: src/main/java/org/apache/maven/archiver/MavenArchiver.java
          ===================================================================
          --- src/main/java/org/apache/maven/archiver/MavenArchiver.java	(revision 1458914)
          +++ src/main/java/org/apache/maven/archiver/MavenArchiver.java	(working copy)
          @@ -20,6 +20,7 @@
            */
           
           import java.io.File;
          +import java.io.FileReader;
           import java.io.IOException;
           import java.util.ArrayList;
           import java.util.Collections;
          @@ -546,7 +547,7 @@
           
                   if ( manifestFile != null )
                   {
          -            archiver.setManifest( manifestFile );
          +            archiver.addConfiguredManifest(new Manifest(new FileReader(manifestFile))); 
                   }
           
                   Manifest manifest = getManifest( session, workingProject, archiveConfiguration );
          

          However, considering I am new to the code base I feel this is a bit hackish, I will try to dig more into things to figure out more formal way.

          BTW, a small issue brings itself: MANIFEST's Bundle-Version should conform to the OSGi specs, this will need manipulating the version declared in the POM to be compatible with OSGi's MANIFEST. (i.e. POM's 1.0.0-RC1-SNAPSHOT would turn something like 1.0.0.RC1-SNAPSHOT).

          Show
          Hesham Saleh added a comment - - edited After some tracking, maven-jar-plugin depends on maven-archiver, which uses plexus-archiver internally to build archives. I found the following lines in plexus-archiver:JarArchiver.java:createManifest: JdkManifestFactory.merge( finalManifest, filesetManifest, false ); JdkManifestFactory.merge( finalManifest, configuredManifest, false ); JdkManifestFactory.merge( finalManifest, manifest, !mergeManifestsMain ); These lines seem the responsible for the issue in hand, however, there is a comment prceeding this block which declares that "Precedence: manifestFile wins over inline manifest, over manifests read from the filesets over the original manifest.". Which is a bit strange, why would a supplied file have more precedence than supplied configuration ?) To cut a long debugging story shorter on anyone who intends to dig through this, here are some facts: The original MANIFEST file is represented by the variable manifest in the above code Any additional parameters supplied through manifestEntries entry in the POM, is set at configuredManifest (This happens by maven-archiver:MavenArchiver.java:createArchive) The POM's XML configuration (manifestEntries and manifestFile) are binded by the maven-jar-plugin to an object of MavenArchiveConfiguration, this config object is supplied "as is" to the previously mentioned maven-archiver:MavenArchiver.java:createArchive method. I was successfully able to reach the desired results by a small change in maven-archiver shown in the following patch: hesham@hesham-work-laptop ~/dev/maven $ cat diff-maven-archiver Index: src/main/java/org/apache/maven/archiver/MavenArchiver.java =================================================================== --- src/main/java/org/apache/maven/archiver/MavenArchiver.java (revision 1458914) +++ src/main/java/org/apache/maven/archiver/MavenArchiver.java (working copy) @@ -20,6 +20,7 @@ */ import java.io.File; + import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -546,7 +547,7 @@ if ( manifestFile != null ) { - archiver.setManifest( manifestFile ); + archiver.addConfiguredManifest( new Manifest( new FileReader(manifestFile))); } Manifest manifest = getManifest( session, workingProject, archiveConfiguration ); However, considering I am new to the code base I feel this is a bit hackish, I will try to dig more into things to figure out more formal way. BTW, a small issue brings itself: MANIFEST's Bundle-Version should conform to the OSGi specs, this will need manipulating the version declared in the POM to be compatible with OSGi's MANIFEST. (i.e. POM's 1.0.0-RC1-SNAPSHOT would turn something like 1.0.0.RC1-SNAPSHOT).
          Hide
          Hesham Saleh added a comment -

          Regarding OSGi spec for bundle version and this transformation, I found a good implementation here: https://java2s.com/Open-Source/Java/Net/Terracotta/com/tc/bundles/MavenToOSGi.java.htm

          Show
          Hesham Saleh added a comment - Regarding OSGi spec for bundle version and this transformation, I found a good implementation here: https://java2s.com/Open-Source/Java/Net/Terracotta/com/tc/bundles/MavenToOSGi.java.htm

            People

            • Assignee:
              Unassigned
              Reporter:
              Robert Cauble
            • Votes:
              4 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated: