Saturday, May 23, 2020

Maven Shaded Plugin



This article is about the what is maven shaded plugin and where we should use it.

maven-shade-plugin is used for the multiple purpose :

  •  It can be used to generate the Uber jar and select the content of the Uber jar
  •  Relocating the classes (means reassign the package for the given class)
  • Make the executable jar.
In our day to day activity , we faced a problem that we were using jira-rest-java-client-core-5.2.0 with spark-streaming_2.11-2.3.0 , and both of them carries different version of guava

jira-rest-java-client-core-5.2.0(guava-26-jre) and spark-streaming_2.11-2.3.0(guava-14.0.1), In straight way I can't just exclude the any one of them , we need both of them , because guava 26-jre(some of the class and method is removed which was in 14.0.1 version)  is not compatible with guava-14.0.1.

So to over come with problem , only solution left is to keep both guava version and with the help of maven plugin m we will rename all package name com.google.common with shaded.com.google.common inside  jira-rest-java-client-core-5.2.0, this way we will be able to use both of the guava version and it wont conflict with each other.

Following are the example of one project which does 

pom.xml


 <properties>
 <shade.groupId>com.xyz.util</shade.groupId>
 <shade.artifactId>jira-rest-java-client-core-shaded</shade.artifactId>
 <shade.version>5.2.0-SHADED</shade.version>
 <shade.packaging>jar</shade.packaging>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>
 
 <groupId>${shade.groupId}</groupId>
 <artifactId>${shade.artifactId}</artifactId>
 <version>${shade.version}</version>
 <packaging>${shade.packaging}</packaging>
 <name>JiraRestJavaClientCoreShaded</name>
 <url>http://maven.apache.org</url>
 <repositories>
  <repository>
   <id>maven-public</id>
   <url>https://repo.maven.apache.org/maven2/</url>
  </repository>
  <repository>
   <id>atlassian-public</id>
   <url>https://packages.atlassian.com/maven/repository/public</url>
  </repository>
 </repositories>
 <dependencies>
  <dependency>
   <groupId>com.atlassian.jira</groupId>
   <artifactId>jira-rest-java-client-core</artifactId>
   <version>5.2.0</version>
  </dependency>
 </dependencies>
 <build>
 <!-- Below plugin will shade the artifacts guava-26.0-jre which is transitive dependency of jira-rest-java-client-core  -->
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
     <execution>
      <phase>package</phase>
      <goals>
       <goal>shade</goal>
      </goals>
      <configuration>
      
       <!-- <shadedArtifactAttached>true</shadedArtifactAttached> -->
       <shadedClassifierName>shaded</shadedClassifierName>
       
       <relocations>
        <relocation>
         <pattern>com.google.common</pattern>
         <shadedPattern>shaded.com.google.common</shadedPattern>
        </relocation>
       </relocations>
       
       <transformers>
        <transformer
         implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
       </transformers>
       <!-- Exclude below artifacts from the uber jar-->
       <artifactSet>
        <excludes>
         <exclude>org.springframework:*</exclude>
         <exclude>org.apache.commons:*</exclude>
         <exclude>commons-logging:*</exclude>
         <exclude>org.codehaus.jackson:*</exclude>
        </excludes>
       </artifactSet>
      </configuration>
     </execution>
    </executions>
    
    <!-- Below plugin install the artifacts into maven repository so we wont need the scope as system for the above shaded jar  -->
   </plugin>
   
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-install-plugin</artifactId>
     <version>2.5.2</version>
     <executions>
      <execution>
       <id>install-external</id>
       <phase>package</phase>
       <configuration>
        <file>${project.build.directory}/${shade.artifactId}-${shade.version}.jar</file>
        <repositoryLayout>default</repositoryLayout>
        <groupId>${shade.groupId}</groupId>
        <artifactId>${shade.artifactId}</artifactId>
        <version>${shade.version}-JAR</version>
        <packaging>${shade.packaging}</packaging>
        <packaging>jar</packaging>
        <generatePom>true</generatePom>
       </configuration>
       <goals>
        <goal>install-file</goal>
       </goals>
      </execution>
     </executions>
    </plugin>
  </plugins>
 </build>
</project>


The above pom will shade it and if you run maven goal mvn clean install then it will install into local repositories.

Then in you main project you can use this shaded jar as below:

<dependency>
    <groupId>com.smartstreamrdu.libraries</groupId>
    <artifactId>jira-rest-java-client-core-shaded</artifactId>
    <version>5.2.0-SHADED-JAR</version>
    <type>jar</type>
 </dependency>



This way we can keep both the guava version and it will work as expected.

No comments:

Post a Comment

Required details

--------------------------------------------------------------------------------------------------------------------------- C:\Program File...