Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Minimize an Uber Jar correctly, Using Shade-Plugin

I am using the Maven-Shade-Plugin to create a runnable Uber-jar. According to the last frame on this page, the size of the jar can be minimized by using:

<configuration>       <minimizeJar>true</minimizeJar> </configuration> 

But this feature does not take into consideration the classes that are declared in the log4j.properties file. Hence, e.g. org.apache.log4j.appender.TimeAndSizeRollingAppender is not included in the Uber-jar, even though it’s declared in the log4j.properties file.

I believe I will face the same problem with Spring. If my code only refers to interface A and my Spring file contains an instantiation of class B that implements A, then B might not be added to the jar, since it’s not in the code.

How can I solve this problem?

like image 447
summerbulb Avatar asked Jan 11 '12 09:01

summerbulb


People also ask

How does maven shade plugin work?

This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.

What is a dependency reduced POM?

Short Answer. The dependency-reduced-pom. xml removes transitive dependencies which are already in your shaded jar. This prevents consumers from pulling them in twice.


1 Answers

This functionality has been added to version 1.6 of the maven-shade-plugin (just released). minimizeJar will now not remove classes that have been specifically included with filters. Note that including some of an artifact's classes in a filter will exclude non-specified classes for that artifact, so be sure to include all the classes that you need.

Here's an example plugin config:

<plugin>     <groupId>org.apache.maven.plugins</groupId>     <artifactId>maven-shade-plugin</artifactId>     <version>1.6</version>         <executions>         <execution>             <phase>package</phase>             <goals>                 <goal>shade</goal>             </goals>                                     <configuration>                 <minimizeJar>true</minimizeJar>                     <filters>                      <filter>                        <artifact>log4j:log4j</artifact>                        <includes>                            <include>**</include>                        </includes>                     </filter>                      <filter>                        <artifact>commons-logging:commons-logging</artifact>                        <includes>                            <include>**</include>                        </includes>                     </filter>                                       </filters>             </configuration>         </execution>     </executions> </plugin> 

To only include specific classes, add them as includes using path slashes in the class name in a filter (again, non-included classes will be automatically excluded).

<filter>   <artifact>org.yourorg:your-artifact</artifact>   <includes>     <include>org/yourorg/yourartifact/api/*</include>     <include>org/yourorg/yourartifact/util/*</include>   </includes> </filter> 
like image 143
Shane Avatar answered Sep 19 '22 16:09

Shane