3

I've been working on a Java Maven project that ultimately creates an executable jar file. At first I had no issues, but then I decided I wanted the dependencies to be copied into the jar as well.

I found the following (very helpful) stack overflow question and followed the instructions provided in the answer (substituting my own main class and target version): Problem building executable jar with maven

This worked wonderfully, but I end up with two jar files (ldap-daemon-0.0.1-SNAPSHOT.jar and ldap-daemon-0.0.1-SNAPSHOT-jar-with-dependencies.jar). I'd be ok with this, but as far as I can tell I can't actually get a copy of the jar with dependencies later using the maven-dependency-plugin's copy functionality.

So, what I want to know is how to accomplish one of the following:

  • Have my main build artifact, ldap-daemon-0.0.1-SNAPSHOT.jar, contain its dependencies
  • Use the maven-dependency-plugin to copy the second build artifact (ldap-daemon-0.0.1-SNAPSHOT-jar-with-dependencies.jar).

Here is my plugin configuration for the ldap-daemon (packaging configuration is "jar"):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <mainClass>com.acuitus.ldapd.LDAPDaemonImp</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>6</source>
        <target>6</target>
    </configuration>
</plugin>

And here is my plugin configuration attempting to copy the resulting jar into a folder in a downstream project:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.7</version>
    <executions>
        <execution>
            <id>copy</id>
            <phase>package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>com.acuitus</groupId>
                        <artifactId>ldap-daemon</artifactId>
                        <version>0.0.1-SNAPSHOT</version>
                        <type>jar</type>
                        <overWrite>true</overWrite>
                        <outputDirectory>${project.build.directory}/classes/www-export</outputDirectory>
                        <destFileName>ldap-daemon.jar</destFileName>
                    </artifactItem>
                </artifactItems>
                    <outputDirectory>${project.build.directory}/wars</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
        </execution>
    </executions>
</plugin>

Any assistance is greatly appreciated. Thanks for your time!

Community
  • 1
  • 1
Alex Broadwin
  • 1,288
  • 11
  • 23

1 Answers1

4

Like you already know the assembly plugin generate two jar files the normal one and one with all dependencies. Maven uses the classifier construct for artefacts build from the same pom but differing in there content, for example one for jdk1.6 or jdk1.7. Or a more common example is the source code jar file from maven. This construct is also used by the assembly plugin. Your copy config looks like this:

<artifactItem>
    <groupId>com.acuitus</groupId>
    <artifactId>ldap-daemon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <type>jar</type>
    <overWrite>true</overWrite>
    <outputDirectory>${project.build.directory}/classes/www-export</outputDirectory>
    <destFileName>ldap-daemon.jar</destFileName>
 </artifactItem>

So you tell maven to copy the normal jar file without the dependencies.

However the jar file you want is the ldap-daemon-0.0.1-SNAPSHOT-jar-with-dependencies.jar. So you need to specify the classifier so maven is able to fetch the correct jar file:

<artifactItem>
    <groupId>com.acuitus</groupId>
    <artifactId>ldap-daemon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <type>jar</type>
    <classifier>jar-with-dependencies</classifier>
    <overWrite>true</overWrite>
    <outputDirectory>${project.build.directory}/classes/www-export</outputDirectory>
    <destFileName>ldap-daemon.jar</destFileName>
 </artifactItem>

I still recommend to have a look also at maven-shade-plugin when you need more control over the generated jar files and classifier used.

mszalbach
  • 10,612
  • 1
  • 41
  • 53
  • It is a dependency, and I am executing mvn install, but all I can get in the downstream project is ldap-daemon-0.0.1-SNAPSHOT.jar, not ldap-daemon-0.0.1-SNAPSHOT-jar-with-dependencies.jar. I haven't been able to find any success with various values in the second plugin configuration above. I don't feel I should need to use the shade plugin since the jar I'm creating is correct, and in the correct directory, but I simply don't know how to reference it in the downstream projects. Am I misunderstanding the benefit of the shade plugin here? Thanks for taking the time to answer. Much appreciated! – Alex Broadwin May 08 '13 at 22:42
  • Hi. Sorry was kinda confused yesterday and did not get your requirement at all. I have corrected my answer above and hopes this is what you was looking for. – mszalbach May 09 '13 at 08:49
  • That did the job perfectly :) Thanks! We recently changed build systems and I'm still getting up to speed on Maven. I appreciate your help! – Alex Broadwin May 09 '13 at 18:57