Search code examples
javamavenmaven-2uberjar

Having difficulty creating an uber-jar


I'm trying to bundle up a java archive (JAR) with all dependencies self contained. First I tried using the maven assembly plugin though this was missing some classes. The jar-with-dependencies documentation suggests using the maven-shade-plugin, which ends up missing different classes. I think what's happening is that multiple dependencies using the same package names seem to get skipped, so things like slf4j get skipped.

What I'd really prefer is for the packaged jar to contain the libraries self-contained instead of repacking them.

I nearly gave up and figured I'd just use the bin descriptor for the assembly plugin which only zipped up the jar itself and no dependencies.

NOTE: I know that others have asked similar questions, which have resulted in suggestions for using shade/assembly plugins, though none have illustrated the specific problem I am having.

UPDATE: Requested by khmarbaise the following shows one POM where ALL classes get skipped. Note that there is another JAR which uses the same package structure but is the localised bundle, localised bundles are included but all classes are omitted.

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.ddtek</groupId>
  <artifactId>openedge</artifactId>
  <packaging>jar</packaging>
  <version>10.1C04</version>
  <name>openedge</name>
  <url>http://progress.com</url>
  <dependencies>
    <dependency>
      <groupId>com.ddtek</groupId>
      <artifactId>base</artifactId>
      <version>10.1C04</version>
    </dependency>
    <dependency>
      <groupId>com.ddtek</groupId>
      <artifactId>util</artifactId>
      <version>10.1C04</version>
    </dependency>
  </dependencies>
</project>

Note that the above POM is a third-party library that does not publish to maven and only exists in our local nexus repo.


Solution

  • If no predefined descriptor suites your needs, you can write your own assembly.

    To include dependencies, you specify something like

    <dependencySets>
        <dependencySet>
          <outputDirectory>/lib</outputDirectory>
          <useProjectArtifact>false</useProjectArtifact>
          <useTransitiveDependencies>true</useTransitiveDependencies>
          <unpack>false</unpack>
           <scope>runtime</scope>
        </dependencySet>
      </dependencySets>
    

    and in your pom something like:

    <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.3</version>
            <configuration>
              <descriptors>
                <descriptor>assembly.xml</descriptor>
              </descriptors>
            </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>
    

    and then customize, following your requirements.