Search code examples
classpathexecutable-jarmaven-assembly-plugin

Help with setting up classpath in an executable jar file


I am trying to build an executable jar with maven-assembly-plugin with all the dependencies. I want the dependencies in a /lib/ directory inside the jar, with the main jar outside, and the configuration files in the same level of the main jar.

My pom.xml is:

<plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                  <archive>
                    <manifest>
                      <addClasspath>true</addClasspath>
                      <classpathPrefix>lib/</classpathPrefix>
                      <mainClass>org.main.Class</mainClass>
                    </manifest>
                    <manifestEntries>
                        <Class-Path>/ MainClass.jar</Class-Path>
                    </manifestEntries>
                  </archive>
                  <descriptors>
                     <!--Relative path to your descriptor -->
                     <descriptor>src/main/assembly/packagejar.xml</descriptor>

                  </descriptors>
                </configuration>
</plugin>

The packagejar.xml is:

<id>eval</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <fileSets>
    <fileSet>
      <directory>${project.build.directory}</directory>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>MainClass.jar</include>
      </includes>
    </fileSet>
  </fileSets>
  <files>
    <file>
        <source>/src/main/resource/logging.properties</source>
        <outputDirectory>/</outputDirectory>
    </file>
    <file>
        <source>/src/main/resource/log4j.properties</source>
        <outputDirectory>/</outputDirectory>
    </file>
    <file>
        <source>/src/main/resource/hibernate.cfg.xml</source>
        <outputDirectory>/</outputDirectory>
    </file>
  </files>
  <dependencySets>
    <dependencySet>
      <outputDirectory>/lib/</outputDirectory>
      <useProjectArtifact>false</useProjectArtifact>
      <unpack>false</unpack>
      <scope>runtime</scope>
    </dependencySet>
  </dependencySets>
  </assembly>

And the resulting manifest.mf file is:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: German
Build-Jdk: 1.6.0_22
Main-Class: org.main.Class
Class-Path: / MainClass.jar lib/dependency1.jar lib/dependency2.jar etc...

With this, I get the mainclass to execute, but it never finds the jars inside lib it needs to work. Probably I'm missing something basic. I've tried also adding in the pom.xml manifestEntries a lib/, lib/.jar, /lib and /lib/.

Any ideas?

Thanks in advance.


Solution

  • Refer Java Tutorial on why it can't be done in the way you expect. For your question on the way to release an executable jar, that is one possible way, but not always you might want to send dependencies separately. There are couple of plugins that will build your executable jar with the dependencies in it(but not the way as you expected). look into OneJAR and Maven Shade . One JAR builts an executable jar with the dependencies in a lib directory , but has custom class loader classes within the executable jar. Maven shade plugin unjars the dependency libraries within the executable jar. I used Maven Shade, because I had the necessity to do some transformations when building the executable along with spring dependencies.