Maven - Creating a Single executable Jar with dependencies.

[Updated: Mar 14, 2017, Created: Jan 15, 2017]

Apache Maven Assembly plugin allows to create an executable jar which includes all its dependencies within it. The resultant jar is also called 'fat jar'.



Example

Create a simple project

Create a project using maven-archetype-quickstart with following parameters.

 <groupId>com.logicbig.example</groupId>
 <artifactId>maven-assembly-plugin-example</artifactId>
 <version>1.0-SNAPSHOT</version>

Import the project into your IDE.


Add dependency of third party jar

As in this example we are using to demonstrate how to create a jar with dependencies. We chose com.google.guava as a dependent jar.

<project ...>
   ......
 <dependencies>
  <dependency>
   <groupId>com.google.guava</groupId>
   <artifactId>guava</artifactId>
   <version>21.0</version>
  </dependency>
 </dependencies>
  ...
</project ...>


Add maven-assembly-plugin in pom

<project .....>
 .......
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
     <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
     </descriptorRefs>
     <archive>
      <manifest>
       <mainClass>com.logicbig.example.Main</mainClass>
      </manifest>
     </archive>
    </configuration>
    <executions>
     <execution>
      <phase>package</phase>
      <goals>
       <goal>single</goal>
      </goals>
     </execution>
    </executions>
   </plugin>
  </plugins>
 </build>
</project>


Create a Main class

package com.logicbig.example;


import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;

public class Main {
    public static void main (String[] args) {
        Multimap<Integer, String> map =
                                 LinkedListMultimap.create();
        map.put(1, "apple");
        map.put(1, "banana");
        map.put(1, "orange");
        System.out.println(map);
    }
}

Run the above class to check if everything is working.

Output

 {1=[apple, banana, orange]}


Package the jar

Now run package goal from command line:

mvn package

It will kick off 'assembly:single' goal as we have attached it with 'package' in above pom using <execution>.

We can also run mvn assembly:single instead.



Running resultant executable jar

Here's are all steps on windows cmd. It shows directory tree before and after packaging. At the end, we are executing jar and having the same output:


D:\examples\maven-assembly-plugin-example>mvn -q clean

D:\examples\maven-assembly-plugin-example>tree /A /F
Folder PATH listing for volume Data
Volume serial number is 000000A3 68F9:EDFA
D:.
|   pom.xml
|
\---src
    \---main
        \---java
            \---com
                \---logicbig
                    \---example
                            Main.java


D:\examples\maven-assembly-plugin-example>mvn -q package

D:\examples\maven-assembly-plugin-example>tree /A /F
Folder PATH listing for volume Data
Volume serial number is 0000008D 68F9:EDFA
D:.
|   pom.xml
|
+---src
|   \---main
|       \---java
|           \---com
|               \---logicbig
|                   \---example
|                           Main.java
|
\---target
    |   maven-assembly-plugin-example-1.0-SNAPSHOT-jar-with-dependencies.jar
    |   maven-assembly-plugin-example-1.0-SNAPSHOT.jar
    |
    +---archive-tmp
    +---classes
    |   \---com
    |       \---logicbig
    |           \---example
    |                   Main.class
    |
    +---maven-archiver
    |       pom.properties
    |
    \---maven-status
        \---maven-compiler-plugin
            \---compile
                \---default-compile
                        createdFiles.lst
                        inputFiles.lst


D:\examples\maven-assembly-plugin-example>java -jar target\maven-assembly-plugin-example-1.0-SNAPSHOT-jar-with-dependencies.jar
{1=[apple, banana, orange]}

D:\examples\maven-assembly-plugin-example>


What's inside jar with dependencies?

Followings creates a temp folder and extracts jar with dependencies there to see the tree.


D:\examples\maven-assembly-plugin-example>md temp

D:\examples\maven-assembly-plugin-example>cd temp

D:\examples\maven-assembly-plugin-example\temp>jar -xf ..\target\maven-assembly-plugin-example-1.0-SNAPSHOT-jar-with-dependencies.jar

