Gary Greenberg
Gary Greenberg

Reputation: 1154

maven-assembly-plugin how to include jar file not from repository

I need to build a distribution jar-with-dependencies which includes one of the dependency jar that for certain reasons cannot be placed into Maven .m2/repository. In my POM file I have:

<dependencies>
    <dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>4.0</version>
    </dependency>
    <dependency>
        <groupId>com.abc.ets</groupId>
        <artifactId>mylib</artifactId>
        <version>3.0.0_258779</version>
        <scope>system</scope>
        <systemPath>${basedir}/lib/mylib_3.0.0_258779.jar</systemPath>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.5</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.abc.myapp.service.MainService</mainClass>
                    </manifest>
                </archive>
            </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>       
    </plugins>
</build>

The build succeeds, but resulting MyApp-1.0.0-jar-with-dependencies.jar does not contain classes from that library, therefore throws ClassNotFoundException. I tried to create assembly.xml file to manage this jar file manually, but plugin documentation is quite sketchy and confusing. Here is what I put into assembly.xml

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
  <!-- TODO: a jarjar format would be better -->
  <id>jar-with-dependencies</id>
  <formats>
    <format>jar</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
      <outputDirectory>/</outputDirectory>
      <useProjectArtifact>true</useProjectArtifact>
      <unpack>true</unpack>
      <scope>runtime</scope>
      <includes>
          <include>${basedir}/lib/mylib_3.0.0_258779.jar</include>
      </includes>
    </dependencySet>
  </dependencySets>
</assembly>

When I run the build, I am getting

Reading assembly descriptor: src/assembly/assembly.xml The assembly id jar-with-dependencies is used more than once. The following patterns were never triggered in this artifact inclusion filter: o './lib/mylib_3.0.0_258779.jar'

The result is the same. Classes from this jar aren't included.

If someone has done similar things, I'd appreciate some pointers.

Upvotes: 2

Views: 4167

Answers (1)

Tunaki
Tunaki

Reputation: 137064

Dependencies having the system scope are expected to be provided at runtime. Quoting the Maven documentation:

Dependencies with the scope system are always available and are not looked up in repository. They are usually used to tell Maven about dependencies which are provided by the JDK or the VM. Thus, system dependencies are especially useful for resolving dependencies on artifacts which are now provided by the JDK, but where available as separate downloads earlier.

As such, the maven-assembly-plugin will not include those dependencies (as it is expected that they are provided). Note that this result will be exactly the same if you switch to the maven-shade-plugin.

The only way around your problem is NOT to use the system scope (which you should never have used to begin with). Instead, install this library to your Maven repo and then declare it in the POM like you would for any normal dependencies (see this answer for more info).

Upvotes: 0

Related Questions