Maven: exclude dependency from shade plugin - java

I've seen next string after mvn clean install
Including com.sun.jersey.contribs:jersey-multipart:jar:1.5 in the
shaded jar
Problem: I can't make it not shaded even I've added exlusion for maven-shade-plugin (see code below)
My maven-shade-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<artifactSet>
<excludes>
//Here ==> <exclude>com.sun.jersey.contribs:jersey-multipart:jar</exclude>
</excludes>
</artifactSet>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>Main</Main-Class>
<Build-Number>123</Build-Number>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

According to http://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html, your exclusion syntax is wrong:
Artifacts to include/exclude from the final artifact. Artifacts are denoted by composite identifiers of the general form groupId:artifactId:type:classifier. ... For convenience, the syntax groupId is equivalent to groupId:*:*:*, groupId:artifactId is equivalent to groupId:artifactId:*:* and groupId:artifactId:classifier is equivalent to groupId:artifactId:*:classifier.
So either use com.sun.jersey.contribs:jersey-multipart:*:jar or com.sun.jersey.contribs:jersey-multipart for your exclusion.
<artifactSet>
<excludes>
<exclude>com.sun.jersey.contribs:jersey-multipart</exclude>
</excludes>
</artifactSet>

Add scope tag in dependency tag with value as 'provided'. It will exclude that dependency.

For anyone, who made a lot of steps to exclude some transitive artifact from your fat jar and it still presented, there may be two causes:
This dependency is transitive for other dependency, not that one, where you've made exclusion. Thus you need to add exclusion tag somewhere else (if your exclusion is located in <dependencies> section, not plugin-level).
mvn dependency:tree is very useful for these searches.
These dependency classes comes to your jar straight from some dependency artifact as ordinary classes, not transitive dependency.
There is some chance that one of dependencies of your project represents fat jar. Certain classes which you want to exclude comes to your project as ordinary classes, not transitive dependency. Thus Maven unable to exclude it. Also this is a reason that Maven’s provided scope is not working (classes still presented in your jar).
More details here: https://mchesnavsky.tech/maven-dependency-exclusion-not-working/

Related

How to install shaded jar instead of the original jar

I add maven-shaded-plugin into my project and it correctly built the shaded uber jar, but still installed the original thin jar. I'd like to install the shaded uber jar so that downstream projects can depend on this shaded uber jar. How can I do it? Thanks.
Here's my pom file.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${plugin.shade.version}</version>
<configuration>
<shadeTestJar>true</shadeTestJar>
<shadedClassifierName>SHADED</shadedClassifierName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<filters>
<filter>
<artifact>*:*</artifact>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>reference.conf</resource>
</transformer>
</transformers>
<artifactSet>
</artifactSet>
<!--<outputDirectory>${project.build.directory}/../../interpreter/python</outputDirectory>-->
<outputFile>${project.build.directory}/../../interpreter/python/${interpreter.jar.name}-${project.version}.jar</outputFile>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
I'm looking for the same answer. I'm using this workaround for now... Don't specify <outputFile> or <finalName> in the maven shade plugin when attaching the shaded artifact. Maven will then install both jars, using the classifier as the differentiator between the two.
Downstream projects can depend on the shaded jar this way:
<dependency>
<groupId>abc</groupId>
<artifactId>xyz</artifactId>
<version>${project.version}</version>
<classifier>SHADED</classifier>
</dependency>

Including some dependencies in my compiled jar

