I am trying to set my build server information into META-INF/MANIFEST.MF. It works very well when using maven-jar-plugin with manifestEntries . The problem is that when I am packaging the Jar with maven-assembly-plugin to a single Jar with dependencies (like in here: How can I create an executable JAR with dependencies using Maven?) I can't see my manifest entries anymore. My guess is that my MANIFEST.MF is being dropped, while the assembly runs, but I could not find the way to set it after the manifest completes.
This is how my pom.xml build section looks like:
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>ConvertorMain</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<archive>
<manifestEntries>
<Application-Version>${app.version.major}.${app.version.minor}.0</Application-Version>
<Built-By>${user}</Built-By>
<Git-Branch>${git.branch}</Git-Branch>
<Git-Commit>${git.commit}</Git-Commit>
</manifestEntries>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
</plugins>
...
</build>
Without the jar-with-dependencies, the MAINFEST.MF will contain:
Manifest-Version: 1.0
Git-Commit: 35ff1f997b0c01daf44ed23425a3dc93307faaf7
Build-Jdk: 1.7.0_03
Built-By: Build Server
Git-Branch: origin/HEAD
Created-By: Apache Maven
Application-Version: 0.2.57
Archiver-Version: Plexus Archiver
Then, unzip -q -c convertor-1.0-jar-with-dependencies.jar META-INF/MANIFEST.MF dumps:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: eranh
Build-Jdk: 1.6.0_35
Main-Class: ConvertorMain
You have simply to copy the archive section from your maven-jar-plugin configuration into the maven-assembly-plugin as well.
Related
Given this plugin config in a Maven pom.xml:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>acme.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Why would MANIFEST.MF be missing Implementation-Version and Implementation-Title, given that all docs that I can get my hands on, either don't mention it, or imply its creation is a default?
The complete generated Manifest is:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.6
Built-By: stewart
Build-Jdk: 17.0.5
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: acme.Main
Spring-Boot-Version: 2.7.5
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Apparently, behind the scenes, spring-boot-maven-plugin still relies on the Manifest created by maven-jar-plugin, because that's the base .jar that is being repackaged.
Having established that, we then find that
Starting with version 2.1, Maven Archiver no longer creates the
Implementation and Specification details in the manifest by default.
If you want them in your manifest you have to say so explicitly in
your configuration.
Thus, what is needed is to add the following to the pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
My pom.xml looks like this
...
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<archive>
<manifest>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
...
but although I specified the main class, on clean package install maven only creates jars that aren't runnable.
How can I fix that? The manifest then looks like this:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: Matthias
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_121
Instead of maven compiler plugin, you should configure the maven jar plugin to create an executable jar :
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
To declare the source/target java version you could use :
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
instead of declaring the compiler plugin.
This is less verbose and it produces exactly the same result.
Besides, if you want to include dependency jars of your application inside your executable jar, you should favor the maven assembly plugin over the maven jar plugin :
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
I'm using maven-jar-plugin in pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<!-- DO NOT include log4j.properties file in your Jar -->
<archive>
<manifest>
<!-- Jar file entry point -->
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
I can see in logs that maven execute it:
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: example.jar
[INFO] [jar:jar {execution: jar}]
but it don't put main class to MANIFEST.MF:
Manifest-Version: 1.0
Built-By: romkazanova
Build-Jdk: 1.7.0_65
Created-By: Apache Maven
Archiver-Version: Plexus Archiver
i don't understand why. I work with Idea.
You have to define the configuration in a pluginManagement area cause the maven-jar-plugin is already bound to the build life-cycle
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
The problem you have is that the execution you have defined means to have a supplemental execution as the log output shows and not change the configuration of the existing execution within the life cycle.
Furthermore you seemed to be running on Maven 2 instead of Maven 3 and you should update as soon as possible because Maven 2 has been defined EoL
You can of course add the version of maven-jar-plugin.
Try to compile manually by prompt: mvn compile
or try: mvn clean install -Dmaven.test.skip=true
What IDE are you using?
#khmarbaise is wrong in his definition of PluginManagement. According to the definition in Maven documentation, PluginManagement is intended to configure project builds that inherit from this one. In your pom.xml you have no needs to keep the PluginManagement node.
You only have to change the location of your configuration node from execution level to plugin level. You can see that #khmarbaise did that too.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<!-- DO NOT include log4j.properties file in your Jar -->
<archive>
<manifest>
<!-- Jar file entry point -->
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Furthermore you don't have to keep the executions node anymore because maven-jar-plugin is already bound to the build life-cycle as #khmarbaise mentioned it.
I am using the maven assembly plugin to generate an app client that is included in an EAR.
However, it isn't including the Main Class for whatever reason. I can't figure out what is wrong.
My Maven Assembly plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>my-program</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.program.my.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
The resulting MANIFEST.MF:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: me
Build-Jdk: 1.8.0_20
EDIT:
Here is the full Maven POM
I have the following in my project's pom.xml which I think should display the version of Maven being used in the resulting WAR file:
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
<Build-Host>${agent.name}</Build-Host>
<Build-User>${user.name}</Build-User>
<Build-Maven>Maven ${maven.version}</Build-Maven>
<Build-Java>${java.version}</Build-Java>
<Build-OS>${os.name}</Build-OS>
<Build-Label>${project.version}</Build-Label>
<Build-Path>${basedir}</Build-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
...
</plugins>
...
</build>
The MANIFEST.MF that is created looks correct see below apart from the Build-Maven line in which the ${maven.version} is not substituted with the actual version number 3.0.4 in this case.
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: stocjon
Build-Jdk: 1.6.0_35
Build-Host:
Build-Java: 1.6.0_35
Build-Label: 1.0.0-SNAPSHOT
Build-Maven: Maven ${maven.version}
Build-OS: Windows XP
Build-Path: C:\Development\project_name
Build-Time: 15:38:50 21-Sep-2012
Build-User: user_name
Any ideas why Maven version is not being populated in the MANIFEST.MF ?
Help would be much appreciated.
Thanks
Jon
You need to add this plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>maven-version</goal>
</goals>
</execution>
</executions>
</plugin>
Check here for details.
We no more need the build-helper-maven-plugin since the feature (MSHARED-38) was added to the component maven-archiver : 2.5 in Feb. 2012 (release notes).
And this component is used by the Maven plugins like maven-jar-plugin, maven-war-plugin, maven-ear-plugin, etc.
The versions of these plugins using this feature are :
maven-jar-plugin : 2.4 (MJAR-148), released in Feb. 2012
maven-war-plugin : 2.2 (MWAR-273), released in Feb. 2012
maven-ear-plugin : 2.8 (MEAR-145), released in Sept. 2012
maven-assembly-plugin : 2.4 (MASSEMBLY-634), released in Nov. 2012
maven-ejb-plugin : 2.4 (MEJB-56), EDIT : released on 24/Aug/14
etc.
So now we'll have this entry by default in the archive's manifest.mf :
Created-By: Apache Maven ${maven.version}
At least as of version 2.4 of the maven-jar plugin, the following entries are added by default to the MANIFEST.MF file in META-INF in the jar:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: abcUser
Created-By: Apache Maven 3.3.3
Build-Jdk: 1.8.0_77
To add the project version and other implementation details, simply add the following to the maven-jar-plugin (either in the pluginManagement section or in the build -> plugins section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
To add something like a build time, add the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
The Build-Time format can be changed by using the following property in the <properties> section of your pom.xml:
<maven.build.timestamp.format>yyyy-MM-dd HH:mm z</maven.build.timestamp.format>
The output of all the above is something like:
Manifest-Version: 1.0
Implementation-Title: UI
Implementation-Version: 2.0.5-SNAPSHOT
Archiver-Version: Plexus Archiver
Built-By: abcUser
Implementation-Vendor-Id: com.xyz.abc.dbe
Build-Time: 2016-12-23 12:04 UTC
Created-By: Apache Maven 3.3.3
Build-Jdk: 1.8.0_77
Implementation-Vendor: XYZ Corporation
For completeness - this worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
This puts in my manifest -
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Old.Curmudgeon
Build-Jdk: 1.5.0_22
Implementation-Title: JarFileName-1.0.2
Implementation-Version: 1.0.2
Implementation-Vendor-Id: our.id
Take a look how it's suggested by jcabi-manifests: http://manifests.jcabi.com/versioning.html
Also, see this blog post for more details: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
In order to get the build machine I added the following plugin:
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>project.properties["hostname"] = InetAddress.getLocalHost().getHostName()</source>
</configuration>
</execution>
</executions>
</plugin>
I could then retrieve the host machine name through ${hostname}.