This question already has an answer here:
How can I combine jars using Maven?
(1 answer)
Closed 9 years ago.
I want to build a standalone jar program use maven, but the output in target doesn't contains the referenced jar libs, how can I include them in my target?
Use following in pom.xml and build the jar, use assembly plugin
<plugins>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>package-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>xxxxx</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Related
I use IntelliJ IDEA to generate a jar file with maven-assembly-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<finalName>${project.artifactId}-fatjar-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
It didn't work, it asks continuously for dependencies during execution. I was unable to use jar file, so I imported the project to Eclipse and used the built-in jar export option. This jar is working fine. I couldn't find what the difference is between these jar files.
The reason is probably that Eclipse is generating a "Class-Path:" entry in the manifest file.
Try to update the assembly conf in your .pom file by adding something like (by heart, not checked):
<addClasspath>true</addClasspath>
By default the maven-assembly-plugin will not bundle all the dependencies required for your own jar to run standalone.
So you will need to add this below under the plugin configuration:
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
As a result, the plugin tag becomes:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>test.LeanFTest</mainClass>
</manifest>
</archive>
<finalName>${project.artifactId}-fatjar-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef> <!-- the secret -->
</descriptorRefs>
</configuration>
</plugin>
You can run:
java -jar path/to/LeanFTest.jar
To directly run the program.
I have a Maven project where I need to package different Java programs as jars, each one with its own dependecies.
To achieve this I am currently using maven-assembly-plugin with different executions, one for each java program I need to package (e.g. Program1.java, Program2.java, Program3.java):
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assembly1</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>my.package1.Program1</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>Program1</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
<execution>
<id>assembly2</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>my.package2.Program2</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>Program2</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
<execution>
<id>assembly3</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>my.package3.Program3</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>Program3</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
Each one of these classes (Program1, Program2, Program3) requires different libraries as depedencies, thus I expected in output to get 3 jars with different size, but I got 3 files of the same size (Program1.jar, Program2.jar, Program3.jar).
It's like Maven is packaging all the dependencies defined inside the tag dependencies, regardless if they are used or not.
How can I tell maven to package, for each execution inside the assembly-plugin, only the dependencies effectively imported and used by the specified Class?
The default behaviour of assembly plugin is to include all dependencies of your current maven module. You could change that by explictly excluding the unwanted dependencies.
However, if you have three different programs that even do not have the same dependencies, it might be better to split up your project into three different (sub-)modules, maybe with a common parent pom. More details can be found here. After splitting up the project, each submodule can run its own assembly plugin that only packs the dependencies that are declared for each submodule.
If you decide to split up your project, you can clean up the required dependencies for each sub-module with the help of the dependency plugin, goal dependency:analyze.
I have written a Java program, when it is run I add the name of every image file in the folder "items" into an ArrayList.
This is fine when I am running the application in eclipse.
But as soon as I export to a runnable JAR file and run it, the images can't be found and returns a NullPointerException.
I've tried to use getClass().getResource() but to no avail.
This is what my Package Explorer looks like and
This is what my exported JAR looks like
As you can see from the second image, all the images are taken out of the items folder and left in the root of the JAR.
Any help would be greatly appreciated!
try maven-assembly-plugin if you are using the maven build tool
How can I create an executable JAR with dependencies using Maven?
https://www.mkyong.com/maven/create-a-fat-jar-file-maven-assembly-plugin/
Put this in your pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<mainClass>com.maven.class... (Class path)</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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
This question already has an answer here:
How can I package a jar with Maven and include some dependencies in WEB-INF/lib?
(1 answer)
Closed 6 years ago.
I need to make a jar out of my Java project, and I need it to also contain the class files of one of the dependencies, but not all of them. I've used maven-assembly-plugin which includes all the files and creates a huge jar, but I only need
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.10.45</version>
</dependency>
I've also tried the maven shade plugin but with no result: I somehow end up including all the dependencies or excluding all of them
<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>
<excludes>
<exclude>org.apache.spark:*</exclude>
<exclude>com.google.code.gson:*</exclude>
<exclude>edu.stanford.nlp:*</exclude>
<exclude>log4j:*</exclude>
<exclude>com.optimaize.languagedetector:*</exclude>
<exclude>info.debatty:*</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
Use 'provided' for the scope tag of the dependencies that you don't want to include in the final jar file.
<dependency>
<groupId>GROUP_ID</groupId>
<artifactId>ARTIFACT_ID</artifactId>
<version>VERSION</version>
<scope>provided</scope>
</dependency>
And use maven-assembly-plugin to build the jar
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>MAIN_CLASS</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
I have a Maven project and I want to create two executable jar files from it. One will be used interactively by users and a second will be run as a scheduled job that reads the log files produced by the former. In the end, I would expect the two jar files to be identical except for the Main-Class attribute in the MANIFEST.MF file.
I am using maven-antrun-plugin to create an executable jar and this seemed to be working fine until I tried to create a second jar file by introducing Maven profiles. The relevant section of my POM file looks like this:
<profiles>
<profile>
<id>publisher</id>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
...
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>${project.artifactId}</finalName>
<archive>
<manifest>
<mainClass>fully.qualified.path.Publisher</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>logReader</id>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
...
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>${project.artifactId}-logReader</finalName>
<archive>
<manifest>
<mainClass>fully.qualified.path.LogReader</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Really, the only difference between the two is the "finalName" and "mainClass" elements as defined within the plugin.
When I try to execute mvn:package on both profiles (I'm using IntelliJ IDEA, by the way), I get two .jar files, but one is correct and the other is incorrect. The "correct" one contains all the dependencies and a valid MANIFEST.MF file. The "incorrect" one contains no dependencies and the MANIFEST.MF file lacks the "Main-Class" property that I need in order for it to be executable.
I have found that if I ever run just one profile or the other, that it works fine but, if I try to execute both profiles at once, it fails. I also get the following notes in my log, but I must admit that I don't completely understand what they are saying:
[INFO] Building jar: .../target/publisher.jar
...
[INFO] Building jar: .../target/publisher-logReader.jar
[WARNING] Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.
Instead of attaching the assembly file: .../target/publisher-logReader.jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: .../target/publisher.jar with assembly file: .../target/publisher-logReader.jar
Any thoughts about this? Is it possible to produce two jar files with a single mvn:package in this way, or am I barking up the wrong tree?
Thanks!
So as soon as I posted this, I found this thread:
Create multiple runnable Jars (with depencies included) from a single Maven project
This uses a different approach in that it doesn't use two profiles, it uses two executions, as such:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>build-publisher</id>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>fully.qualified.path.Publisher</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${project.artifactId}</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
<execution>
<id>build-logReader</id>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>fully.qualified.path.LogReader</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<finalName>${project.artifactId}-logReader</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This seems to be working. The moral of the story seems to be that I don't completely understand profiles or when they should be used.