10

I have the following custom assembly:

<assembly>
    <id>full</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.outputDirectory}</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

And the following configuration section:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptors>
            <descriptor>src/main/assembly/assembly.xml</descriptor>
        </descriptors>
        <archive>
            <manifest>
                <mainClass>com.example.MyExample</mainClass>
                <addClasspath>true</addClasspath>
                <classpathPrefix>./lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

According to the documentation on the maven assembly plugin, this should add a classpath item to the manifest file, however it does not work. If I use the deprecated assembly goal instead of single, it does work.

I noticed somewhere someone mentioned that the archive section is only available with the jar format, but that is what I'm using.

When they deprecated assembly:assembly, did they define a new way of doing this correctly? I really don't like using deprecated functionality, but if they break the way things worked and don't properly document it, I really don't know how to avoid this.

Does anyone have any examples of how to do this properly?

jpaugh
  • 6,634
  • 4
  • 38
  • 90
davija
  • 301
  • 2
  • 3
  • 10

3 Answers3

4

This is not a good use of the assembly plugin. Java doesn't do jars-in-jars. You can use the maven-jar-plugin's configuration options to add a classpath to the manifest of your main jar, and then use the assembly plugin to collect your dependencies and drop then next to your main jar in a zip or tarball.

http://maven.apache.org/shared/maven-archiver/examples/classpath.html

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • I have since removed the dependencies from the jar and am placing them in a lib folder alongside the jar. However, the problem still remains. The assembly plugin does not add the classpath as specified. – davija Sep 15 '11 at 00:32
  • It's not supposed to. The jar plugin has that job. – bmargulies Sep 15 '11 at 12:07
  • 4
    According to the documentation on the assembly plugin, if you tell it to add the classpath it does. It works in other goals that are now deprecated. Check the docs – davija Sep 24 '11 at 23:42
  • @bmargulies What about fat jars, which package all dependencies together? Isn't that the whole point of it? – jpaugh Mar 28 '16 at 18:17
  • Ok, so this [answer](https://stackoverflow.com/questions/12357136/reference-jars-inside-a-jar) clears it up. I had heard about One Jar, but didn't realize this was impossible *without* One Jar. – jpaugh Mar 28 '16 at 18:34
3

Try updating the maven-assembly-plugin to version 2.5 or newer.

The unexpected absence of the entry Class-Path in the manifest file seems to have been caused by the bug MASSEMBLY-576. The bug was fixed in version 2.5 of the plugin (released 26 October 2014).

Filip Bártek
  • 646
  • 7
  • 15
2

You should use the maven jar plugin:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>main class</mainClass>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>
Brant Bobby
  • 14,956
  • 14
  • 78
  • 115
Adi Mor
  • 2,145
  • 5
  • 25
  • 44