1

I have a .jar we have developed in-house. It is built using maven. It has a dependency, commons-codec, that is provided from the maven central repository.

.jar .pom dependency ("myjar"):

<packaging>jar</packaging>
...
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>         
</dependency>
...

.war .pom dependency:

<packaging>war</packaging>
...
<dependency>
    <groupId>com.myco.mydiv</groupId>
    <artifactId>myjar</artifactId>
    <version>1.5.54</version> 
</dependency>
....

I can build and test this jar without issue. When the jar is included as a dependency in a .war, it builds without problem, but at run time, the external dependency for commons-codec produces a class def not found exception.

I tried changing the scope for commons-codec in the .jar .pom to 'compile' but this did not help.

I can fix this by adding the commons-codec dependency to the .war .pom, but this is not the right way to fix it (I think) as it requires all projects using the .jar to know about this dependency and include it likewise. I could also include the external .jar in the WEB-INF/lib to solve this, but it also seems like the incorrect approach.

What is the best way to handle this? Why is the common-codec dependency not visible at run time for the .war?

This conversation seems to touch on a similar issue: https://github.com/ReactiveX/RxNetty/issues/292

And so I wonder if there is a right way to handle this with nested dependencies.

But I just noticed this answer, which seems to show the right way to do this: https://stackoverflow.com/a/98743/2266428

jar-with-dependencies via the maven-assembly-plugin seems to solve the problem but at the expense of a very large .jar (6 MB in my case).

J E Carter II
  • 1,436
  • 1
  • 22
  • 39
  • please share pom.xml – Aman Chhabra Jul 12 '18 at 16:39
  • Which parts do you think are most relevant, @AmanChhabra? The pom includes proprietary information, I'll need to create a simplified example to satisfy corporate security and want to make sure I provide enough. – J E Carter II Jul 12 '18 at 16:43
  • I've found two different approaches that offer different pros and cons. Fat Jars:https://www.mkyong.com/maven/create-a-fat-jar-file-maven-assembly-plugin/ and dependency uploading: https://product.hubspot.com/blog/the-fault-in-our-jars-why-we-stopped-building-fat-jars --- it really seems that I just need to understand dependencies better, like shouldn't I be able to just make sure one dependency makes it into my final jar? – J E Carter II Jul 12 '18 at 17:34

1 Answers1

0

After trying multiple approaches, it turns out the Shade plugin was exactly what was needed. The below added plugin configuration to my .war .pom, exactly as shown, added the dependency to the jar and made it available to the .war at runtime.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <minimizeJar>true</minimizeJar>
        </configuration>
      </execution>
    </executions>
  </plugin>

Unzipping the initial .jar shows that the following path and classes are now included in the build:

org > apache > commmons > codec > *.class
J E Carter II
  • 1,436
  • 1
  • 22
  • 39