Including dependencies in a jar with Maven

531,964

Solution 1

You can do this using the maven-assembly plugin with the "jar-with-dependencies" descriptor. Here's the relevant chunk from one of our pom.xml's that does this:

  <build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

Solution 2

With Maven 2, the right way to do this is to use the Maven2 Assembly Plugin which has a pre-defined descriptor file for this purpose and that you could just use on the command line:

mvn assembly:assembly -DdescriptorId=jar-with-dependencies

If you want to make this jar executable, just add the main class to be run to the plugin configuration:

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

If you want to create that assembly as part of the normal build process, you should bind the single or directory-single goal (the assembly goal should ONLY be run from the command line) to a lifecycle phase (package makes sense), something like this:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <id>create-my-bundle</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

Adapt the configuration element to suit your needs (for example with the manifest stuff as spoken).

Solution 3

If you want to do an executable jar file, them need set the main class too. So the full configuration should be.

    <plugins>
            <plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <!-- ... -->
                       <archive>
                           <manifest>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
         </plugin>
   </plugins>

Solution 4

There's the shade maven plugin. It can be used to package and rename dependencies (to omit dependency problems on the classpath).

Solution 5

        <!-- Method 1 -->
        <!-- Copy dependency libraries jar files to a separated LIB folder -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <excludeTransitive>false</excludeTransitive> 
                <stripVersion>false</stripVersion>
            </configuration>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <!-- Add LIB folder to classPath -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
        </plugin>


        <!-- Method 2 -->
        <!-- Package all libraries classes into one runnable jar -->
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
        </plugin>            
Share:
531,964
racer
Author by

racer

Updated on July 20, 2022

