Shade Plugin Harcording Dependency For Excluded Artifact also - maven

I have the following shade plugin config :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createSourcesJar>false</createSourcesJar>
<keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
<promoteTransitiveDependencies>true</promoteTransitiveDependencies>
<artifactSet>
<includes>
<include>XXXX:AAAA-common</include
</includes>
<excludes>
<exclude>XXXX:client</exclude>
</excludes>
</artifactSet>
<finalName>${project.artifactId}-${project.version}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I see that the XXXX:client is being excluded from the maven dependency, but in that pom that gets generated, I see that the dependency is getting hard coded with the version
<dependency>
<groupId>XXXX</groupId>
<artifactId>client</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
Is there a way we can remove the dependency entirely, or just remove the hardcoded version ?

On further analysis, I found that their is no way we can remove the hardcoded version. An alternative which you can try is maven-assembly plugin but it provides very little flexibility.

Related

Inconsistent behaviour between maven-surefire and tycho-surefire, with jacoco not generating reports

I'm working on creating a pom for a project and adding test cases to it. The project is an eclipse plugin.
Compiling the project with tycho works just fine, the only problem is during testing:
If I run both maven-surefire-plugin tests and tycho-surefire-plugin-tests, the former performs all the tests as expected, while the latter gives the following error:
Execution test of goal org.eclipse.tycho:tycho-surefire-plugin:1.7.0:test failed: Tycho build extension not configured for MavenProject
I would be perfectly fine to just add <skipTests>true</skipTests> to the tycho-surefire-plugin while keeping maven-surefire-plugin on; the problem is even that way, jacoco refuses to create the coverage site, with the following (non error) message:
Skipping JaCoCo execution due to missing execution data file.
I tried to look for solutions of both, but any combination of the solutions I found doesn't lead me to having a working coverage site.
Maven really makes me quite confused, especially with tycho around, so I'd apreciate any explanation on top of the actual fix.
Here is my pom:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroupid</groupId>
<artifactId>myartifactid</artifactId>
<name>myname</name>
<packaging>eclipse-test-plugin</packaging>
<properties>
<tycho-version>1.7.0</tycho-version>
</properties>
<parent>
<groupId>parentgroupid</groupId>
<artifactId>parent</artifactId>
<version>0.9.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>src/test/java/</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/Test_*.java</include>
</includes>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
<executions>
<execution>
<id>test</id>
<phase>test</phase>
<configuration>
<includes>
<include>**/Test_*.java</include>
</includes>
</configuration>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<configuration>
<output>file</output>
<append>true</append>
<includes>
<include>**/path_to_source/**/*</include>
</includes>
</configuration>
<executions>
<execution>
<id>jacoco-initialize</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>jacoco-site</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And here is my parent pom:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>parentgroupid</groupId>
<artifactId>parent</artifactId>
<version>0.9.5</version>
<packaging>pom</packaging>
<modules>
<module>moduleid</module>
</modules>
<properties>
<tycho-version>1.7.0</tycho-version>
</properties>
<repositories>
<repository>
<id>eclipse-2020-06</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/2020-06</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
<configuration>
<includeAllDependencies>true</includeAllDependencies>
</configuration>
</plugin>
</plugins>
</build>
</project>
Of course there won't be any test result for the JaCoCo due to you are using very old Surefire version 2.12.4. This version was not created for JUnit5.
Use the latest version 3.0.0-M5 and see the tutorial.
If you want to have tiny POM, remove the dependency junit-jupiter-engine due to you do not need to have an access to the JUnit internals in your test code. The Surefire will download it shortly before the test runtime.
Your POM has several errors. Let's start with the root cause and then other priorities from high to low.
Whole problem is that Surefire does not know about JaCoCo. You have to tel "him" this way (see jacoco.agent) which "wires" both. Pls ead the documentation in the JaCoCo project:
<properties>
<jvm.args.tests>-Xmx2048m -Xms1024m -XX:SoftRefLRUPolicyMSPerMB=50 -Djava.awt.headless=true -Djdk.net.URLClassPath.disableClassPathURLCheck=true</jvm.args.tests>
<properties>
...
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
</configuration>
...
The next error is with the way how you use plugins. The plugin jacoco-maven-plugin must be used only in the plugins section. The problem is that you use it also in the dependencies section. You do not want to have it on the classpath. It is job of the property jacoco.agent to put the jacoco agent on the test classpth only but there the JaCoCo plugin must start before the Surefire plugin.
The next thing i do not understand is the config of the compiler. Why you have this?
<executions>
<execution>
<id>compiletests</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
I have second question regarding the packaging. I have never seen this one. It isn't a standard packaging.
<packaging>eclipse-test-plugin</packaging>
Has the Eclipse plugin any special binary form of the archive file?

