Creating JAR with Maven dependencies

Asked

Viewed 6,704 times

9

I want to use the Maven to generate the JAR with its dependencies in format .jar, the solutions I found are not valid.

The Eclipse has three forms of generate a executable JAR.

  1. Extract required Libraries into gerenated JAR
  2. Package required Libraries into generated JAR < I use that in Eclipse.
  3. Copy required Libraries into a sub-Folder next to the generated JAR

And Maven has a form equivalent to Eclipse?


Using maven-jar-plugin

   <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>qualquer.que.seja.seu.pacote.ClasseMain</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

Problem: This mode generates a JAR without format dependencies .jar.


Using maven-assemply-plugin

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>qualquer.que.seja.seu.pacote.ClasseMain</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
</plugin>

Problem: Generates a JAR with "extracted" dependencies out of format .jars.

2 answers

5


There is also the Maven Shade Plugin that allows you to package the artifact in a super-jar, including its dependencies, and even rename the packages of some dependencies if you wish.

Take an example:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.2</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>org.sonatype.haven.HavenCli</mainClass>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Besides putting everything together in a single jar, which makes it very easy to distribute for download, for example, the Shade also allows renaming dependency packages, helping a lot in cases where there may be classpath conflicts, for example.

It is important to note that plugins Shade and Assembly are not direct competitors, although the two allow to pack the dependencies in a jar. When it comes to packaging, Assembly is more powerful, flexible and complicated. Shade has fewer features, but to create a Uber-jar it is more direct and simple.

  • I used that method and I get [ERROR] Could not find goal 'attached' in plugin org.apache.maven.plugins:maven-shade-plugin:2.2 among available goals shade, help -> [Help 1] and others. are looking for solutions.

  • 1

    Bug fixed. Was using <goal>attached</goal> I traded for <goal>shade</goal>.

  • @Eduardobentorochajunior Okay, I was just going to say I was more like the other answer.

  • 1

    @Liuutz, I like that shade, for each compilation it generates a JAR and keeps an old one, is that right? Has some way of having the .jar guy commons-net-3.3.jar. In all the tests I’ve done with Maven I have the Folder of my dependencies org/apache/commons/.. I believe it will work the same way, but my JAR earns a few kB and more. D

  • 1

    @Eduardobentorochajunior That’s right. Usually the new super jar serves for distribution and is fatter even, since it includes the dependencies within it. That way, you don’t need to have the jars in the folder. But, if you want to have the dependencies in separate jars, then you can use the other plugin (Assembly) to create a zip with the jars, for example.

  • 1

    +1 Hade is the scheme to package Big Yard easy to run.

Show 1 more comment

4

Missed you set up as the maven-assembly-plugin shall be executed, that is to say, which Goal and in what phase of Maven as well. To package a jar with dependencies during the package, the configuration looks like this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>qualquer.que.seja.seu.pacote.ClasseMain</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>attached</goal>
            </goals>
        </execution>
    </executions>
</plugin>
  • I took this test, it creates a JAR and the cool part is that JUNIT is no longer in mine JAR, but the dependencies continue unpacked in Folder format, Thank you

  • He didn’t create a jar nome-do-projeto-jar-with-dependencies.jar?

  • Created, however the dependencies are in format Folder (understand), the eclipse takes this commons-net-3.3.jar and put inside my .jar, using this plugin it creates a folder called org/apache/commons/... Got it?

  • I understood Eduardo. I tried here in every way to use the maven-assembly-plugin to generate with the jars and even I managed. However I bumped into a bug that does not put the classpath in the file MANIFEST.MF. Hence the jar is not executable.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.