How to include Maven dependencies in Manifest file - java

I am developing a plugin for the OSGI application, using maven to compile. In order to install the plugin, the OSGI application should read the information about plugin dependencies. This information should be provided in the MANIFEST.MF file. What I'm wondering is how to use Virgo Tooling to generate a proper MANIFEST.MF file.
These are the dependencies I would like to include in the MANIFEST.MF
UPDATE According to the answer I used the Apache Felix
To the pom.xml I have added
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>
downloaded the maven-bundle.jar and executed the command mvn org.apache.felix:maven-bundle-plugin:manifest which produced the .jar file with the manifest, but manifest contained only following infromation
Manifest-Version: 1.0
Implementation-Vendor: The Apache Software Foundation
Implementation-Title: Maven Bundle Plugin
Implementation-Version: 3.2.0
Implementation-Vendor-Id: org.apache.felix
Built-By: cziegeler
Build-Jdk: 1.7.0_80
Specification-Vendor: The Apache Software Foundation
Specification-Title: Maven Bundle Plugin
Created-By: Apache Maven 3.3.9
Specification-Version: 3.2.0
Archiver-Version: Plexus Archiver
Any ideas what I did wrong?

Personally, I would generate the MANIFEST.MF file with Apache Felix Maven Bundle Plugin
Try to add some configuration to the plugin in the project's pom.xml file.
Here's a start, but you should read the documentation and find the correct instructions that will fit your precise need. It would be helpful if you could provide an example of MANIFEST.MF file.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Embed-Dependency>*;scope=compile|runtime;inline=false</Embed-Dependency>
</instructions>
</configuration>
<executions>
<execution>
<id>generate-manifest</id>
<goals>
<goal>manifest</goal>
</goals>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
With this kind of config, the MANIFEST.MF will be generated during 'generate-resources' phase.

Related

`Implementation-Version` not in Manifest after `spring-boot-maven-plugin` repackage

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>

maven deployable jar "java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver" error

I have a deployable maven project where I'm trying to connect to a hive server using JDBC. This is my pom file:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.test.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
This generates a jar file which has a manifest.mf which is like this:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: test
Class-Path: hive-jdbc-2.1.1.jar hive-common-2.1.1.jar ...
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_72
Main-Class: com.test.Main
Now, when I try to run the jar file using java -jar test.jar, I get
java.lang.ClassNotFoundException: org.apache.hadoop.hive.jdbc.HiveDriver
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
Why do I get this exception even though the jar file is configured properly in the classpath of the manifest file?
Thanks.
The jar referenced in the dependency seems not to be found by java. Probably is not located in the same folder as the target jar.
Depending on what you mean by deploayable maven project you have a couple of possible solutions
add the dependency to the classpath of the container
build a "fat" jar containing the dependency (using the maven shade or assembly plugin)
You can add maven-dependency-plugin to copy your dependencies from local or remote repositories to a specified location
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>compile</includeScope>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
or as another option use maven-assembly-plugin
See here
Make Sure which jar (hive ) do you want .. because it has diferent versions
The old verison jar is
org.apache.hadoop.hive.jdbc.HiveDriver
here is the mvnrepository
and the newest jar is org.apache.hive.jdbc.HiveDriver here is the new settings
your mistakes is used the old dependency with the new jar name;

Maven ignored maven archiver

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.

How to get Java MANIFEST.MF to include Maven Version Number

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}.

ManifestEntries when building jar-with-dependencies

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.

Categories