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>
Related
I am using JaCoCo code coverage, but the report is including classes from jar, lib. (Offline Instrumentation, Maven)
I solved the problem with the offline configuration since "aspectj-maven-plugin" was changing the class files, and also now I successfully exclude the packages outside of target/classes -> src. thanks to this answer in stackoverflow.
But now I am getting the classes from jar, lib inside the report and I have not idea how to exclude then. I Show my configuration and examples below
I also tried this solution Exclude classes of jar files from jacoco coverage report But it doesn't work for me.
<exclude>**/lib/*</exclude>
My jacoco offline configuration:
<properties>
<jacoco.version>0.8.4</jacoco.version>
<argLine></argLine>
</properties>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<version>${jacoco.version}</version>
</dependency>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>instrument</goal>
<goal>restore-instrumented-classes</goal>
<goal>report</goal>
</goals>
<configuration>
<!-- this configuration affects all goals -->
<excludes>
<exclude>*</exclude>
<exclude>com/company/rrPackage/**/*.class</exclude>
<exclude>org/**/*.class</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
surefire-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.15</version>
<configuration>
<testNGArtifactName>...</testNGArtifactName>
<suiteXmlFiles>
<suiteXmlFile>...</suiteXmlFile>
</suiteXmlFiles>
<skip>${skip.test}</skip>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
<properties>
...
</properties>
</configuration>
</plugin>
And the reason what I think that I am getting classes from jar inside de jacoco:report. In my pom.xml I have the following dependencies:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.2.9</version>
</dependency>
Also I have a couple of import in my classes like this
import org.hsqldb.lib.StringUtil;
for example:
This has no dependency on the pom.xml but is used in one of the project classes, and jacoco shows it in the report
import javax.mail.internet.AddressException;
I have other cases with the same behavior that result in the same problem: Jacoco show those classes from jar in the report, as shown in the images
Try includes instead of excludes. Notice that you need .class at the end.
try something like that:
<configuration>
<includes>
<include>com/company/package/**/*.class</include>
</includes>
</configuration>
Base on your example:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>instrument</goal>
<goal>restore-instrumented-classes</goal>
<goal>report</goal>
</goals>
<configuration>
<!-- this configuration affects all goals -->
<includes>
<include>com/company/packageToInclude/**/*.class</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
I don't know how you generate lib directory, because you don't provide complete example.
However in case of the following example
src/main/java/Example.java
class Example {
}
src/test/java/ExampleTest.java
public class ExampleTest {
#org.junit.Test
public void test() {
new Example();
}
}
and pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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>org.example</groupId>
<artifactId>example</artifactId>
<version>0.1-SNAPSHOT</version>
<properties>
<jacoco.version>0.8.4</jacoco.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<version>${jacoco.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>test-compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>junit</includeArtifactIds>
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>instrument</goal>
<goal>restore-instrumented-classes</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
execution of mvn clean verify produces
$ ls -R target/classes
target/classes:
Example.class lib
target/classes/lib:
junit-4.12.jar
and following report
And after addition of following <configuration>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<goals>
<goal>instrument</goal>
<goal>restore-instrumented-classes</goal>
<goal>report</goal>
</goals>
<configuration>
<excludes>
<exclude>lib/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
execution of the same command mvn clean verify produces following report
If the above doesn't help, then please provide absolutely complete example allowing everybody else to reproduce exactly the same what you do.
Is it still possible to download JRE from maven as a zip file, so that one can include it in the packaged product? I found this code, which doesn't work anymore:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.oracle</groupId>
<artifactId>jre</artifactId>
<version>1.8.141</version>
<type>zip</type>
<classifier>windows-i586</classifier>
<outputDirectory>${basedir}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
UPDATE: Looks like such thing could only work after uploading the zip file to the own maven repo...
Change the version 1.8.141 to 1.8.0_131. The latest maven has this one only:
<!-- https://mvnrepository.com/artifact/com.oracle.java/jre -->
<dependency>
<groupId>com.oracle.java</groupId>
<artifactId>jre</artifactId>
<version>1.8.0_131</version>
</dependency>
EDIT :As per the comments from OP
This example here is for a dependency. What I need is a maven goal to
copy unzipped JRE to a folder. And actually I do need a specific JRE
version. So currently, the solution is to install the JRE zip file in
my maven repo and unpack it with maven goal.
Copying and unzipping the jre artifact to another location may be achieved by Maven Dependency Plugin
<project>
[...]
<dependencies>
<dependency>
<groupId>com.oracle.java</groupId>
<artifactId>jre</artifactId>
<version>1.8.0_131</version>
</dependency>
</dependencies>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>validate</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.oracle.java</groupId>
<artifactId>jre</artifactId>
<type>zip</type>
<outputDirectory>/path/to/alternateLocation</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
In my POM.xml, I have used maven-shade plugin and relocated the httpClient dependency. But when I print the dependency tree using mvn dependency:tree, I still see the httpClient library in the tree as shown below. Why is this happening. Any help will be appreciated.
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.3.5:provided
My POM.xml is as below.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>parser</artifactId>
<packaging>jar</packaging>
<!-- change these to the appropriate values -->
<name>Parser Apps</name>
<description>Applications to showcase different parsers</description>
<properties>
<!-- change this if you desire to use a different version of Apex Core -->
<apex.version>3.4.0</apex.version>
<apex.apppackage.classpath>lib/*.jar</apex.apppackage.classpath>
<malhar.version>3.4.0</malhar.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<encoding>UTF-8</encoding>
<source>1.7</source>
<target>1.7</target>
<debug>true</debug>
<optimize>false</optimize>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/deps</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</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>
<artifactSet>
<includes>
<include>org.apache.httpcomponents.*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.apache.httpcomponents</pattern>
<shadedPattern>org.shaded.httpcomponents</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>app-package-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-${project.version}-apexapp</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/assemble/appPackage.xml</descriptor>
</descriptors>
<archiverConfig>
<defaultDirectoryMode>0755</defaultDirectoryMode>
</archiverConfig>
<archive>
<manifestEntries>
<Class-Path>${apex.apppackage.classpath}</Class-Path>
<DT-Engine-Version>${apex.version}</DT-Engine-Version>
<DT-App-Package-Group-Id>${project.groupId}</DT-App-Package-Group-Id>
<DT-App-Package-Name>${project.artifactId}</DT-App-Package-Name>
<DT-App-Package-Version>${project.version}</DT-App-Package-Version>
<DT-App-Package-Display-Name>${project.name}</DT-App-Package-Display-Name>
<DT-App-Package-Description>${project.description}</DT-App-Package-Description>
</manifestEntries>
</archive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<move file="${project.build.directory}/${project.artifactId}-${project.version}-apexapp.jar"
tofile="${project.build.directory}/${project.artifactId}-${project.version}.apa" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<!-- create resource directory for xml javadoc-->
<id>createJavadocDirectory</id>
<phase>generate-resources</phase>
<configuration>
<tasks>
<delete dir="${project.build.directory}/generated-resources/xml-javadoc"/>
<mkdir dir="${project.build.directory}/generated-resources/xml-javadoc"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/${project.artifactId}-${project.version}.apa</file>
<type>apa</type>
</artifact>
</artifacts>
<skipAttach>false</skipAttach>
</configuration>
</execution>
</executions>
</plugin>
<!-- generate javdoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<!-- generate xml javadoc -->
<execution>
<id>xml-doclet</id>
<phase>generate-resources</phase>
<goals>
<goal>javadoc</goal>
</goals>
<configuration>
<doclet>com.github.markusbernhardt.xmldoclet.XmlDoclet</doclet>
<additionalparam>-d ${project.build.directory}/generated-resources/xml-javadoc -filename ${project.artifactId}-${project.version}-javadoc.xml</additionalparam>
<useStandardDocletOptions>false</useStandardDocletOptions>
<docletArtifact>
<groupId>com.github.markusbernhardt</groupId>
<artifactId>xml-doclet</artifactId>
<version>1.0.4</version>
</docletArtifact>
</configuration>
</execution>
</executions>
</plugin>
<!-- Transform xml javadoc to stripped down version containing only class/interface comments and tags-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>transform-xmljavadoc</id>
<phase>generate-resources</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/generated-resources/xml-javadoc</dir>
<includes>
<include>${pmalhar.versioroject.artifactId}-${project.version}-javadoc.xml</include>
</includes>
<stylesheet>XmlJavadocCommentsExtractor.xsl</stylesheet>
<outputDir>${project.build.directory}/generated-resources/xml-javadoc</outputDir>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<!-- copy xml javadoc to class jar -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/generated-resources/xml-javadoc</directory>
<includes>
<include>${project.artifactId}-${project.version}-javadoc.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- add your dependencies here -->
<dependency>
<groupId>org.apache.apex</groupId>
<artifactId>malhar-library</artifactId>
<version>${malhar.version}</version>
<!--
If you know that your application does not need transitive dependencies pulled in by malhar-library,
uncomment the following to reduce the size of your app package.
-->
<!--
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
-->
</dependency>
<dependency>
<groupId>org.apache.apex</groupId>
<artifactId>malhar-contrib</artifactId>
<version>${malhar.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.0.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.sf.supercsv</groupId>
<artifactId>super-csv</artifactId>
<version>2.4.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.apex</groupId>
<artifactId>apex-common</artifactId>
<version>${apex.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.apex</groupId>
<artifactId>apex-engine</artifactId>
<version>${apex.version}</version>
<scope>provided</scope>
</dependency>
Two things -
You should be aware what relocation does is not "...relocated the httpClient dependency" but as the source suggests -
If the uber JAR is reused as a dependency of some other project,
directly including classes from the artifact's dependencies in the
uber JAR can cause class loading conflicts due to duplicate classes on
the class path. To address this issue, one can relocate the classes
which get included in the shaded artifact in order to create a private
copy of their bytecode
When you execute the mvn dependency:tree it would display all the dependencies(direct and transitive) included in your project. Instead, the maven shade plugin
shade:shade is bound to the package phase and is used to create a
shaded jar.
renaming or optimizing the dependencies further. Here goes the details for Maven Shade Plugin -
This plugin provides the capability to package the artifact in an
uber-jar, including its dependencies and to shade - i.e. rename - the
packages of some of the dependencies.
The dependency is not removed from original POM, so the behavior of dependency:tree is correct.
Shade plugin will also generate a new POM (dependency-reduced-pom.xml) wherein shaded dependencies are removed from the <dependencies> section. This looks like the one you are after.
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 have a custom plugin that is defined using the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>pram.plugintest</groupId>
<artifactId>pram.plugintest</artifactId>
<packaging>maven-plugin</packaging>
<version>1.1-SNAPSHOT</version>
<name>pram.plugintest Maven Mojo</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.3</version>
<configuration>
<goalPrefix>blah</goalPrefix>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Running
mvn blah:touch
Creates a text file in the target directory as expected. I now create a lifecycles.xml file in the resources directory specified in the pom
<lifecycles>
<lifecycle>
<id>touch</id>
<phases>
<phase>
<id>package</id>
<executions>
<execution>
<goals>
<goal>touch</goal>
</goals>
</execution>
</executions>
</phase>
</phases>
</lifecycle>
</lifecycles>
In another maven project, I would like to bind the running of mvn blah:touch to an execution task similar to this
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>test1</id>
<phase>blah:touch</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>mainClass=org.sonatype.mavenbook.weather.Main</mainClass>
</configuration>
</execution>
</executions>
</plugin>
...
However running this creates the text file but doesn't attempt to run org.sonatype.mavenbook.weather.Main
Is this the correct approach?
Ultimately what I would like is to have multiple execution sections in the exec-maven-plugin that are not bound to the default phases. Logically it would look like this
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>test1</id>
<phase>blah:touch</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>mainClass=org.sonatype.mavenbook.weather.Main</mainClass>
</configuration>
</execution>
<execution>
<id>test2</id>
<phase>blah:touch2</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>mainClass=org.sonatype.mavenbook.weather.SomeOtherClass</mainClass>
</configuration>
</execution>
</executions>
</plugin>
...
So if I run mvn blah:touch then org.sonatype.mavenbook.weather.Main will be executed and if I run mvn blah:touch2 then org.sonatype.mavenbook.weather.SomeOtherClass will be executed instead.
It seems like it should be straightforward to do but there's nothing in the documentation that seems to point out how to do this.
You can not use the exec-maven-plugin for this and you do not need the lifecycle.xml if you only would like to execute your plugin during a build.
To execute your plugin during a specific Maven phase, you simply have to add
<plugins>
<plugin>
<groupId>your.group.id</groupId>
<artifactId>your.artifact.id</artifactId>
<executions>
<execution>
<id>unique-execution-id</id>
<goals>
<goal>the.goal.of.your.plugin</goal>
</goals>
<phase>maven.phase</phase>
<configuration>
....
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Please specify the goal in the goal element without the prefix.
Did you read http://www.sonatype.com/books/mvnref-book/reference/writing-plugins-sect-plugins-lifecycle.html?