Comments

  • racer
    racer almost 2 years

    Is there a way to force maven(2.0.9) to include all the dependencies in a single jar file?

    I have a project the builds into a single jar file. I want the classes from dependencies to be copied into the jar as well.

    Update: I know that I cant just include a jar file in a jar file. I'm searching for a way to unpack the jars that are specified as dependencies, and package the class files into my jar.

  • posdef
    posdef almost 12 years
    I am trying exactly this, however the plugin is not run and the jar file is not created even though the build executes smoothly. Is there a common pitfall that I might have gotten stuck with?
  • hansvb
    hansvb over 11 years
    There is also a Maven plugin for One-JAR: onejar-maven-plugin.googlecode.com/svn/mavensite/usage.html
  • Souvik Bhattacharya
    Souvik Bhattacharya over 10 years
    It's working for me but have a questing. after build now two jars are created one with project artifactid-version and another with artifactid-version-"jar-with-dependencies". But I want only one jar to be build. Is there any other way
  • D. A.
    D. A. about 10 years
    In case any new mvn folks got stuck like me, add the plugin to <plugins> inside <build> which is inside <project>.
  • lony
    lony about 10 years
    How can I avoid including libraries I don't use in my code? My jar just using SSJ sums up to 10 MB :(
  • lux
    lux almost 10 years
    @D.A. Why people leave out relevant (read: pertinent) details like that are beyond me.
  • Hobbyist
    Hobbyist over 9 years
    Still can't get this to work, I've followed like 15 different answers on different questions too.
  • technocrat
    technocrat about 9 years
    @Christian.tucker There's a 2nd jar in the target directory created like this: ./target/example-0.0.1-SNAPSHOT.jar and ./target/example-0.0.1-SNAPSHOT-jar-with-dependencies.jar
  • James Watkins
    James Watkins about 9 years
    How can I get the install goal to put the jar-with-dependencies into the repo?
  • lilalinux
    lilalinux over 8 years
    @Christian.tucker mvn assembly:assembly -DdescriptorId=jar-with-dependencies
  • Hammad Hassan
    Hammad Hassan over 8 years
    Just add one more thing in configuration. Your main class information. <archive> <manifest> <mainClass>fully qualified name</mainClass> </manifest> </archive>
  • Admin
    Admin over 8 years
    the maven-dependency-plugin <outputDirectory> dont work, always write on "dependency" folder
  • Admin
    Admin over 8 years
    create a jar with a internal folder "dependency" containing project dependencies and put it on MANIFEST.MF
  • Admin
    Admin over 8 years
    <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.java</include> <include>**/*.properties</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*</include> </includes> <targetPath>META-INF/</targetPath> </resource> <resource> <directory>${project.build.directory}/dependency/</direc‌​tory> <includes> <include>*.jar</include> </includes> <targetPath>lib/</targetPath> </resource> </resources>
  • raisercostin
    raisercostin over 7 years
    Based on this answer I created this project. You shouldn't need to change anything except the pom file: github.com/raisercostin/jarinjarloader
  • Kyle
    Kyle almost 7 years
    if you don't like jar-with-dependencies as part of the file name.
  • geschema
    geschema over 6 years
    It works but I'm seeing two JARs in the target directory: with and without dependencies. How do I generate only the JAR that has the dependencies?
  • WesternGun
    WesternGun about 6 years
    Is it the same as Eclipse "Export as Runnable jar"? Because with this you can choose to "package all dependencies with the JAR", you then get all dependencies in project-lib folder, along your jar.
  • Rop
    Rop about 6 years
    @FaithReaper -- It might be "the same", I never tried that. But I guess if you use Eclipse, it's not easily scriptable, which is a requirement, if you want to implement an automated build+deploy-pipeline. For example, let Jenkins-server do the build from your git source-repository, or similar.
  • Alex78191
    Alex78191 about 6 years
  • Tina J
    Tina J over 5 years
    Why is the name of jar appended by "jar-with-dependencies"?! Any workarounds?
  • Kush Patel
    Kush Patel about 5 years
    How to include a jar file into jar file in maven ?
  • vitro
    vitro almost 5 years
    Not quite true regarding services, shade plugin has transformers and one of them is for concatenating contents of files under the META-INF/services directory. More info here: maven.apache.org/plugins/maven-shade-plugin/examples/…
  • ccu
    ccu over 4 years
    @Tina J you can add <appendAssemblyId>false</appendAssemblyId> inside the <configuration> tag to exclude the "-jar-with-dependencies" suffix in the final name.
  • Kachopsticks
    Kachopsticks almost 4 years
    Hello, if you use this plugin, will it grab jars from a local lib folder? I reference some dependencies this way in the project that I want to build into a jar... ` <dependency> <groupId>com.kachop</groupId> <artifactId>mylocal</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${basedir}/lib/lk/mylocal.jar</systemPath> </dependency>`
  • amucunguzi
    amucunguzi over 3 years
    @SouvikBhattacharya add <appendAssemblyId>false</appendAssemblyId> to maven-assembly-plugin configutation.
  • tcurdt
    tcurdt over 3 years
    It basically encapsulates the artifact in its own namespace. I cannot think of any scenario where this still allows for clashes.
  • Harihara_K
    Harihara_K almost 3 years
    Please describe, how it exactly solves the problem
  • NIrav Modi
    NIrav Modi almost 3 years
    I have added only this plugin
  • Kalesh Kaladharan
    Kalesh Kaladharan over 2 years
    The first option is the best for faster rebuilds. assembly-plugin just takes too much time packaging dependencies, which is expected.
  • gtree
    gtree over 2 years
    I tried the first approach here. In the documentation, it states ""Note: The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over Internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes." In your Method 1, are you referring people to writing custom jar loaders?
  • gtree
    gtree over 2 years
    I noticed there was a difference in the copying and unpacking in comparison to the assembly. I kept getting "ClassNotFoundException" when trying to run my jar file for my server. How do you recommend proceeding if using your method 1? I couldn't get mine to work.
  • Tianbing Leng
    Tianbing Leng about 2 years
    Option 2 works for me, thanks!
  • Mic
    Mic almost 2 years
    For option 1 (If you don't want to copy JUnit dependencies to target folder) you must add <includeScope>compile</includeScope> to the maven-dependency-plugin <configuration>