Maven Shade : include only specific artifacts and exclude all the rest - java

I am trying to achieve a very simple thing : Only include some artifacts in my build, while excluding everything else. I do not want to specify both include and excludes.
(Actually my problem with Maven Shade goes deeper than syntax, it is also about its logic, that puzzles me : I find the double paradigm (Inclusion + Exclusion) confusing because to me both are linked.)
I have been scratching my head for hours about this.
Although a few examples are provided here in the doc, I failed to find a working syntax in my case (I keep on getting everything included whatever I tried).
(I find the documentation pretty light IMHO and I can't find a thorough comprehensive reference for this plugin.)
I am sure there is a way to achieve this.
<filters>
<filter>
<artifact>**:**</artifact>
<includes>
<include>org/apache/logging/**</include>
</includes>
<excludes>
<exclude>all/the/rest/**</exclude>
</excludes>
</filter>
</filters>
also :
what is this /path/to/artifact syntax ? Does org/apache/logging refer to artifact org.apache.logging or am I mistaken.

I used the following approach as suggested in a comment :
<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>
#here comes the interesting part
<artifactSet>
<includes>
<include>org.apache.logging.log4j:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>

Could you please try this, it will include all the classes from org.apache.maven package
Sample ex:-
<profiles>
<profile>
<id>TestShadeProfile</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.apache.maven:*
</include>
</includes>
<excludes>
<exclude>*:maven-core</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
hope it will help you

Related

Maven assembly plugin is not including the project packages [duplicate]

This question already has answers here:
Building a fat jar using maven
(7 answers)
Closed 1 year ago.
I'm trying to build a fat jar with maven assembly plugin for distributing a desktop application.
My POM looks like
<build>
<!-- To parse properties files under resources folder : -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.acme.qpguard.editor.Application</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The command mvn assembly: single is creating a fat jar with other dependencies, but fat jar does no include my classes.
So while starting the jar, I'm getting an error
Error: Could not find or load main class com.acme.qpguard.editor.Application
How can I fix my POM so that it includes my project files too
Please note that the project is running fine in Eclipse.
Thanks, #Mayur and #Randy Casburn. Your pointers definitely helped me in finding a fix using maven shaded plugin.
I'm posting the fix as someone may find this useful at a later point of time
<build>
<!-- To parse properties files under resources folder : -->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<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>com.acme.qpguard.editor.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Note: I have to apply a filter for removing signature files from some jars as it was breaking the execution.

Creating runnable/uber jar with maven from project mixed with Java and Kotlin

I have a Java project that I use maven for dependency resolution and building the self-contained, runnable/uber jar (via maven-shade-plugin currently) and I'd like to start playing around with mixing Kotlin into the projects for some new features.
Is using maven to create a runnable/uber jar comprised of Java (primarily) and Kotlin something that is relatively simple to do, and/or supported? Or am I looking at a hack job of gluing together a bunch of stuff that might work if done right? Kotlin isn't a requirement, but since it's supposed to be able to mix freely with Java, it's something I've been wanting to try out on this project. Really trying to gauge if it's a can of worms, or no big deal (and if it's nbd, best direction to look into?)
Here is the build section of my pom.xml so you can see how I'm creating it currently
<build>
<finalName>my-server</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<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>
<!-- exclude signatures -->
<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.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>com.mycompany.myproject.mymainclass</Main-Class>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Anyone have experience doing something like this? Simple? or just stay away?

Maven Get Specific Classes

Is there a way that I can get maven to only include specific .class files when importing dependencies into uber jar (shade). I'm looking for a way to get files that contain "Client" in their name to be pulled out of the dependency jars and added to the final jar. Any help would be wonderful.
You should be able to use the maven-dependency-plugin like this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId><!--dependency groupId--></groupId>
<artifactId><!--dependency artifactId--></artifactId>
<version><!--depedency version--></version>
<includes>**/*Client*.java</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you are using the Maven Shade Plugin, you can a filter, which will allow you to filter which artifacts get shaded, but as well as which classes to exclude or include.
Here's the example they provide:
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
</excludes>
</filter>
</filters>

Maven package resources with classes

I'm generating a War file with Maven and publishing the classes jar as well:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
Is it also possible to publish the resources from the war in the classes jar?
My advice would be to put these resources in their own separate jar module and then have the war use them as a dependency. That way the war and any other project could refer to the resources as if it was any other dependency.
But if you don't want to do that or you can't, I think you'll have to use a classifier. As I said, this isn't ideal. Here's a detailed tutorial on how to do it:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>only-library</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<classifier>only-library</classifier>
<excludes>
<exclude>**/Main*</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>everything</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<classifier>everything</classifier>
<includes>
<include>**/*</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Create an artifact overlay

I would like to overlay another person's project, using customizations of specific files (ie one file would use a different controller, or display something in one way, or have different processes). We have been using an overlay that takes all of the files I have in my repository, and overlaying all of the files on top of their files so that my smaller set of customizations still act like the larger project should. We have accomplished it like this so far, but it plays havoc on the IDE. Is there a better way? I tried using maven-builder-helper-plugin but it gave me duplicate classes on the java files I had overriden.
<build>
<sourceDirectory>target/overlay</sourceDirectory>
<resources>
<resource>
<directory>target/overlay</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<copy todir="target/overlay" overwrite="true">
<fileset dir="src/main/java">
</fileset>
<fileset dir="src/main/resources">
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sample.service</groupId>
<artifactId>sampleService</artifactId>
<classifier>sources</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>target/overlay</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I should note that I'm absolutely fine with using a different direction than this one. I just couldn't figure out a better way to include all of the resource & source files that are needed from them to keep the project running properly. This is for a module that is a part of a web app. The module that is being built and the module it is overlaying are both jar's
We do this using the maven war overlay feature (read about it here). To do this we simply have a dependency from our web client module onto a war type <type>war</type>, and override what we need to in our module. Maven will take the contents of the dependent war and use its files to provide content for our web client, but if there is a clash on filename it'll take the file from our web client, not from the dependent jar. It's as if it takes the dependent jar and overlays our client on top of it to produce a new war. We do this very simply, without any need for ant run -- in years of using maven I have never had to resort to antrun (I consider it an antipattern).
You mention in the comments that you have a separate problem dealing with some xml files. This can be handled by the resource plugin, if you tell it which directory your files are in, and give it a wildcard to define the files you need copying.
So, I figured out a solution that allows me overlay the artifact without messing around with the source directory. Instead of slapping all of the files I want to overlay on top of the artifact files, I realized a simpler way would be to expand the artifact, remove the duplicate classes/resources, and use it as an additional source. I created my own plugin that takes as many 'source' directories as I want and it filters them in the order loaded.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sample.service</groupId>
<artifactId>sampleService</artifactId>
<classifier>sources</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${additional-source-folder}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>mn-stateadvantage</groupId>
<artifactId>duplicateSourceRemover-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>removeDuplicates</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<sourceDirectories>
<param>src/main</param>
<param>${additional-source-folder}</param>
</sourceDirectories>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-resources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${additional-source-folder}</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${additional-source-folder}</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Categories