D:\examples\maven-assembly-plugin-example\temp>tree /A /F
Folder PATH listing for volume Data
Volume serial number is 0000007D 68F9:EDFA
D:.
+---com
|   +---google
|   |   +---common
|   |   |   +---annotations
|   |   |   |       Beta.class
|   |   |   |       GwtCompatible.class
|   |   |   |       GwtIncompatible.class
|   |   |   |       VisibleForTesting.class
|   |   |   |
|   |   |   +---base
|   |   |   |   |   Absent.class
|   |   |   |   |   AbstractIterator$1.class
|   |   |   |   |   AbstractIterator$State.class
|   |   |   |   |   AbstractIterator.class
|   |   |   |   |   Ascii.class
|   |   |   |   |   CaseFormat$1.class
|   |   |   |   |   CaseFormat$2.class
|   |   |   |   |   CaseFormat$3.class
|   |   |   |   |   CaseFormat$4.class
|   |   |   |   |   CaseFormat$5.class
|   |   |   |   |   CaseFormat$StringConverter.class
|   |   |   |   |   CaseFormat.class
|   |   |   |   |   CharMatcher$1.class
|   |   |   |   |   CharMatcher$And.class
|   |   |   |   |   CharMatcher$Any.class
|   |   |   |   |   CharMatcher$AnyOf.class
|   |   |   |   |   CharMatcher$Ascii.class
|   |   |   |   |   CharMatcher$BitSetMatcher.class
|   |   |   |   |   CharMatcher$BreakingWhitespace.class
|   |   |   |   |   CharMatcher$Digit.class
|   |   |   |   |   CharMatcher$FastMatcher.class
|   |   |   |   |   CharMatcher$ForPredicate.class
|   |   |   |   |   CharMatcher$InRange.class
|   |   |   |   |   CharMatcher$Invisible.class
|   |   |   |   |   CharMatcher$Is.class
|   |   |   |   |   CharMatcher$IsEither.class
|   |   |   |   |   CharMatcher$IsNot.class
|   |   |   |   |   CharMatcher$JavaDigit.class
|   |   |   |   |   CharMatcher$JavaIsoControl.class
|   |   |   |   |   CharMatcher$JavaLetter.class
|   |   |   |   |   CharMatcher$JavaLetterOrDigit.class
|   |   |   |   |   CharMatcher$JavaLowerCase.class
|   |   |   |   |   CharMatcher$JavaUpperCase.class
        --------------------- more -----------------------------
|   |   |   |   |
|   |   |   |   \---internal
|   |   |   |           Finalizer.class
|   |   |   |
|   |   |   +---cache
|   |   |   |       AbstractCache$SimpleStatsCounter.class
|   |   |   |       AbstractCache$StatsCounter.class
|   |   |   |       AbstractCache.class
|   |   |   |       AbstractLoadingCache.class
|   |   |   |       Cache.class
|   |   |   |       CacheBuilder$1.class
|   |   |   |       CacheBuilder$2.class
|   |   |   |       CacheBuilder$3.class
|   |   |   |       CacheBuilder$NullListener.class
|   |   |   |       CacheBuilder$OneWeigher.class
|   |   |   |       CacheBuilder.class
|   |   |   |       CacheBuilderSpec$1.class
|   |   |   |       CacheBuilderSpec$AccessDurationParser.class
|   |   |   |       CacheBuilderSpec$ConcurrencyLevelParser.class
|   |   |   |       CacheBuilderSpec$DurationParser.class
|   |   |   |       CacheBuilderSpec$InitialCapacityParser.class
|   |   |   |       CacheBuilderSpec$IntegerParser.class
|   |   |   |       CacheBuilderSpec$KeyStrengthParser.class
|   |   |   |       CacheBuilderSpec$LongParser.class
|   |   |   |       CacheBuilderSpec$MaximumSizeParser.class
|   |   |   |       CacheBuilderSpec$MaximumWeightParser.class
|   |   |   |       CacheBuilderSpec$RecordStatsParser.class
|   |   |   |       CacheBuilderSpec$RefreshDurationParser.class
        --------------------- more -----------------------------
|   |   |   |
|   |   |   +---collect
|   |   |   |       AbstractBiMap$1.class
|   |   |   |       AbstractBiMap$BiMapEntry.class
|   |   |   |       AbstractBiMap$EntrySet.class
|   |   |   |       AbstractBiMap$Inverse.class
|   |   |   |       AbstractBiMap$KeySet.class
|   |   |   |       AbstractBiMap$ValueSet.class
|   |   |   |       AbstractBiMap.class
|   |   |   |       AbstractIndexedListIterator.class
|   |   |   |       AbstractIterator$1.class
|   |   |   |       AbstractIterator$State.class
|   |   |   |       AbstractIterator.class
|   |   |   |       AbstractListMultimap.class
|   |   |   |       AbstractMapBasedMultimap$1.class
        --------------------- more -----------------------------
