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