Combine multiple module jars into a single one - java

Now I have a Maven project and here's my project structure:
| sound(parent)
| -- sound-service (sub-module)
| -- sound-start (sub-module)
In sound's pom. I have following:
<modules>
<module>sound-service</module>
<module>sound-start</module>
</modules>
After click clean - compile - package in order, IDEA IntelliJ helps me create two JAR packages for each sub-module. But what I want is a single JAR file with all dependencies and JAR libraries included. I also added the following maven plugin in the pom file of parent root, but I still cannot get one JAR with the whole thing.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.yct.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Did I miss something? Do I also need to add some other dependencies in sound's pom?

jar-with-dependencies can help you build a jar with the dependencies, not modules.
Instead of using <modules></modules>, try to use <dependencies></dependencies> instead.

I think the recommended way to put together single-jar applications in Maven is to use the shade plugin. In one of my projects, I configure it like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<!-- see http://maven.apache.org/plugins/maven-shade-plugin/examples/attached-artifact.html -->
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>standalone</shadedClassifierName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>main.class.name.here</mainClass>
</transformer>
<transformer
implementation="com.github.edwgiz.mavenShadePlugin.log4j2CacheTransformer.PluginsCacheFileTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.github.edwgiz</groupId>
<artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
</plugin>

Related

Vertx jar build throws error, works when running directly

I am running a vertx application from my local machine. Everything works perfectly fine when running it using Intellij Java Application configuration.
After generating the fat jar using mvn package, it throws random ArrayIndexOutOfBoundsException in places where the code is actually running fine.
Is the problem in the threads autogenerated in the vertex build?
Here's the build configuration from my pom.xml
<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>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>App</Main-Verticle>
</manifestEntries>
</transformer>
</transformers>
<artifactSet/>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

maven shade plugin override a file

I am using maven shade plugin to create a fat jar. I want to override 1 properties file that is coming from a jar i don't control. I want to update that properties file before creating the shaded jar. I tried using transformers configuration but when i am trying to override I am getting error
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-shade-plugin:3.2.4:shade (default) on project dsp-santa-breakbox: Error creating shaded jar: duplicate entry: assets/components/hystrixCommand/hystrixCommand.js -> [Help 1]
Here is my shade plugin configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>assets/components/hystrixCommand/hystrixCommand.js</resource>
<file>src/main/resources/hystrixCommand.js</file>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Is there a way to achieve this?
i had to filter the file from other artifact,
Here is how the final configuration looked like
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>com.yammer.breakerbox:breakerbox-service</artifact>
<excludes>
<exclude>assets/components/hystrixCommand/hystrixCommand.js</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
<resource>assets/components/hystrixCommand/hystrixCommand.js</resource>
<file>src/main/resources/hystrixCommand.js</file>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>

Include all resources in maven project in pom.xml

I need to include all resources in my pom.xml but i didn't succeed. Indeed, I'm trying this code but i don't think it works for all resources
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>project/classifier</shadedClassifierName>
<outputFile>shade\${project.artifactId}.jar</outputFile>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>fr.tse.fise2.pip.graphic.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
favicon should be in src/main/resources or a subfolder.
If you dont want to keep it there you can copy it using maven-resources-plugin
I need to include all of my resources on the project named pip.
error it's juste because my includes in pom.xml don't include src/main/resources and main can't access to files in this folder
enter image description here

Maven exec works, but java -jar does not

I have simple maven project with only one dependency. I can install it and run it command-line via Exec Maven Plugin:
mvn exec:java -D"exec.mainClass"="com.MyClass"
After packaging maven generates a .jar file in my directory. With a help of Maven JAR Plugin I made its manifest to know my main method class. It looks like:
...
Created-By: Apache Maven 3.3.1
Build-Jdk: 1.8.0_66
Main-Class: com.MyClass
Now I want to run this .jar file like regular java executable using java command, but after doing the following:
java -jar myFile.jar
it gives an error java.lang.NoClassDefFoundError concerning my only dependency.
How can I make maven to add all dependencies into my executable jar file?
One way to achieve this is using Apache 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.
This plugin has some advantages for large project with many dependencies. This is explained here: Difference between maven plugins ( assembly-plugins , jar-plugins , shaded-plugins)
In my project I use it with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</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.xxx.tools.imagedump.ImageDumpLauncher</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
You could use the Apache Maven Assembly Plugin, in order to create a jar with all its dependencies, so your pom.xml should be like the following:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>mypackage.myclass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
I hope it helps you, bye.

Run an executable JAR with external class path

Using Maven I compiled my project into a JAR that includes all the dependencies except for one big dependecy. The inclusion of the dependecies is done using:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<archive>
<manifest>
<mainClass>com.mypackage.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
Exclusion of dependencies is done with <scope>provided</scope>
The target myjar.jar is in the same folder as BigExternalJar.jar, but when I try to run:
java -cp ".:BigExternalJar.jar:myjar.jar" -jar myjar.jar
I get an exception for missing classes (those classes are from BigExternalJar.jar).
How can one pack dependencies into a JAR, using Maven only, but still be able to add additional JARs in classpath? Note that the BigExternalJar is not always in the same folder so I cannot add it manually to the MANIFEST file.
There are two similar questions that might look duplicate but they do not have an answer to this situation.
Eclipse: How to build an executable jar with external jar? AND
Running a executable JAR with external dependencies
The classpath argument is ignored if you use the -jar option. Only the classpath provided in the manifest is used.
<build>
<plugins>
<!-- compiler插件, 设定JDK版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>xxx.xxx.yourmain</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
pls try this~~~ all external jar will be in your packaged jar

Categories