|   |   |   +---graph
|   |   |   |       AbstractDirectedNetworkConnections$1.class
|   |   |   |       AbstractDirectedNetworkConnections.class
|   |   |   |       AbstractGraph$1.class
|   |   |   |       AbstractGraph.class
|   |   |   |       AbstractGraphBuilder.class
|   |   |   |       AbstractNetwork$1$1$1.class
|   |   |   |       AbstractNetwork$1$1.class
|   |   |   |       AbstractNetwork$1.class
|   |   |   |       AbstractNetwork$2.class
|   |   |   |       AbstractNetwork.class
|   |   |   |       AbstractUndirectedNetworkConnections.class
|   |   |   |       AbstractValueGraph$1.class
|   |   |   |       AbstractValueGraph.class
|   |   |   |       ConfigurableMutableGraph.class
|   |   |   |       ConfigurableMutableNetwork.class
|   |   |   |       ConfigurableMutableValueGraph.class
|   |   |   |       ConfigurableNetwork.class
|   |   |   |       ConfigurableValueGraph.class
|   |   |   |       DirectedGraphConnections$1$1.class
|   |   |   |       DirectedGraphConnections$1.class
|   |   |   |       DirectedGraphConnections$2$1.class
|   |   |   |       DirectedGraphConnections$2.class
|   |   |   |       DirectedGraphConnections$PredAndSucc.class
|   |   |   |       DirectedGraphConnections.class
|   |   |   |       DirectedMultiNetworkConnections$1.class
        --------------------- more -----------------------------
|   |   |   +---hash
|   |   |   |       AbstractByteHasher.class
|   |   |   |       AbstractCompositeHashFunction$1.class
|   |   |   |       AbstractCompositeHashFunction.class
|   |   |   |       AbstractHasher.class
|   |   |   |       AbstractNonStreamingHashFunction$BufferingHasher.class
|   |   |   |       AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream.class
|   |   |   |       AbstractNonStreamingHashFunction.class
|   |   |   |       AbstractStreamingHashFunction$AbstractStreamingHasher.class
|   |   |   |       AbstractStreamingHashFunction.class
|   |   |   |       BloomFilter$1.class
|   |   |   |       BloomFilter$SerialForm.class
|   |   |   |       BloomFilter$Strategy.class
|   |   |   |       BloomFilter.class
|   |   |   |       BloomFilterStrategies$1.class
|   |   |   |       BloomFilterStrategies$2.class
|   |   |   |       BloomFilterStrategies$BitArray.class
|   |   |   |       BloomFilterStrategies.class
|   |   |   |       ChecksumHashFunction$1.class
|   |   |   |       ChecksumHashFunction$ChecksumHasher.class
|   |   |   |       ChecksumHashFunction.class
|   |   |   |       Crc32cHashFunction$Crc32cHasher.class
|   |   |   |       Crc32cHashFunction.class
|   |   |   |       FarmHashFingerprint64.class
|   |   |   |       Funnel.class
|   |   |   |       Funnels$ByteArrayFunnel.class
|   |   |   |       Funnels$IntegerFunnel.class
|   |   |   |       Funnels$LongFunnel.class
|   |   |   |       Funnels$SequentialFunnel.class
        --------------------- more -----------------------------
|   |   |   |
|   |   |   +---html
|   |   |   |       HtmlEscapers.class
|   |   |   |       package-info.class
|   |   |   |
|   |   |   +---io
|   |   |   |       AndroidIncompatible.class
|   |   |   |       AppendableWriter.class
|   |   |   |       BaseEncoding$1.class
|   |   |   |       BaseEncoding$2.class
|   |   |   |       BaseEncoding$3.class
|   |   |   |       BaseEncoding$4.class
|   |   |   |       BaseEncoding$5.class
|   |   |   |       BaseEncoding$Alphabet.class
|   |   |   |       BaseEncoding$Base16Encoding.class
|   |   |   |       BaseEncoding$Base64Encoding.class
|   |   |   |       BaseEncoding$DecodingException.class
|   |   |   |       BaseEncoding$SeparatedBaseEncoding.class
|   |   |   |       BaseEncoding$StandardBaseEncoding$1.class
|   |   |   |       BaseEncoding$StandardBaseEncoding$2.class
|   |   |   |       BaseEncoding$StandardBaseEncoding.class
|   |   |   |       BaseEncoding.class
|   |   |   |       ByteArrayDataInput.class
|   |   |   |       ByteArrayDataOutput.class
|   |   |   |       ByteProcessor.class
|   |   |   |       ByteSink$1.class
|   |   |   |       ByteSink$AsCharSink.class
|   |   |   |       ByteSink.class
        --------------------- more -----------------------------
