The classes added to exclude in maven shade plugin don't get excluded.
My pom.xml has one dependency which has shaded classes conflicting with other dependencies.
So I added the path to those classes in maven shade plugin to exclude them.
I have this for maven shade plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</dependency>
</dependencies>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<excludes>
<exclude>io.confluent.shaded.kafka.serializers.subject.*</exclude>
<exclude>io/confluent/shaded/kafka/serializers/subject/*</exclude>
</excludes>
</filter>
</filters>
<mainClass>com.expediagroup.das.businessevent.CommerceBusinessBookingEventMetricCalculatorApp</mainClass>
<layout>JAR</layout>
</configuration>
</execution>
</executions>
</plugin>
After compiling it still shows those classes not being removed.
Any help is appreciated.
Related
I'm using Maven 3.6.2 with a multi-module Java project. The example module depends on the core module, so I have a dependency in the example module's POM like this:
<dependency>
<groupId>com.company</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
The issue is that not all of the classes from the core module are being packaged into the example jar when I run mvn clean install. Only the classes that are used in the example project are being packaged. I need all classes packaged for a later process.
I'm using the maven-shade-plugin with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>module-info.class</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</execution>
</executions>
</plugin>
How can I include all classes from the core module in the example jar without having to use them in the example jar?
The issue was the minimizeJar parameter. According to https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html#minimizeJar:
When true, dependencies will be stripped down on the class level to
only the transitive hull required for the artifact.
I removed that parameter and it worked as expected.
I have a maven project which I have say spring framework libraries as dependencies, I want to copy spring framework dependencies with there transitive dependencies to a location specified.
I have gone through maven dependency plugin guides at apache, I have several options where non of them will solve the complete problem.
copy dependencies option
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
This will copy all the dependencies and there transitives to a given location, I want only spring dependencies and there transitives.
copying specific artifacts
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.4.RELEASE</version>
<type>jar</type>
<overWrite>false</overWrite> <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
This is not coping the transitive dependencies.
Any solution which solve my both problems.
This is possible with the assembly plugin.
Plugin configuration:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
<finalName>plugins</finalName> <!--folder name in target directory-->
</configuration>
<executions>
<execution>
<id>some-id</id> <!-- must match assembly id in assembly.xml-->
<phase>pre-integration-test</phase> <!-- pic -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assembly.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>some-id</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes>
<include>
org.springframework:spring-web
</include>
</includes>
<useTransitiveDependencies>true</useTransitiveDependencies>
<useTransitiveFiltering>true</useTransitiveFiltering>
</dependencySet>
</dependencySets>
</assembly>
The important bits are <useTransitiveDependencies>true</useTransitiveDependencies> and <useTransitiveFiltering>true</useTransitiveFiltering>, which cause the include to be applied to project dependencies, but not to transitive dependencies, resulting in spring-web artifact and it's dependencies to be copied to the directory.
You can use the maven assembly plugin for this.
Check it out and specifically the dependency set:
http://maven.apache.org/plugins/maven-assembly-plugin/
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_dependencySet
You can provide an output directory and you can specify which dependencies to put in there
There is also an option: useTransitiveDependencies. Set this to true to get the behaviour you want.
Here's an option:
create module (producer) to collect dependencies and publish them as a zip.
in consumer user depencency:unpack to unpack that zip
It is cumbersome and the exclusions still need some cherry picking, but much less and it could be run in parallel threads.
Producer
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>packaging</groupId>
<artifactId>jdbcdrivers</artifactId>
<packaging>zip</packaging>
<name>jdbcdrivers</name>
<dependencies>
<!-- set up deps for capture and limit their impact on anything which depends upon this module via optional-false -->
<dependency>
<groupId>net.sf.jtds</groupId>
<artifactId>jtds</artifactId>
<scope>test</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<scope>test</scope>
<optional>false</optional>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
<optional>false</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>dist profile: hive jdbc driver ${baseName}</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}/lib/addons/jdbcdriver/</outputDirectory>
<useBaseVersion>true</useBaseVersion>
<excludeTransitive>false</excludeTransitive>
<overWriteIfNewer>true</overWriteIfNewer>
<includeScope>test</includeScope>
<excludeScope>provided</excludeScope>
<excludeGroupIds>org.codehaus.groovy,org.apache.ivy,jdk.tools</excludeGroupIds> <!-- you might need to cherry pick excludes if scope doesn't worjk -->
<prependGroupId>true</prependGroupId>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I am trying to create a deploy-able jar which using Apache's commons-lang3. However my AWS cluster where my Hadoop is does not contain this library so I get a classNotFoundException. I figured I needed to manually add that dependency in but I am having issues working with the maven shade plugin (I was recommended to use this) My current pom file looks like this :
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.12.0-cdh5.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<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>
<artifact>org.apache.commons:commons-lang3</artifact>
<includes>
<include>org/apache/commons/commons-lang3/3.4/*</include>
</includes>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
I want a completely normal jar with the addition of the commons-lang3 library embedded inside. Is there something I am doing incorrectly?
To include whitelisted jars you need to do the following:
<build>
<plugins>
<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>
<artifactSet>
<includes>
<include>org.apache.commons:commons-lang3</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I am building a multimodule project with Maven where one module represents the shaded version of the other module:
parent
|- base
|- base-shaded
The base module contains all my source files but with dependencies I want to import into my own namespace. This shaded module is described by my base-shaded module which basically only contains a POM which configures a dependency on base and the Maven Shade plugin.
This works fine. The Shade plugin includes all the dependencies and creates a shaded artifact, including a source artifact. However, I am missing a javadoc artifact which is not created by the Shade plugin. Therefore, I attempted to copy the base module's javadoc artifact. However, the release:release goal ignores these artifacts which prevents me to deploying to Maven Central. Still, I managed to include copy these files and include them in install target.
Is there a canonical way of including a non-assembled file in a build? I start to think that I might be the wrong approach.
Here is the plugin configuration of my base-shaded POM. Sorry that it is so much, but in the end, it is Maven XML:
<!-- Shade dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${version.plugin.shade}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<dependencyReducedPomLocation>
${project.build.directory}/dependency-reduced-pom.xml
</dependencyReducedPomLocation>
<createSourcesJar>true</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent>
<relocations>
<relocation>
<pattern>${shade.source}</pattern>
<shadedPattern>${shade.target}</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<!-- Copy dependency version's javadoc artifacts -->
<plugin>
<groupId>com.github.goldin</groupId>
<artifactId>copy-maven-plugin</artifactId>
<version>${version.plugin.copy}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<resources>
<resource>
<targetPath>${project.build.directory}</targetPath>
<file>
${project.basedir}/../base/target/base-${project.version}-javadoc.jar
</file>
<destFileName>base-${project.version}-javadoc.jar</destFileName>
</resource>
<resource>
<targetPath>${project.build.directory}</targetPath>
<file>
${project.basedir}/../base/target/base-${project.version}-javadoc.jar.asc
</file>
<destFileName>base-shaded-${project.version}-javadoc.jar.asc</destFileName>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Because the javadoc files are copied manually, they must be installed manually as well -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-javadoc</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<packaging>jar</packaging>
<classifier>javadoc</classifier>
<file>${build.directory}/base-shaded-${project.version}-javadoc.jar</file>
</configuration>
</execution>
<execution>
<id>install-javadoc-asc</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<packaging>jar.asc</packaging>
<classifier>javadoc</classifier>
<file>${build.directory}/base-shaded-${project.version}-javadoc.jar.asc</file>
</configuration>
</execution>
</executions>
</plugin>
Of course, there is a plugin for this task, the build-helper-maven-plugin.
We use something like the following to attach the javadoc produced by the unshaded module into the shaded module
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>../unshaded-module/target/unshaded-module-${project.version}-javadoc.jar</file>
<type>jar</type>
<classifier>javadoc</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
I have a multi-module project which I assemble with the assembly plugin to a fat jar. Thank works fine so far, but now I want to build another jar that only consists of special packages of the dependencies of the uber-pom.
An example:
I have 3 deps on sub-projects and I want to have a jar with
com.mycompany.api.*,
com.mycompany.settings.*
com.mycompany.public.*
but not
com.mycompany.internal.*
These packages are distributed through the 3 deps.
Any chance to realize something like that with the assembly plugin?
Thanks,
Jan
The Shade plugin should probably be able to do something like that.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<includes>
<include>com/mycompany/api/*</include>
<include>com/mycompany/settings/*</include>
<include>com/mycompany/public/*</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>