How to use shade plugin relocation with 3rdparty dependency injection - maven-shade-plugin

Can shade plugin modify resource and byte code such that dependency injection will us relocated packages? I don't think it does.
I shaded and relocated javax.transaction.TransactionManager to org.me.shaded.javax... and my code that use it appears to function but a org.infinispan:infinispan-core attempts dependency injection using the original package name, fails to locate TransactionManager and throws this error:
Caused by: java.lang.NoSuchMethodException: java.lang.Object.injectDependencies(..., javax.transaction.TransactionManager, ...)
When I look in my uber jar I find infinispan-core-component-metadata.dat when contains strings referencing the javax and not the shaded package.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<minimizeJar>false</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope>
<shadedArtifactAttached>true</shadedArtifactAttached>
<relocations>
<relocation>
<pattern>javax.transaction</pattern>
<shadedPattern>org.me.shaded.javax.transaction</shadedPattern>
</relocation>
</relocations>
<artifactSet>
<excludes>
<exclude>org.apache.hbase:*</exclude>
<exclude>org.apache.ant:*</exclude>
<exclude>org.eclipse.jetty:*</exclude>
<exclude>org.springframework:*</exclude>
<exclude>geronimo-spec</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<excludes>
<exclude>webapps/**</exclude>
</excludes>
</filter>
<filter>
<artifact>org.infinispan:infinispan-core</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
<filter>
<artifact>org.jboss.spec.javax.transaction:jboss-transaction-api_1.1_spec</artifact>
<excludes>
<exclude>javax/transaction/**</exclude>
</excludes>
</filter>
<filter>
<artifact>javax.transaction:jta</artifact>
<includes>
<include>javax/transaction/**</include>
</includes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>

Related

maven-generated uberjar doesn't contain dependency classes

I'm running maven 3.6.0 on ubuntu 18.04.
My application’s pom.xml includes this dependency; the associated "neptus" jar is in my local .m2/repository:
<dependencies>
<dependency>
<groupId>pt.lsts.neptus</groupId>
<artifactId>neptus</artifactId>
<version>x.x</version>
</dependency>
My application actually does reference classes from the “neptus” jar file, so I want to include those classes in my project’s uberjar. Therefore the pom.xml also includes this, adapted from http://maven.apache.org/plugins/maven-shade-plugin/examples/includes-excludes.html
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/runners/**</exclude>
</excludes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Yet the uberjar generated by 'mvn clean package' doesn’t contain any class files from the neptus artifact, and so my app throws java.lang.NoClassDefFoundError for those missing classes.
What am I doing wrong?
Thanks!
The maven-shade-plugin is ignored by default if that plugin is enclosed within a pluginManagement block, as it is in my case (sorry, not shown in my original post). The shade plugin does get executed if I do this:
% mvn package shade:shade
as described in this thread.

Oozie loading jars provided by user first

I have tried oozie.launcher.mapreduce.job.user.classpath.first property in workflow.xml to load my jars first over sharelib jars.
Unable to run workflow when this property is used.
hadoop-hdfs is available in the provided jar and version is not incompatible
Maven relocation strategy can be used to avoid conflicting classes
http://maven.apache.org/plugins/maven-shade-plugin/examples/class-relocation.html
Posting pom.xml shaded plugin config which worked for me
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.apache.http</pattern>
<shadedPattern>shaded.org.apache.http</shadedPattern>
</relocation>
</relocations>
<shadedArtifactAttached>true</shadedArtifactAttached>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

Exclude specific files from all dependencies in pom

I want to exclude pdf files from all the dependencies. When I use filter property and specify the folder name for a pariticular dependency as below it works.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>com.test:myexample</artifact>
<excludes>
<exclude>TESTCASES/VFX/**/**/**/*.pdf</exclude>
<exclude>Test/**/*.pdf</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.test.CLI</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
However it does'nt work, when I used the configuration below. Reference link: https://maven.apache.org/plugins/maven-jar-plugin/examples/include-exclude.html
Do I need to follow any specific fileset pattern?
<configuration>
<excludes>
<exclude>**/*.pdf</exclude>
</excludes>
</configuration>
After adding the filter property as below it works.
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>**/*.pdf</exclude>
</excludes>
</filter>
</filters>

How to build a jar from a module of maven with dependencies from other module?

I have some modules in maven, and I want to build a jar of a module which has a dependency of just other module.
How can I include in the jar both modules?
Edit:
I have the followings modules:
myproject-core/
myproject-api/
myproject-dependencie/
myproject-api-web/
And I want to build a jar in myproject-api with myproject-dependencie. I have more dependencies in myproject-api and I only need to have in this jar myproject-api and myproject-dependencie.
Thanks!
I guess the maven-shade-plugin will be your friend:
https://maven.apache.org/plugins/maven-shade-plugin/
In you plugins section Something like:
...
<properties>
<shade-main-class>{your-main-class}</shade-main-class>
</properties>
...
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<includes>
<include>com/yourcompany/**</include>
</includes>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${shade-main-class}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
...

Filter resources maven-shade-plugin

I am trying to filter the resources included in my jar. I'm using shade-maven-plugin and this one is adding all the resources of all my dependencies into my generated jar, I only want to be included my project resources.
Here is my pom definition:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>es.app.applet.MyApplet</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>
I tried to add the next filter to remove all the resources, and then add another filter adding only my artifactID resources, but it doesn't work.
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>resources/*.*</exclude>
</excludes>
</filter> <filter>
<artifact>my.groupId:my.artifactId</artifact>
<includes>
<include>resources/*.*</include>
</includes>
</filter>
Ideas?
Thanks.
This is because filter includes happen before filter excludes.
With your code you are including you "my.groupId:my.artifactId" -> resources/.
But aterwards you are excluding all "resources/."
From the original documentation :
From a logical perspective, includes are processed before excludes,
thus it's possible to use an include to collect a set of files from
the archive then use excludes to further reduce the set.

Resources