Tycho copy-dependencies do not include plugin dependencies

For one plugin in my tycho reactor I would like to copy a "pure-maven" dependency and its transitive ones in a folder named "lib/".
Currently if I use the copy-dependencies goal from maven-dependency-plugin, my dependency is correctly copied but the "plugin-dependencies" resolved by tycho are also copied, and I don't want those.
Any suggestion to achieve this goal ? I'm currently using the following code snippet
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${maven.groupid}</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Any suggestions are welcome.
Following this discussion on Eclipse forums it seems that we can tell maven to only include dependencies coming from the current pom.xml file using a combination of excludeScope and includeScope tags.
This updated XML snippet does the job as expected
<dependencies>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${maven.groupid}</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<!-- The lines below are aimed at telling maven NOT TO COPY tycho dependencies. Do not remove those! -->
<!-- See: https://dev.eclipse.org/mhonarc/lists/tycho-user/msg05080.html -->
<excludeScope>system</excludeScope>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Maven remove version from dependency jar

I'd like to know if there is a way to remove version number from maven dependency.
Let's say for my project I'd like to fetch commons-lang3 3.4 using maven dependency plugin:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
My pom configuration says, it is fetching dependencies to the ./lib directory inside of my project.
What I would like to achieve is remove on the fly version number from commons-lang3-3.4.jar. It would look like:
./lib/commons-lang3.jar
Question: Is there any way to do such thing?
Specifying finalName won't help here.
<build>
<finalName>${project.name}-testing</finalName>
</build>
Below my existing configuration:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${dir.javaLibs}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
To remove the version from copied dependencies, you can use the stripVersion option of the maven-dependency-plugin:
Strip artifact version during copy
Which has default value to false.
Hence, given your existing configuration, here is the change:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>process-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${dir.javaLibs}</outputDirectory>
<!-- new configuration entry below-->
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

use maven-shade-plugin, but dependency classes are not in the final jar

In my project's pom.xml I have the following dependency:
<dependency>
<groupId>com.my.library</groupId>
<artifactId>MyLib</artifactId>
<version>1.0</version>
<type>jar</type>
</dependency>
<dependency>
...
</dependency>
I would like to have my project's final built jar including the classes of above com.my.library:MyLib dependency, so I used maven-shade-plugin in the following way:
<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>
<filters>
<filter>
<artifact>com.my.library:MyLib</artifact>
<includes>
<include>com/my/library/**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Then, I run mvn clean install , my project was built successfully.
But when I check the content of MyProject.jar under target/ directory, it doesn't contain classes from com.my.library:MyLib dependency ,why? Where am I wrong with maven-shade-plugin ?
Define an <artifactSet>:
<artifactSet>
<includes>
<include>com.my.library:MyLib</include>
</includes>
</artifactSet>
And try removing the <artifact/> from the <filters/>. This should do it.
change pattern to
<includes>
<include>com/my/library/**.class</include>
</includes>

Maven - Copy specific dependency with its transitive dependencies to a give location

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>

Resources