2870

I want to package my project in a single executable JAR for distribution.

How can I make a Maven project package all dependency JARs into my output JAR?

Thorbjørn Ravn Andersen
  • 73,784
  • 33
  • 194
  • 347
soemirno
  • 29,244
  • 3
  • 19
  • 14
  • 15
    Please explain which goal of the dependency plugin you are referring to. I know of no goal which does what the original question requests: to put all the dependencies either A) inside the authors jar via repackaging, or B) make an executable jar that has the others in a classpath of MANIFEST.MF – Matthew McCullough Mar 11 '09 at 15:11
  • 2
    You might find this useful http://www.rationaljava.com/2015/02/maven-tip-all-about-executable-jars.html – Dan Feb 02 '15 at 19:01
  • 1
    2 examples: http://www.tugay.biz/2015/12/a-standalone-java-web-application-with.html http://www.tugay.biz/2016/11/how-did-i-create-executable-jar-with.html – Koray Tugay Mar 30 '17 at 06:54
  • 2
    Refer https://stackoverflow.com/questions/35217128/is-it-possible-to-build-a-java-project-only-once-using-eclipse-and-share/35359756#35359756 – Thanga Sep 11 '17 at 08:18
  • For Gradle see the stackoverflow post: [Create fat/Uber JAR in Gradle](https://stackoverflow.com/a/71092054/8583692). – Mahozad Dec 02 '22 at 11:46

33 Answers33

2792
<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </plugin>
  </plugins>
</build>

and you run it with

mvn clean compile assembly:single

Compile goal should be added before assembly:single or otherwise the code on your own project is not included.

See more details in comments.


Commonly this goal is tied to a build phase to execute automatically. This ensures the JAR is built when executing mvn install or performing a deployment/release.

<build>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>fully.qualified.MainClass</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
      <executions>
        <execution>
          <id>make-assembly</id> <!-- this is used for inheritance merges -->
          <phase>package</phase> <!-- bind to the packaging phase -->
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>
YQ.Wang
  • 1,090
  • 1
  • 17
  • 43
IAdapter
  • 62,595
  • 73
  • 179
  • 242
  • 30
    Thanks @IAdapter. Note that you should always do a compile before hand because it will just put whatever is in "target/classes" in the JAR. This will ensure that the JAR includes any changes you recently made to the source code. So, you should do something like: `mvn clean compile assembly:single`. – Michael May 31 '11 at 19:03
  • 1
    I've associated the assembly:single goal with the package phase in my project's pom.xml, but it works only when I do a mvn assembly:single from the command line. – Sahil Dave Oct 23 '13 at 14:55
  • Is here any way I can direct the to a class under the test directory? I have a main class under org.core (the directory structure exists under main and test) but maven only includes compiled classes from main and not test. – Prashant Vaidyanathan Jul 16 '14 at 02:10
  • Can we use this metod for java fx jar. Our the default ant jar task is better. But i am facing issues of dependencies with ant jar task.look my Question http://stackoverflow.com/questions/25915793/using-maven-ant-plugin-in-javafx-application-how-to-add-dependencies-in-javafx – Mubasher Sep 18 '14 at 16:56
  • 6
    I see that this doesn't add the jars to the uber jar, instead this just adds all the class files to the jar. – pitchblack408 Apr 07 '15 at 16:31
  • 234
    Tip: you can also add the element `false` into the `configuration` to avoid the annoying "-jar-with-dependencies" suffix in the name – maxivis May 06 '15 at 19:22
  • 2
    maven assembly plugin could introduce some issues because could override some dependencies, so I cannot tell you to use it! Use the maven Shade plugin instead which works very nice for us. We spent some days to found that the maven assembly plugin overrides some dependencies which break application jar. Have a look there : https://www.mkyong.com/maven/create-a-fat-jar-file-maven-shade-plugin/ – user3774109 Mar 09 '17 at 15:07
  • 8 levels of wrapping is insane overdoing it – Niklas Rosencrantz Nov 21 '17 at 21:48
  • 1
    @maxivis Doing this seems to work but generates some warnings. – Raffi Khatchadourian Feb 01 '18 at 22:41
  • 3
    what if i don't have main method or class, i just need some random java file to be jar? – parlad Jul 20 '18 at 11:02
  • @parladneupane leave out the ... portion – gerardw Oct 24 '18 at 16:27
  • He do not asked to use plugings, maven should be able compile with dependencies itself without strange commands and plugings –  Nov 20 '18 at 22:04
  • 6
    @user10201743 Just to give a little context: _Everything_ in Maven is a plugin. The compiler? `maven-compiler-plugin`. Tests? `maven-surefire-plugin`. These two, including the assembly, are official maven plugins, so they might as well be considered as part of maven (esp. cause, at least now, all three of them are in your effective POM by default). – Adowrath Mar 16 '19 at 18:09
  • I ran into this with the alexa-skills-kit-sdk-for-java which worked well until the instructions to create the WAR barfed in Maven. In 'Developing Your First Skill' it says enter the line command 'mvn org.apache.maven.plugins:maven-assembly-plugin:2.6:assembly -DdescriptorId=jar-with-dependencies package' which does not work. I put the above plug-in in the 'highest POM' (closest to the root file) and ran the line command 'mvn clean compile assembly:single' from that POM (directory) and it worked perfectly. – Richard Bradley Smith May 25 '19 at 01:16
  • 1
    For example if your main class path is `src/main/java/com/example/ui/Main.java`, you must write like that to pom.xml: `com.example.ui.Main`. – Halil İbrahim Oymacı Mar 31 '20 at 09:25
  • I got into trouble with this because I kept placing my various attempts using different plugin under build pluginManagement plugins instead of build plugins. Of course, there are no error messages to tell you about this mistake. – Jack D Menendez Dec 06 '20 at 20:05
  • And in case you're new here, you would run that new compiled program using: `java -jar target/*with-dependencies.jar` and you can add any command line arguments you want to pass to your program. – William Entriken Feb 19 '21 at 01:07
  • 2
    this is NOT executable – Enerccio Jun 28 '21 at 14:57
  • format of the assembly plugin is pure garbage. it changes the output structure completely. resources, classes, eveyrthing is flat. just take the normal war and turn it into a jar. – mjs Oct 08 '21 at 15:25
  • If you are using spring boot then you need to use spring boot mechanisms for this. e.g. https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/maven-plugin/reference/html/#repackage – BodhiOne Jan 14 '22 at 14:23
  • @Enerccio you are looking for native binary I guess (.exe) take a look at graalvm but you can also set your windows via ASSOC and FTYPE command to know JAR files you run it like normal executable, in Linux and BSD try shebang line, a search through google about thing I just said it will be helpful. – SinaMobasheri Sep 06 '22 at 20:17
  • I am getting the error: "Plugin 'maven-assembly-plugin:' not found" – Nisim Naim Aug 29 '23 at 12:26
406

You can use the dependency-plugin to generate all dependencies in a separate directory before the package phase and then include that in the classpath of the manifest:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Alternatively, use ${project.build.directory}/classes/lib as OutputDirectory to integrate all JAR files into the main JAR file, but then you will need to add custom classloading code to load the JAR files.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
André Aronsen
  • 4,069
  • 1
  • 14
  • 2
  • Is there a way to use this method without writing custom class loaders? I am getting "ClassNotFoundException". When I compared the assembly plugin, I was thinking that I could unpack the dependencies using maven-dependency-plugin. Any recommendations? – gtree Dec 13 '21 at 14:53
  • I'm using this plugin configuration because I can run the standard package lifecycle and it will perform all necessary actions to create an executable jar. I won't need any custom mvn command lines. – kenneth Dec 21 '22 at 12:31
325

See executable-jar-with-maven-example (GitHub)

Notes

Those pros and cons are provided by Stephan.


For Manual Deployment

  • Pros
  • Cons
    • Dependencies are out of the final jar.

Copy Dependencies to a specific directory

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>prepare-package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Make the JAR File Executable and Classpath Aware

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

At this point the JAR file is actually executable with external classpath elements.

java -jar target/${project.build.finalName}.jar

Make Deployable Archives

The JAR file is only executable with the sibling ...lib/ directory. We need to make archives to deploy with the directory and its content.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-antrun-plugin</artifactId>
  <executions>
    <execution>
      <id>antrun-archive</id>
      <phase>package</phase>
      <goals>
        <goal>run</goal>
      </goals>
      <configuration>
        <target>
          <property name="final.name" value="${project.build.directory}/${project.build.finalName}"/>
          <property name="archive.includes" value="${project.build.finalName}.${project.packaging} ${project.build.finalName}.lib/*"/>
          <property name="tar.destfile" value="${final.name}.tar"/>
          <zip basedir="${project.build.directory}" destfile="${final.name}.zip" includes="${archive.includes}" />
          <tar basedir="${project.build.directory}" destfile="${tar.destfile}" includes="${archive.includes}" />
          <gzip src="${tar.destfile}" destfile="${tar.destfile}.gz" />
          <bzip2 src="${tar.destfile}" destfile="${tar.destfile}.bz2" />
        </target>
      </configuration>
    </execution>
  </executions>
</plugin>

Now you have target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz) which each contains the jar and lib/*.


Apache Maven Assembly Plugin

  • Pros
  • Cons
    • No class relocation support (use maven-shade-plugin if class relocation is needed).
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
      <configuration>
        <archive>
          <manifest>
            <mainClass>${fully.qualified.main.class}</mainClass>
          </manifest>
        </archive>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
      </configuration>
    </execution>
  </executions>
</plugin>

You have target/${project.bulid.finalName}-jar-with-dependencies.jar.


Apache Maven Shade Plugin

  • Pros
  • Cons
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <shadedArtifactAttached>true</shadedArtifactAttached>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>${fully.qualified.main.class}</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

You have target/${project.build.finalName}-shaded.jar.


onejar-maven-plugin

  • Pros
  • Cons
    • Not actively supported since 2012.
<plugin>
  <!--groupId>org.dstovall</groupId--> <!-- not available on the central -->
  <groupId>com.jolira</groupId>
  <artifactId>onejar-maven-plugin</artifactId>
  <executions>
    <execution>
      <configuration>
        <mainClass>${fully.qualified.main.class}</mainClass>
        <attachToBuild>true</attachToBuild>
        <!-- https://code.google.com/p/onejar-maven-plugin/issues/detail?id=8 -->
        <!-- classifier>onejar</classifier -->
        <filename>${project.build.finalName}-onejar.${project.packaging}</filename>
      </configuration>
      <goals>
        <goal>one-jar</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Spring Boot Maven Plugin

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>repackage</goal>
      </goals>
      <configuration>
        <classifier>spring-boot</classifier>
        <mainClass>${fully.qualified.main.class}</mainClass>
      </configuration>
    </execution>
  </executions>
</plugin>

You have target/${project.bulid.finalName}-spring-boot.jar.


Quarkus Maven Plugin

  • Pros
  • Cons
<plugin>
  <groupId>io.quarkus.platform</groupId>
  <artifactId>quarkus-maven-plugin</artifactId>
  <extensions>true</extensions>
  <configuration>
    <skipOriginalJarRename>true</skipOriginalJarRename> <!-- keep the original jar without .origin -->
    <properties>
      <quarkus.native.container-build>false</quarkus.native.container-build>
      <quarkus.package.type>uber-jar</quarkus.package.type>
      <quarkus.package.main-class>${mainClass}</quarkus.package.main-class>
      <quarkus.package.output-directory>${project.build.directory}</quarkus.package.output-directory>
      <quarkus.package.runner-suffix>-quarkus</quarkus.package.runner-suffix>
    </properties>
  </configuration>
  <executions>
    <execution>
      <id>uber-jar</id>
      <phase>package</phase>
      <goals>
        <goal>build</goal>
      </goals>
    </execution>
  </executions>
</plugin>

You have target/${project.bulid.finalName}-quarkus.jar.

Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
157

Taking IAdapter's answer and reformatting it, we have:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>
    </plugins>
</build>

Next, I would recommend making this a natural part of your build, rather than something to call explicitly. To make this a integral part of your build, add this plugin to your pom.xml and bind it to the package lifecycle event. However, a gotcha is that you need to call the assembly:single goal if putting this in your pom.xml, while you would call 'assembly:assembly' if executing it manually from the command line.

<project>
  [...]
  <build>
      <plugins>
          <plugin>
              <artifactId>maven-assembly-plugin</artifactId>
              <configuration>
                  <archive>
                      <manifest>
                          <addClasspath>true</addClasspath>
                          <mainClass>fully.qualified.MainClass</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>
      [...]
      </plugins>
    [...]
  </build>
</project>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthew McCullough
  • 17,160
  • 7
  • 39
  • 38
102

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. After trying to use maven-assembly and maven-jar, I found that this plugin best suited my needs.

I found this plugin particularly useful as it merges the content of specific files instead of overwriting them. This is needed when there are resource files that are have the same name across the JAR files and the plugin tries to package all the resource files.

See the example below:

<plugins>
    <!-- This plugin provides the capability to package
         the artifact in an über-JAR file, including
         its dependencies and to shade - i.e. rename -
         the packages of some of the dependencies. -->
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>1.4</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <artifactSet>
                        <!-- Signed JAR files-->
                        <excludes>
                            <exclude>bouncycastle:bcprov-jdk15</exclude>
                        </excludes>
                    </artifactSet>

                    <transformers>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <!-- Main class -->
                            <mainClass>com.main.MyMainClass</mainClass>
                        </transformer>

                        <!-- Use resource transformers to prevent file overwrites -->
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                            <resource>properties.properties</resource>
                        </transformer>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                            <resource>applicationContext.xml</resource>
                        </transformer>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                            <resource>META-INF/cxf/cxf.extension</resource>
                        </transformer>
                        <transformer
                            implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
                            <resource>META-INF/cxf/bus-extensions.xml</resource>
                        </transformer>
                    </transformers>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vijay Katam
  • 1,291
  • 1
  • 9
  • 8
26

You can use the maven-shade plugin to build an über JAR file like below:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Minisha
  • 2,117
  • 2
  • 25
  • 56
23

I have long used the Maven assembly plugin, but I could not find a solution to the problem with "already added, skipping". Now, I'm using another plugin - onejar-maven-plugin. An example is below (mvn package builds the JAR file):

<plugin>
    <groupId>org.dstovall</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.3.0</version>
    <executions>
        <execution>
            <configuration>
                <mainClass>com.company.MainClass</mainClass>
            </configuration>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

You need to add a repository for that plugin:

<pluginRepositories>
    <pluginRepository>
        <id>onejar-maven-plugin.googlecode.com</id>
        <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
    </pluginRepository>
</pluginRepositories>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
marioosh
  • 27,328
  • 49
  • 143
  • 192
21

You can add the following to your pom.xml file:

<build>
<defaultGoal>install</defaultGoal>
<plugins>
  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.mycompany.package.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-my-jar-with-dependencies</id>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>
</plugins>
</build>

Afterwards you have to switch via the console to the directory, where the pom.xml file is located. Then you have to execute mvn assembly:single and then your executable JAR file with dependencies will be hopefully build. You can check it when switching to the output (target) directory with cd ./target and starting your JAR with a command similar to java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar.

I tested this with Apache Maven 3.0.3.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Benny Code
  • 51,456
  • 28
  • 233
  • 198
20

You can use maven-dependency-plugin, but the question was how to create an executable JAR file. To do that requires the following alteration to Matthew Franglen's response (btw, using the dependency plugin takes longer to build when starting from a clean target):

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>fully.qualified.MainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>unpack-dependencies</id>
                    <phase>package</phase>
                    <goals>
                        <goal>unpack-dependencies</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
    <resources>
        <resource>
            <directory>${basedir}/target/dependency</directory>
        </resource>
    </resources>
</build>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
20

I went through every one of these responses looking to make a fat executable JAR file containing all dependencies and none of them worked right. The answer is the shade plugin, it’s very easy and straightforward.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.3</version>

  <executions>
    <!-- Run shade goal on package phase -->
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>

      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>path.to.MainClass</mainClass>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>

</plugin>

Be aware that your dependencies need to have a scope of compile or runtime for this to work properly.

This example came from mkyong.com

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dsutherland
  • 792
  • 6
  • 15
17

Another option if you really want to repackage the other JARs contents inside your single resultant JAR is the Maven Assembly plugin. It unpacks and then repacks everything into a directory via <unpack>true</unpack>. Then you'd have a second pass that built it into one massive JAR.

Another option is the OneJar plugin. This performs the above repackaging actions all in one step.

Matthew McCullough
  • 17,160
  • 7
  • 39
  • 38
15

You could combine the maven-shade-plugin and maven-jar-plugin.

  • The maven-shade-plugin packs your classes and all dependencies in a single JAR file.
  • Configure the maven-jar-plugin to specify the main class of your executable JAR file (see Set Up The Classpath, chapter "Make The Jar Executable").

Example POM configuration for maven-jar-plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>com.example.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

Finally create the executable JAR file by invoking:

mvn clean package shade:shade
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Oliver
  • 490
  • 4
  • 10
  • 4
    The Shade plugin now has means of specifying the Main-Class entry in the manifest: http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html – Chadwick Feb 27 '12 at 21:35
13

It will work like:

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack-dependencies</id>
            <phase>generate-resources</phase>
            <goals>
                <goal>unpack-dependencies</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Unpacking has to be in the generate-resources phase or it will not be included as resources.

cb4
  • 6,689
  • 7
  • 45
  • 57
kac-ani
  • 131
  • 1
  • 2
  • Getting this issue: org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:3.1.2:unpack-dependencies (unpack-dependencies) on project services: Unknown archiver type – Mohan Kanakala Dec 15 '20 at 12:34
  • `Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-dependency-plugin:2.8:unpack-dependencies (execution: unpack-dependencies, phase: generate-resources)` – TheTechRobo the Nerd Aug 31 '22 at 23:20
11

Ken Liu has it right in my opinion. The Maven dependency plugin allows you to expand all the dependencies, which you can then treat as resources. This allows you to include them in the main artifact. The use of the assembly plugin creates a secondary artifact which can be difficult to modify - in my case I wanted to add custom manifest entries. My POM file ended up as:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>unpack-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>unpack-dependencies</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
    ...
    <resources>
      <resource>
        <directory>${basedir}/target/dependency</directory>
        <targetPath>/</targetPath>
      </resource>
    </resources>
  </build>
  ...
</project>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matthew Franglen
  • 4,441
  • 22
  • 32
10

To resolve this issue, we will use the Maven Assembly plugin that will create the JAR file together with its dependency JAR files into a single executable JAR file. Just add the below plugin configuration in your pom.xml file.

<build>
   <pluginManagement>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
               <archive>
                  <manifest>
                     <addClasspath>true</addClasspath>
                     <mainClass>com.your.package.MainClass</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>
      </plugins>
   </pluginManagement>
</build>

After doing this, don’t forget to run the Maven tool with this command:

mvn clean compile assembly:single

Maven - Creating a JAR file together with its dependency JAR files into a single executable JAR file

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anoop Rai
  • 459
  • 5
  • 6
9

What is the problem with locating shared assembly files with maven-assembly-plugin-2.2.1?

Try using the descriptorId configuration parameter instead of descriptors/descriptor or descriptorRefs/descriptorRef parameters.

Neither of them do what you need: look for the file on classpath. Of course you need adding the package where the shared assembly resides on the maven-assembly-plugin's classpath (see below). If you're using Maven 2.x (not Maven 3.x), you may need adding this dependency in top-most parent pom.xml in the pluginManagement section.

See this for more details.

Class: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader

Example:

<!-- Use the assembly plugin to create a zip file of all our dependencies. -->
<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2.1</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <descriptorId>assembly-zip-for-wid</descriptorId>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>cz.ness.ct.ip.assemblies</groupId>
            <artifactId>TEST_SharedAssemblyDescriptor</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</plugin>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
7

I compared the tree plugins mentioned in this post. I generated two JAR files and a directory with all the JAR files. I compared the results and definitely the maven-shade-plugin is the best.

My challenge was that I have multiple Spring resources that needed to be merged, as well as jax-rs, and JDBC services. They were all merged properly by the shade plugin in comparison with the maven-assembly-plugin. In which case Spring will fail unless you copy them to your own resources folder and merge them manually one time.

Both plugins output the correct dependency tree. I had multiple scopes like test, provide, compile, etc. The test and provided were skipped by both plugins. They both produced the same manifest, but I was able to consolidate licenses with the shade plugin using their transformer. With the maven-dependency-plugin of course you don't have those problems, because the JAR files are not extracted. But like some other have pointed out, you need to carry one extra file(s) to work properly.

Here is a snip of the pom.xml file:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <includeScope>compile</includeScope>
                <excludeTransitive>true</excludeTransitive>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.rbccm.itf.cdd.poller.landingzone.LandingZonePoller</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>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.3</version>
    <configuration>
        <shadedArtifactAttached>false</shadedArtifactAttached>
        <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
        <transformers>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/services/javax.ws.rs.ext.Providers</resource>
            </transformer>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/spring.factories</resource>
            </transformer>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/spring.handlers</resource>
            </transformer>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/spring.schemas</resource>
            </transformer>
            <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                <resource>META-INF/spring.tooling</resource>
            </transformer>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
            <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheLicenseResourceTransformer">
            </transformer>
        </transformers>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fabio
  • 555
  • 3
  • 9
  • 24
7

For anyone looking for options to exclude specific dependencies from the über JAR file, this is a solution that worked for me:

<project...>
    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>1.6.1</version>
            <scope>provided</scope> <!--  <=============  -->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>...</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

It's not a configuration of the mvn-assembly-plugin, but a property of the dependency.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul Bormans
  • 1,292
  • 16
  • 22
  • do you mean that maven-assembly-plugin honors the scope specified for the dependency and by default included ONLY runtime dependencies? Also does it resolve & do it transitively for the transitive dependencies aswell? – lmk Feb 26 '22 at 06:05
  • I tried several of these answers, and this is the one that worked for me. And. so. simple. – TheGeeko61 Mar 01 '23 at 19:30
6

Something that has worked for me was:

  <plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.build.directory}/classes</outputDirectory>
        </configuration>
      </execution>

    </executions>
  </plugin>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
      <execution>
        <id>unpack-dependencies</id>
        <phase>package</phase>
      </execution>
    </executions>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <classpathPrefix>lib/</classpathPrefix>
          <mainClass>SimpleKeyLogger</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

I had an extraordinary case, because my dependency was system one:

<dependency>
  ..
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/myjar.jar</systemPath>
</dependency>

I have changed the code provided by user189057 with changes:

  1. maven-dependency-plugin is executed in "prepare-package" phase
  2. I am extracting unpacked classes directly to "target/classes"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fascynacja
  • 1,625
  • 4
  • 17
  • 35
6

It may not be a good idea to embed all the dependencies in the project's JAR file itself.

I see the point (ease of deployment / usage), but it depends of the use case of your project (and there may be alternatives (see below)).

If you use it fully standalone, why not?

But if you use your project in other contexts (like in a web application, or dropped in a folder where other JARs are sitting), you may have JAR duplicates in your classpath (the ones in the folder, the one in the JAR files). Maybe not a bid deal, but I usually avoid this.

A good alternative:

  • deploy your application as a ZIP or WAR file: the archive contains your project's JAR file and all dependent JAR files;
  • use a dynamic classloader mechanism (see Spring Framework, or you can easily do this yourself) to have a single entry point of your project (a single class to start - see the Manifest mechanism in another answer), which will add (dynamically) to the current classpath all the other needed JAR files.

Like this, with in the end just a manifest and a "special dynamic classloader main", you can start your project with:

java -jar ProjectMainJar.jar com.stackoverflow.projectName.MainDynamicClassLoaderClass
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SRG
  • 1,569
  • 1
  • 17
  • 19
6

This is the best way I found:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <archive>
      <manifest>
      <addClasspath>true</addClasspath>
      <mainClass>com.myDomain.etc.MainClassName</mainClass>
      <classpathPrefix>dependency-jars/</classpathPrefix>
      </manifest>
    </archive>
  </configuration>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>2.5.1</version>
  <executions>
    <execution>
      <id>copy-dependencies</id>
      <phase>package</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>
          ${project.build.directory}/dependency-jars/
        </outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

With this configuration, all dependencies will be located in /dependency-jars. My application has no Main class, just context ones, but one of my dependencies do have a Main class (com.myDomain.etc.MainClassName) that starts the JMX server, and receives a start or a stop parameter. So with this I was able to start my application like this:

java -jar ./lib/TestApp-1.0-SNAPSHOT.jar start
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
EliuX
  • 11,389
  • 6
  • 45
  • 40
6

There are millions of answers already. I wanted to add you don't need <mainClass> if you don't need to add entryPoint to your application. For example, APIs may not have necessarily have a main method.

Maven plugin configuration

  <build>
    <finalName>log-enrichment</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>

Build

mvn clean compile assembly:single

Verify

ll target/
total 35100
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ./
drwxrwx--- 1 root vboxsf     4096 Sep 29 16:25 ../
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 archive-tmp/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 classes/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-sources/
drwxrwx--- 1 root vboxsf        0 Sep 29 16:25 generated-test-sources/
-rwxrwx--- 1 root vboxsf 35929841 Sep 29 16:10 log-enrichment-jar-with-dependencies.jar*
drwxrwx--- 1 root vboxsf        0 Sep 29 16:08 maven-status/
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
prayagupa
  • 30,204
  • 14
  • 155
  • 192
6

I wanted to migrate my Spring application (using Apereo Foundation's CAS client) to Spring Boot 1.5. I ran into many problems, like:

no main manifest attribute, in target/cas-client-web.jar

I tried to make one unique JAR file with all dependencies. After searching on the Internet, I was able to do it with these lines:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <fork>true</fork>
        <mainClass>${start-class}</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>${start-class}</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
</plugin>

start-class is my main class:

<properties>
    <java.version>1.8</java.version>
    <start-class>com.test.Application</start-class>
</properties>

And my Application is:

package com.test;

import java.util.Arrays;

import com.test.TestProperties;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration
@EnableConfigurationProperties({TestProperties.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {

            System.out.println("Let's inspect the beans provided by Spring Boot:");

            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                System.out.println(beanName);
            }
        };
    }

}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
uwevil
  • 660
  • 6
  • 12
  • What is "CAS"? [Central Authentication Service](https://en.wikipedia.org/wiki/Central_Authentication_Service)? – Peter Mortensen Aug 17 '22 at 07:30
  • Or [computer algebra system](https://en.wikipedia.org/wiki/Computer_algebra_system)? – Peter Mortensen Aug 18 '22 at 05:04
  • [Jasig](https://en.wikipedia.org/wiki/Jasig)'s (now [Apereo Foundation](https://en.wikipedia.org/wiki/Apereo_Foundation#Merger_with_Sakai_Foundation)) *[Central Authentication Service](https://en.wikipedia.org/wiki/Jasig#Software_projects)* client? – Peter Mortensen Aug 18 '22 at 05:10
  • [GitHub page](https://github.com/apereo/cas) - *"CAS is an enterprise multilingual single sign-on solution for the web and attempts to be a comprehensive platform for your authentication and authorization needs. ... The primary implementation of the protocol is an open-source Java server component by the same name ... CAS is 100% free open source software managed by Apereo"* – Peter Mortensen Aug 18 '22 at 05:18
5

This could also be an option. You will be able to build your JAR file.

<build>
    <plugins>
        <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>WordListDriver</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
salmanbw
  • 1,301
  • 2
  • 17
  • 23
5

To create an executable JAR from the command line itself, just run the below command from the project path:

mvn assembly:assembly
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mayank
  • 67
  • 1
  • 1
  • 5
    I think you still need to do some stuff in the `pom.xml` otherwise you get `Error reading assemblies: No assembly descriptors found.`. That's what happens for me anyway. – Sridhar Sarnobat Sep 08 '17 at 18:59
4

I tried the most upvoted answer here and was able to get the JAR file runnable. But the program didn't run correctly. I do not know what the reason was. When I try to run from Eclipse, I get a different result, but when I run the JAR file from command line I get a different result (it crashes with a program-specific runtime error).

I had a similar requirement as the OP just that I had too many (Maven) dependencies for my project. Fortunately, the only solution that worked for me was that using Eclipse. It is very simple and very straightforward. This is not a solution for the OP, but it is a solution for someone who has a similar requirement, but with many Maven dependencies,

  1. Just right-click on your project folder (in Eclipse) and select Export

  2. Then select JavaRunnable JAR

  3. You will be asked to choose the location of the JAR file

  4. Finally, select the class that has the Main method that you want to run and choose *Package dependencies with the JAR file and click Finish

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rocky Inde
  • 1,511
  • 1
  • 20
  • 27
4

Add to file pom.xml:

<dependency>
    <groupId>com.jolira</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.4.4</version>
</dependency>

And

<plugin>
    <groupId>com.jolira</groupId>
    <artifactId>onejar-maven-plugin</artifactId>
    <version>1.4.4</version>
    <executions>
        <execution>
            <goals>
                <goal>one-jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

That’s it. Next, the mvn package will also create one fat JAR additionally, including all dependency JAR files.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Aydin K.
  • 3,309
  • 36
  • 44
3

The maven-assembly-plugin worked great for me.

I spent hours with the maven-dependency-plugin and couldn't make it work. The main reason was that I had to define the artifact items explicitly in the configuration section which should be included as it is described in the documentation.

There is an example there for the cases when you want to use it like: mvn dependency:copy, where there are not included any artifactItems, but it doesn't work.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Chris
  • 549
  • 1
  • 5
  • 18
3

I tried multiple solutions, but this is the one that worked perfectly in the scenario where we wanted to create a non-executable fat JAR file with all internal dependencies for external systems having no previous relevance. A production scenario was tested.

Include this in the pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<build>
   <sourceDirectory>src</sourceDirectory>
   <plugins>
      <plugin>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.8.1</version>
         <configuration>
            <source>1.8</source>
            <target>1.8</target>
         </configuration>
      </plugin>
      <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
         <configuration>
            <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
         </configuration>
      </plugin>
   </plugins>
</build>

The command to run to build the fat JAR file:

mvn assembly:assembly
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

This blog post shows another approach with combining the maven-jar and maven-assembly plugins. With the assembly configuration XML file from the blog post it can also be controlled if dependencies will be expanded or just be collected in a folder and referenced by a classpath entry in the manifest:

The ideal solution is to include the jars in a lib folder and the manifest.mf file of the main jar include all the jars in classpath.

And exactly that one is described here: Executable JAR file with dependent JAR files using Maven

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jan Ziegler
  • 106
  • 1
  • 4
0

Use:

mvn clean install -U dependency:copy-dependencies

The .jar file will be generated in the folder called "target", in the same root as the "src" folder.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matheus Santz
  • 538
  • 6
  • 7
-1

Okay, so this is my solution. I know it's not using the pom.xml file. But I had the problem with my programmme compiling and running on NetBeans, but it failing when I tried Java -jar MyJarFile.jar. Now, I don't fully understand Maven and I think this why was having trouble getting NetBeans 8.0.2 to include my JAR file in a library to put them into a JAR file. I was thinking about how I used to use JAR files with no Maven in Eclipse.

It's Maven that can compile all the dependencies and plugins. Not NetBeans. (If you can get NetBeans and be able to use java .jar to do this please tell me how (^.^)v )

Solved - for Linux: by opening a terminal.

Then

cd /MyRootDirectoryForMyProject

Next

mvn org.apache.maven.plugins:maven-compiler-plugin:compile

Next

mvn install

This will create a JAR file in the target directory.

MyJarFile-1.0-jar-with-dependencies.jar

Now

cd target

(You may need to run: chmod +x MyJarFile-1.0-jar-with-dependencies.jar)

And finally

java -jar MyJarFile-1.0-jar-with-dependencies.jar

Please see LifecyclePhaseNotFoundException.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mycowan
  • 993
  • 8
  • 18
  • 2
    Try opening the Maven project you created with Netbeans. The basic rule of Netbeans is always create a Maven project and never a 'Java application' The add a maven-shade-plugin like one of the answers. Works like a charm. – rjdkolb Nov 02 '15 at 10:45
-2
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4.1</version>
            <configuration>
                <!-- get all project dependencies -->
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <!-- bind to the packaging phase -->
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Shang Gao
  • 57
  • 1
  • 2
  • 1
    Include some text explaining your solution. See this help on writing a good answer https://stackoverflow.com/help/how-to-answer. – cb4 Apr 19 '22 at 03:04