|   |   |   |
|   |   |   +---math
|   |   |   |       BigIntegerMath$1.class
|   |   |   |       BigIntegerMath.class
|   |   |   |       DoubleMath$1.class
|   |   |   |       DoubleMath.class
|   |   |   |       DoubleUtils.class
|   |   |   |       IntMath$1.class
|   |   |   |       IntMath.class
|   |   |   |       LinearTransformation$1.class
|   |   |   |       LinearTransformation$LinearTransformationBuilder.class
|   |   |   |       LinearTransformation$NaNLinearTransformation.class
|   |   |   |       LinearTransformation$RegularLinearTransformation.class
|   |   |   |       LinearTransformation$VerticalLinearTransformation.class
|   |   |   |       LinearTransformation.class
|   |   |   |       LongMath$1.class
|   |   |   |       LongMath$MillerRabinTester$1.class
|   |   |   |       LongMath$MillerRabinTester$2.class
|   |   |   |       LongMath$MillerRabinTester.class
|   |   |   |       LongMath.class
|   |   |   |       MathPreconditions.class
|   |   |   |       package-info.class
|   |   |   |       PairedStats.class
|   |   |   |       PairedStatsAccumulator.class
|   |   |   |       Quantiles$1.class
|   |   |   |       Quantiles$Scale.class
|   |   |   |       Quantiles$ScaleAndIndex.class
|   |   |   |       Quantiles$ScaleAndIndexes.class
|   |   |   |       Quantiles.class
|   |   |   |       Stats.class
|   |   |   |       StatsAccumulator.class
|   |   |   |
|   |   |   +---net
|   |   |   |       HostAndPort.class
|   |   |   |       HostSpecifier.class
|   |   |   |       HttpHeaders.class
|   |   |   |       InetAddresses$TeredoInfo.class
|   |   |   |       InetAddresses.class
|   |   |   |       InternetDomainName.class
|   |   |   |       MediaType$1.class
|   |   |   |       MediaType$2.class
|   |   |   |       MediaType$Tokenizer.class
|   |   |   |       MediaType.class
|   |   |   |       package-info.class
|   |   |   |       PercentEscaper.class
|   |   |   |       UrlEscapers.class
|   |   |   |
|   |   |   +---primitives
|   |   |   |       Booleans$BooleanArrayAsList.class
|   |   |   |       Booleans$BooleanComparator.class
|   |   |   |       Booleans$LexicographicalComparator.class
|   |   |   |       Booleans.class
|   |   |   |       Bytes$ByteArrayAsList.class
|   |   |   |       Bytes.class
|   |   |   |       Chars$CharArrayAsList.class
|   |   |   |       Chars$LexicographicalComparator.class
|   |   |   |       Chars.class
|   |   |   |       Doubles$DoubleArrayAsList.class
|   |   |   |       Doubles$DoubleConverter.class
|   |   |   |       Doubles$LexicographicalComparator.class
|   |   |   |       Doubles.class
|   |   |   |       Floats$FloatArrayAsList.class
|   |   |   |       Floats$FloatConverter.class
|   |   |   |       Floats$LexicographicalComparator.class
|   |   |   |       Floats.class
|   |   |   |       Ints$IntArrayAsList.class
|   |   |   |       Ints$IntConverter.class
|   |   |   |       Ints$LexicographicalComparator.class
|   |   |   |       Ints.class
|   |   |   |       Longs$LexicographicalComparator.class
|   |   |   |       Longs$LongArrayAsList.class
|   |   |   |       Longs$LongConverter.class
|   |   |   |       Longs.class
|   |   |   |       package-info.class
|   |   |   |       ParseRequest.class
|   |   |   |       Primitives.class
|   |   |   |       Shorts$LexicographicalComparator.class
|   |   |   |       Shorts$ShortArrayAsList.class
|   |   |   |       Shorts$ShortConverter.class
|   |   |   |       Shorts.class
|   |   |   |       SignedBytes$LexicographicalComparator.class
|   |   |   |       SignedBytes.class
|   |   |   |       UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator.class
|   |   |   |       UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1.class
|   |   |   |       UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator.class
|   |   |   |       UnsignedBytes$LexicographicalComparatorHolder.class
|   |   |   |       UnsignedBytes.class
|   |   |   |       UnsignedInteger.class
|   |   |   |       UnsignedInts$LexicographicalComparator.class
|   |   |   |       UnsignedInts.class
|   |   |   |       UnsignedLong.class
|   |   |   |       UnsignedLongs$LexicographicalComparator.class
|   |   |   |       UnsignedLongs.class
|   |   |   |
|   |   |   +---reflect
|   |   |   |       AbstractInvocationHandler.class
|   |   |   |       ClassPath$1.class
|   |   |   |       ClassPath$ClassInfo.class
|   |   |   |       ClassPath$DefaultScanner.class
|   |   |   |       ClassPath$ResourceInfo.class
|   |   |   |       ClassPath$Scanner.class
|   |   |   |       ClassPath.class
|   |   |   |       Element.class
|   |   |   |       ImmutableTypeToInstanceMap$1.class
|   |   |   |       ImmutableTypeToInstanceMap$Builder.class
|   |   |   |       ImmutableTypeToInstanceMap.class
|   |   |   |       Invokable$ConstructorInvokable.class
|   |   |   |       Invokable$MethodInvokable.class
|   |   |   |       Invokable.class
|   |   |   |       MutableTypeToInstanceMap$1.class
|   |   |   |       MutableTypeToInstanceMap$UnmodifiableEntry$1.class
|   |   |   |       MutableTypeToInstanceMap$UnmodifiableEntry$2.class
|   |   |   |       MutableTypeToInstanceMap$UnmodifiableEntry.class
|   |   |   |       MutableTypeToInstanceMap.class
        --------------------- more -----------------------------
