remove all dependencies of a jar within a maven assembly - java

I am trying to create a zip file that includes two folders each folder will contain a plugin of a certain dependency within the pom. I am currently able to create the correct structure but I would like to make sure that the jar of the first dependency for example does not fall within that of the second.
my current pom structure is as follows:
<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>
<parent>
<groupId>PARENT-GROUP</groupId>
<artifactId>PARENT-ARTIFACT</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>
<groupId>GROUP-ID</groupId>
<artifactId>ARTIFACT-ID</artifactId>
<properties>
<main.project>MAIN-PROJECT</main.project>
<plugin.version>0.0.1-SNAPSHOT</plugin.version>
<plugin.artifact>PLUGIN-ID</plugin.artifact>
</properties>
<dependencies>
<dependency>
<groupId>PLUGIN-GROUP</groupId>
<artifactId>${plugin.artifact}</artifactId>
<version>${plugin.version}</version>
</dependency>
<dependency>
<groupId>SECOND-DEPENDENCY</groupId>
<artifactId>SECOND-ARTIFACT-ID</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${main.project}-${project.parent.version}</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${project.basedir}/src/zip.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
As can be seen I have two dependencies within the pom that I am getting. The output I would like to have is the following folder structure
main\lib: contains the second dependency jar with all it's dependencies within the same folder.
main\plugin\plugin: contains all of the first dependency (the plugin and all it's dependency) both folders should not include the dependency of the first and vice versa. So far I have come up with the following assembly xml
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>release</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
<excludes>
<exclude>
*:${plugin.artifact}
</exclude>
</excludes>
</dependencySet>
<dependencySet>
<outputDirectory>/plugins/${plugin.artifact}-${plugin.version}/${plugin.artifact}-${plugin.version}</outputDirectory>
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
<excludes>
<exclude>
*:SECOND-ARTIFACT-ID
</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>
This give me the write folder structure but includes the dependencies in both I would like to know if there is a better way to exclude the dependencies of each of the jars automatically instead of excluding them one by one

Helping other people with the solution if they are looking for it. All you will need to perform is adding within the dependencySet an extra tag user transitive filtering and set it to true.
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<unpack>false</unpack>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
<excludes>
<exclude>
*:${plugin.artifact}
</exclude>
</excludes>
</dependencySet>
this will make sure that the excludes dependencies are filtered.

Related

NoClassDefFoundError inside Jar with Maven [duplicate]

This is my pom file:
<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>com.sia.g7</groupId>
<artifactId>sia</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sia</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>commons-math</groupId>
<artifactId>commons-math</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jmathplot</groupId>
<artifactId>jmathplot</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jmathplot.jar</systemPath>
</dependency>
<dependency>
<groupId>jgraphx</groupId>
<artifactId>jgraphx</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jgraphx.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>com.sia.g7.AbstractSimulation</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
And when I run the jar I get:
Exception in thread "main" java.lang.NoClassDefFoundError: com/mxgraph/swing/mxGraphComponent
which is part of the jgraphx dependency.
What am I missing?
you can do it by adding this dependencySet to your assembly file descriptor
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>system</scope>
</dependencySet>
this assembly descriptor add all dependencies including system scoped
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>jar-with-all-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>system</scope>
</dependencySet>
</dependencySets>
</assembly>
Yes, and this is one of the reasons you shouldn't abuse system scope dependencies (which is globally a bad practice) and this problem has already been mentioned several times here on SO (here, here). I'm proposing a solution to deal with project relative dependencies in a "clean" way in this answer.
You should remove the <scope>system</scope> clauses from those dependencies.
When the scope is set to system that means the artifact is ALWAYS available, so jar-with-dependencies does not include it.
It must not be system scope in the first place. This is the source of your problem.
Install/deploy your dependency into the repository and make it a normal compile (or runtime) scope dependency.
There are 2 solutions:
Recommended: create a repository and then provide the dependency in the same way as you provide dependency from maven repository.
Though the above solution is the recommended one, but if you don't want to create the repository, then here is the workaround:
First in your pom.xml, remove the system scope and the systemPath. Please note that the commented lines were removed to resolve this issue.
<dependency>
<groupId>com.paymentus.timgroup.statsd</groupId>
<artifactId>paymentus-timgroup-statsd-client</artifactId>
<version>1.0-SNAPSHOT</version>
<!--<scope>system</scope>-->
<!--<systemPath>${basedir}/external_lib/xyz.jar</systemPath>-->
</dependency>
Use maven-install-plugin in the same pom.xml. You need to modify the details in bold, no need to change any other thing in this plugin:
<project> ....
<profiles>...<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-external</id>
<phase>clean</phase>
<configuration>
**<file>${basedir}/external_lib/xyz.jar</file>**
<repositoryLayout>default</repositoryLayout>
**<groupId>com.my.project</groupId>**
**<artifactId>my-project</artifactId>**
**<version>1.0-SNAPSHOT</version>**
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins></profiles>
</project>
Unpack your jar and add it to src/main/resources.

How to generate resource files from parent POM in Maven?

I want to have parent POM similar to the following:
<project>
<groupId>com.mycompany.whatever</groupId>
<artifactId>whatever-parent</artifactId>
<version>1</version>
<packaging>pom</packaging>
<build>
<plugins>
<!-- plugin for generating resource files -->
<plugin>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<configuration>
<files>
<file>
<!-- location relative to jar's root -->
<location>lorem.txt</location>
<!-- file contents -->
<contents>Lorem ipsum dolor</contents>
</file>
</files>
</configuration>
<executions>
<execution>
<goals>
<goal>...</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
So when it will be used as parent POM then lorem.txt file will be automatically generated and packaged inside jar.
If you need a file include inside your jar/zip file.
Please refer the way to use maven assembly plugin:
http://maven.apache.org/plugins-archives/maven-assembly-plugin-2.6/examples/index.html
http://maven.apache.org/plugins/maven-assembly-plugin/
EX:
<assembly xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>src/main/config_templates</directory>
<lineEnding>unix</lineEnding>
<outputDirectory>config_templates</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>dep/*</include>
<include>classpaths/*</include>
<include>endorsed/*</include>
<include>*.jar</include>
</includes>
<outputDirectory>target</outputDirectory>
</fileSet>
If you need the structure of your project from the first time, please refer the way to create proj from your own archetype:
https://maven.apache.org/archetype/maven-archetype-plugin/usage.html
I hope they can help you.

maven pom to gradle - assembly plugin failure

I'm currently having my JAVA Maven projects and trying to migrate it to Gradle. I issued the below command to convert it,
gradle init
Kindly find the pom.xml, the descriptor xml file of my project and the generated build.gradle files below,
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ProjectA</artifactId>
<packaging>jar</packaging>
<name>ProjectA</name>
<dependencies>
<dependency>
<groupId>org.jpos</groupId>
<artifactId>jpos</artifactId>
<version>113</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/non-distributable-lib/jpos113.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<archive>
<manifest>
<mainClass>com.test.jpos.Main</mainClass>
</manifest>
</archive>
<descriptor>src/main/assembly/assemble_POSMClient_JPOS_Bridge.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<parent>
<groupId>com.test</groupId>
<artifactId>ProjectRoot</artifactId>
<version>5.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
build.gradle :
description = 'ProjectA'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile files('src/main/non-distributable-lib/jpos113.jar')
}
assemble_POSMClient_JPOS_Bridge.xml :
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>assemble_pos</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.basedir}/../POSMClient-Common/src/main/lib/Packaged-Web-Components</directory>
<outputDirectory>Packaged-Web-Components</outputDirectory>
<includes>
<include>**/*.*</include>
</includes>
<excludes>
<exclude>www.zip</exclude>
<exclude>*.uncompressed.js</exclude>
<exclude>js/lib/cometd/*</exclude>
<exclude>.gitmodules</exclude>
<exclude>README.md</exclude>
<exclude>package.sh</exclude>
<exclude>updateDojo.sh</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/../POSMClient-Common/src/main/native</directory>
<outputDirectory>Packaged-Web-Components/</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
</fileSets>
Note:
When i do a clean there are no exceptions coming up and is successfull, but its failing to generate the assembly jar file.
gradle clean
Its failing to generate the assembly plugin section in the build.gradle file. Kindly let me know if there is something i'm missing.
There is no like-like way of working with maven and gradle. Just running gradle init will not help to resolve most of the pom structure.
Gradle has similar plugin for distribution.
Below link has more details, on how u can write blocks of codes in build.gradle file to achieve assembly and distribution.
https://docs.gradle.org/current/userguide/distribution_plugin.html

Include entire dependency JAR as JAR within maven project

Is it possible to tell Maven, or one of its common plug-ins, to pack one of my dependency JARs within the final assembly as a JAR file?
ie If I depend on org.some-group:some-artifact:1.2.3, the Maven plug-in would just stuff the entire some-artifact-1.2.3.jar into my final JAR file?
If I understood your question clearly, you need to add one specific jar into your generated jar, in this case you might use use classifier with maven-assembly-plugin
POM.xml
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>jar-with-dependencies-module</artifactId>
<version>1.0.0-SNAPSHOT</version>
<classifier>jar-with-dependencies</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
assembly.xml
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>final-assembly</id>
<formats>
<format>jar</format>
</formats>
<dependencySets>
<!-- Include the jar-with-dependencies -->
<dependencySet>
<includes>
<include>org.some-group:some-artifact:1.2.3</include>
</includes>
<useProjectArtifact>false</useProjectArtifact>
<!-- Don't use transitive dependencies since they are already included in the jar -->
<useTransitiveDependencies>false</useTransitiveDependencies>
</dependencySet>t>
</dependencySets>
</assembly>
Above configurations might give you an idea where to start and how you can include specific jars to your final jar

How do you use the maven shade plugin to include only specific classes from a dependency with scope "provided"?

I am using the maven shade plugin to package my application into a jar file. One of my dependencies is to Tomcat:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>7.0.59</version>
<scope>provided</scope>
</dependency>
The scope of this dependency is provided as the container itself will supply its JAR files. However, I do need to add a few single classes from this dependency to my JAR file. I tried adding a filter and specifying the name of the class that is to be added, but it seems that provided dependencies are ignored by the shade plugin.
<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>
<filters>
<filter>
<artifact>org.apache.tomcat:tomcat-catalina</artifact>
<includes>
<include>org/apache/catalina/deploy/LoginConfig.class</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Any ideas how what I need can be achieved?
The configuration setting you need is <useDependencyReducedPomInJar>true</useDependencyReducedPomInJar>. This will create a file named dependency-reduced-pom.xml with the references to the shaded jar(s) removed. You can also use <promoteTransitiveDependencies>true</promoteTransitiveDependencies> if the shaded jars have their own transitive dependencies to add them to the modified pom.
I had the same issue and If I can suggest a solution it would be to use the maven-assembly-plugin which will address your problem :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.mypackage.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
And here is a sample of the assembly.xml which will allow you include "provided" scope artifacts:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
</dependencySet>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>provided</scope>
</dependencySet>
</dependencySets>
I'am just having classpath issues in the generated artifact in the Manifest file!
I'm not very familiar with this plugin, but the best place for finding solutions to these kinds of problems is to have a look at the plugin/ goal documentation.
I guess the parameter keepDependenciesWithProvidedScope is what you are looking for.
I had the same issue, but I found we misunderstood how this plug-in works. If some dependencies are bundled into the shaded jar, they will be removed from the dependencies in the pom.xml in the shaded jar. So you should change nothing, just left their scope runtime.

Categories

Resources