I'm trying to create a executable jar(using maven) that contains the project classes and it's dependencies with a manifest file that has the entry for the main class and the class path entry that points to the dependencies packed in the root of the jar;something like this :
Manifest File:
..... Main-Class : com.acme.MainClass Class-Path : dependecy1.jar dependecy2.jar .....
Jar:
jar-root |-- .... |-- com/acme/../*.class |-- dependecy1.jar `-- dependecy2.jar
I'm using the maven-jar-plugin to create the manifest file and the maven-shade-plugin to create the "uber" jar but the dependencies are unpacked and added as classes to my jar.
Normally, when we package a project into a jarW file, the jar file doesn't contain its dependencies, so the dependency jar files would need to be included in the classpathW in order to execute a class in the project's jar file that uses one of the dependencies.
Use the maven-shade-plugin to package all dependencies into one über-JAR file. It can also be used to build an executable JAR file by specifying the main class.
Actually, I didn't check what the maven-shade-plugin
is doing exactly (or any other plugin) as maven 2 has everything built-in to create a megajar or uberjar. You just have to use the maven-assembly-plugin with the predefined jar-with-dependencies
descriptor.
Just add this snippet to your pom.xml
to customize the manifest:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>my.package.to.my.MainClass</mainClass> </manifest> </archive> </configuration> </plugin>
And the following command will generate your uberjar:
mvn assembly:assembly -DdescriptorId=jar-with-dependencies
But, again, the default behavior of this descriptor is to unpack dependencies (like the maven-shade-plugin). To be honest, I don't get why this is a problem but, if this is really not what you want, you can use your own custom assembly descriptor.
To do so, first, create your assembly descriptor, let's say src/assembly/uberjar.xml
, with the following content:
<assembly> <id>uberjar</id> <formats> <format>jar</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <dependencySets> <dependencySet> <unpack>false</unpack> <scope>runtime</scope> <useProjectArtifact>false</useProjectArtifact> </dependencySet> </dependencySets> <fileSets> <fileSet> <directory>${project.build.outputDirectory}</directory> <outputDirectory>/</outputDirectory> </fileSet> </fileSets> </assembly>
Then, configure the maven-assembly-plugin to use this descriptor and to add the dependencies to the Class-Path
entry of the manifest:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>src/assembly/uberjar.xml</descriptor> </descriptors> <archive> <manifest> <mainClass>my.package.to.my.MainClass</mainClass> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> <!-- <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> --> </plugin>
Finally run mvn assembly:assembly
to produce your uberjar.
Optionally, uncomment the executions
element to bind the assembly plugin on the package
phase (and have the assembly produced as part of the normal build).
OneJar has a maven2 plugin.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With