Hello people of stackoverflow, on my working project I have 5 dependencies.
I'm working on a project which doesn't contain any main method.
What I would like to do is including 2 (HikariCP and slf4j) out of my 5 dependencies in the final jar, but I don't figure how to do this, it's always adding all of them.
Edit: I'm using eclipse
Using Maven
You can use the maven-shade-plugin to generate a fat-jar (or uber-jar). It will package all your dependencies inside the jar:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>YOUR_JAR_FINAL_NAME</finalName>
</configuration>
</plugin>
</plugins>
</build>
Documentation related to the maven-shade-plugin can be found in here
UPDATE: As you want to include just a few dependencies inside of it, you can check the Selecting contents for Uber JAR section:
You can use the include or exclude tag to select which content will be provided to the jar, you can find some examples from the docs below:
Excluding
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
</configuration>
Including and excluding
<configuration>
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>junit/framework/**</include>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
<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>
UPDATE 2: For a runnable jar file, you can follow this section of the documentation related to Executable Jars
In Eclipse
You can use the Package required libraries into generated JAR option, the downside of it is that you can't really select which dependencies do you want to include into to, since it is assessing all the required libs for you project.
I believe if you really want to remove some stuff, you would need to use Maven to package, or remove manually the dependencies you don't like from the generated jar, generating a custom jar with your own hands:

How to Include and Exclude Some of Files From Different Artifacts Using Maven Shaded Plugin

I am trying to create a uber jar using Maven Shaded plugin to do that i have created a Maven profile.I have two dependency projects related to current project.
Project-A Depends on Project-B and Project-C. All of them share same group id. we are using monolith repo structure.Below are projects .pom details
Project-A.pom
<dependency>
<groupId>com.sample.project</groupId>
<artifactId>Project-B</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>com.sample.project</groupId>
<artifactId>Project-C</artifactId>
<version>1.6.0</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/LICENSE</exclude>
<exclude>LICENSE</exclude>
<exclude>*:*</exclude> // exclude all artifacts
<exclude>com.sample.manual:*</exclude> // exclude specific artifact
</excludes>
<includes>
<include>com.sample.project:*</include> //include only com.sample.project related artifacts
</includes>
</artifactSet>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
</transformer>
</transformers>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
My requirement is that i want to exclude all .xml files from dependent projects and only include Xml files from current project.To do that i have used following filters but i can not achieve it.
<exclude>com.sample.project:*.xml</exclude>
<include>com.sample.project:{project.artifactId}:*.xml</include>
Please let me know how to do it.

Build lucene from sources: Codec does not exist

I've imported Lucene sources and built successfully.
But when I'm trying to use any of Lucene classes, I get
A SPI class of type org.apache.lucene.codecs.Codec with name 'Lucene410' does not exist
The current classpath supports the following names: []
I tried to get path to classes by
String path = Lucene410Codec.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
And got right path, so there is no problem with wrong jar-file.
The problem was that I've missed META-INF folder while imported project.
I've manually added META-INF/services folder and it's contents - codecs files (which I took from lucene.core.jar) to sources and configured right build path.
add something to resources in eclipse
Now I can work with Lucene.
For the ones who is facing such issue I have another solution which seems decent. Main reason for such issue to occur is that some JAR files (Lucene in this case) providing implementations of some interfaces ship with 'META-DATA/service' directory. This directory then maps interfaces to their implementation classes for lookup by the service locator. So the solution will be to relocate the class names of these implementation classes and merge multiple implementations of the same interface into one service entry.
Maven's shade plugin provides a resource transformer called ServiceResourceTransformer which does such relocation. So in practice I would define the plugin as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>main.class.of.your.app.MainClass</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

configure Maven Shade minimizeJar to include class files

I am trying to minimize the UberJar's size by using Maven Shade Plugin's minimizeJar. It looks like minimizeJar only includes classes that are statically imported in the code (I suspect this because I see LogFactory.class in uber jar at org\apache\commons\logging\ but no classes of the impl package are included, hence throwing java.lang.ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl when I run the uber-jar).
Is there any way I can tell Maven's Shade plugin to include specified packages into the final jar no matter what the minimizeJar suggests?
Here the pom snippet of what I am trying:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>commons-logging:commons-logging</artifact>
<includes>
<include>org/apache/commons/logging/**</include>
</includes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.myproject.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
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>
I am using the 2.0 version of the Maven Shade Plugin and still I am not able to include classes after "minimizing" the JAR.
As a workaround the only thing that comes to my mind is to create references to the needed classes to avoid the minimization code to get rid of them. ie:
/*
* This block prevents the Maven Shade plugin to remove the specified classes
*/
static {
#SuppressWarnings ("unused") Class<?>[] classes = new Class<?>[] {
JButton.class,
JMenu.class,
JMenuBar.class,
JMenuItem.class
};
}
I hope Maven developers implement a way to handle this situation (which I guess is very common).

Categories