|   |   |   |
|   |   |   +---util
|   |   |   |   \---concurrent
|   |   |   |           AbstractCatchingFuture$AsyncCatchingFuture.class
|   |   |   |           AbstractCatchingFuture$CatchingFuture.class
|   |   |   |           AbstractCatchingFuture.class
|   |   |   |           AbstractCheckedFuture.class
|   |   |   |           AbstractExecutionThreadService$1$1.class
|   |   |   |           AbstractExecutionThreadService$1$2.class
|   |   |   |           AbstractExecutionThreadService$1.class
|   |   |   |           AbstractExecutionThreadService$2.class
|   |   |   |           AbstractExecutionThreadService.class
|   |   |   |           AbstractFuture$1.class
|   |   |   |           AbstractFuture$AtomicHelper.class
|   |   |   |           AbstractFuture$Cancellation.class
|   |   |   |           AbstractFuture$Failure$1.class
|   |   |   |           AbstractFuture$Failure.class
|   |   |   |           AbstractFuture$Listener.class
|   |   |   |           AbstractFuture$SafeAtomicHelper.class
|   |   |   |           AbstractFuture$SetFuture.class
        --------------------- more -----------------------------
|   |   |   |           WrappingExecutorService$1.class
|   |   |   |           WrappingExecutorService.class
|   |   |   |           WrappingScheduledExecutorService.class
|   |   |   |
|   |   |   \---xml
|   |   |           package-info.class
|   |   |           XmlEscapers.class
|   |   |
|   |   \---thirdparty
|   |       \---publicsuffix
|   |               PublicSuffixPatterns.class
|   |               PublicSuffixType.class
|   |               TrieParser.class
|   |
|   \---logicbig
|       \---example
|               Main.class
|
\---META-INF
    |   MANIFEST.MF
    |
    \---maven
        +---com.google.guava
        |   \---guava
        |           pom.properties
        |           pom.xml
        |
        \---com.logicbig.example
            \---maven-assembly-plugin-example
                    pom.properties
                    pom.xml


D:\examples\maven-assembly-plugin-example\temp>

It shows that instead of creating nested dependent jars, this plugin creates a flat directory structure with merged java packages and classes tree.





Example Project

Dependencies and Technologies Used :

  • guava 21.0: Guava is a suite of core and expanded libraries that include utility classes, google's collections, io classes, and much much more. Guava has only one code dependency - javax.annotation, per the JSR-305 spec.
  • JDK 1.8
  • Maven 3.3.9

Assembly Plugin Example Select All Download
  • maven-assembly-plugin-example
    • src
      • main
        • java
          • com
            • logicbig
              • example

See Also