I am very frustrated. I've spent a long time trying to compile a Maven project into an Uber/Fat jar file using the Maven shade plugin, but I still keep getting "mvn is not recognized as an internal or external command" error in command prompt. Here are the important bits of my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>*my main class*</mainClass>
</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>
I don't know what I'm doing wrong. I am going into my project's directory using Windows Command Prompt and typed "mvn clean install" but it doesn't seem to work. I am new to Maven, I generally use Gradle. Has the plugin not loaded? Am I doing something wrong? Or am I just being stupid as always?
Any help appreciated! Thanks in advance!
For Maven to work on command line, you need to
download and unzip it to some directory
Add the bin directory in that directory to your PATH
If you have done that, you may have a type or may need to restart your system.
I am trying to run a jar created by the maven shade plugin. I am configuring the main class the following way:
<project>
...
<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>org.comany.MainClass</Main-Class>
<Build-Number>123</Build-Number>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
But when I try running the jar using java -jar app.jar it gives the following error
"no main manifest attribute, in app.jar"
EDIT:
I checked the contents of the jar using jar tf app.jar and I see a MANIFEST.MF file. BUt it does not have the entry for main class. How do I make sure the manifest file in jar has this entry apart for adding it in the shade plugin configuration?
Maven's shade plugin uses the JAR generated by the jar plugin and adds dependencies on it. Since it seems like the transforms on the shade plugin do not work properly, you just need to set the configuration for the jar-plugin like so:
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mypackage.MyClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
<plugin>
[Your shade plugin definition without the transformers here]
</plugin>
</build>
Don't forget to add shade as a target:
mvn clean package shade:shade
Check if you have more than one main(). If you do, maven needs to know which one to use.
I am having a similar problem to this question. I have tried all the suggestions listed and am still at a loss. My issue is that I am trying to build a maven project and distribute it to other machines, but the jar files are not being populated with a correct Manifest. Each time I build and run I get the following error: no main manifest attribute, in myjar.jar. Is there some sort of configuration file I need to edit? I just don't know what is going on. I have attempted this fix also, but to no avail.
You can add it into project's pom file, inside <project> tag:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Another option is to use the maven shade plugin. Unlike the maven jar plugin showed by tigran, the maven shade plugin includes your dependencies in the generated jar.
A sample usage of the plugin is :
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>your.main.Class</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I'm relatively new to the Maven mantra, but I'm trying to build a command-line runnable jar with Maven. I've setup my dependencies, but when I run mvn install and attempt to run the jar, two things happen. First, no main class is found, which is correctable. When I've corrected this, I get errors on run stating that classes cannot be found.
Maven is not packaging my dependency libraries inside of the jar, so I am unable to run the jar as a stand-alone application. How do I correct this?
The easiest way to do this would be to create an assembly using the maven-assembly-plugin and the predefined jar-with-dependencies descriptor. You'll also need to generate a manifest with a main-class entry for this uber jar. The snippet below shows how to configure the assembly plugin to do so:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Then, to generate the assembly, just run:
mvn assembly:assembly
If you want to generate the assembly as part of your build, simply bind the assembly:single mojo to the package phase:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
And simply run:
mvn package
Maven is not packaging your dependencies inside your jar file, because you don't usually do this with Java programs.
Instead you deliver the dependencies together with your jar file and mention them in the Class-Path header of the Manifest.
To go this route, you'll need to enable the addClasspath property (documented here) for the maven-jar-plugin.
If you really want to include all your dependencies in your jar file, then you can use the Maven Assembly plugin to create a jar-with-dependencies.
This is what I would do for small projects. Most of the time you don't want one huge jar.
to build:
mvn clean dependency:copy-dependencies package
to execute (in target dir):
java -cp myjar.jar:./dependency/* com.something.MyClass
I Agree with Joachim Sauer,
Instead of using jar-with-dependency you should configure the jar plugin like that in your pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<index>true</index>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>[mainClassFullName]</mainClass>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${project.url}</url>
<key>value</key>
</manifestEntries>
</archive>
</configuration>
</plugin>
And use this assembly configuration to add the jar dependencies to you assembly:
<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>zip-with-jars</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</dependencySets>
</assembly>
Just add the below code in pom.xml and Run as: maven:install . The jar will be created in target folder of eclipse which can be used as "java -jar Hello.jar" . but make sure that name of main class is given com.abc.HelloWorld.java
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-shade-plugin</artifactid>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalname>HelloW</finalname>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestentries>
<main-class>com.abc.HelloWorld.java</main-class>
<build-number>1</build-number>
</manifestentries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I have a spring boot application, and the jar created by maven package can be run without setting up additional plugins.
Inside my pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
https://spring.io/projects/spring-boot
How do I get my project's runtime dependencies copied into the target/lib folder?
As it is right now, after mvn clean install the target folder contains only my project's jar, but none of the runtime dependencies.
This works for me:
<project>
...
<profiles>
<profile>
<id>qa</id>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
mvn install dependency:copy-dependencies
Works for me with dependencies directory created in target folder. Like it!
The best approach depends on what you want to do:
If you want to bundle your dependencies into a WAR or EAR file, then simply set the packaging type of your project to EAR or WAR. Maven will bundle the dependencies into the right location.
If you want to create a JAR file that includes your code along with all your dependencies, then use the assembly plugin with the jar-with-dependencies descriptor. Maven will generate a complete JAR file with all your classes plus the classes from any dependencies.
If you want to simply pull your dependencies into the target directory interactively, then use the dependency plugin to copy your files in.
If you want to pull in the dependencies for some other type of processing, then you will probably need to generate your own plugin. There are APIs to get the list of dependencies, and their location on disk. You will have to take it from there...
Take a look at the Maven dependency plugin, specifically, the dependency:copy-dependencies goal. Take a look at the example under the heading The dependency:copy-dependencies mojo. Set the outputDirectory configuration property to ${basedir}/target/lib (I believe, you'll have to test).
Hope this helps.
All you need is the following snippet inside pom.xml's build/plugins:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
The above will run in the package phase when you run
mvn clean package
And the dependencies will be copied to the outputDirectory specified in the snippet, i.e. lib in this case.
If you only want to do that occasionally, then no changes to pom.xml are required. Simply run the following:
mvn clean package dependency:copy-dependencies
To override the default location, which is ${project.build.directory}/dependencies, add a System property named outputDirectory, i.e.
-DoutputDirectory=${project.build.directory}/lib
If you want to do this on an occasional basis (and thus don't want to change your POM), try this command-line:
mvn dependency:copy-dependencies -DoutputDirectory=${project.build.directory}/lib
If you omit the last argument, the dependences are placed in target/dependencies.
A simple and elegant solution for the case where one needs to copy the dependencies to a target directory without using any other phases of maven (I found this very useful when working with Vaadin).
Complete pom example:
<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>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${targetdirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then run mvn process-sources
The jar file dependencies can be found in /target/dependency
Try something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy</id>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
supposing
you don't want to alter the pom.xml
you don't want test scoped (e.g. junit.jar) or provided dependencies (e.g. wlfullclient.jar)
here ist what worked for me:
mvn install dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/lib
If you want to deliver a bundle of your application jar, together with all its dependencies and some scripts to invoke the MainClass, look at the appassembler-maven-plugin.
The following configuration will generate scripts for Window and Linux to launch the application (with a generated path referencing all the dependency jars, download all dependencies (into a lib folder below target/appassembler). The assembly plugin can then be used to package the whole appassembler directory to a zip which is installed/deployed along with the jar to the repository.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>generate-jsw-scripts</id>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
<configuration>
<!--declare the JSW config -->
<daemons>
<daemon>
<id>myApp</id>
<mainClass>name.seller.rich.MyMainClass</mainClass>
<commandLineArguments>
<commandLineArgument>start</commandLineArgument>
</commandLineArguments>
<platforms>
<platform>jsw</platform>
</platforms>
</daemon>
</daemons>
<target>${project.build.directory}/appassembler</target>
</configuration>
</execution>
<execution>
<id>assemble-standalone</id>
<phase>integration-test</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<programs>
<program>
<mainClass>name.seller.rich.MyMainClass</mainClass>
<!-- the name of the bat/sh files to be generated -->
<name>mymain</name>
</program>
</programs>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
The assembly descriptor (in src/main/assembly) to package the direcotry as a zip would be:
<assembly>
<id>archive</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/appassembler</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
If you make your project a war or ear type maven will copy the dependencies.
It's a heavy solution for embedding heavy dependencies, but Maven's Assembly Plugin does the trick for me.
#Rich Seller's answer should work, although for simpler cases you should only need this excerpt from the usage guide:
<project>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
You can use the the Shade Plugin to create an uber jar in which you can bundle all your 3rd party dependencies.
Just to spell out what has already been said in brief. I wanted to create an executable JAR file that included my dependencies along with my code. This worked for me:
(1) In the pom, under <build><plugins>, I included:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<archive>
<manifest>
<mainClass>dk.certifikat.oces2.some.package.MyMainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
(2) Running mvn compile assembly:assembly produced the desired my-project-0.1-SNAPSHOT-jar-with-dependencies.jar in the project's target directory.
(3) I ran the JAR with java -jar my-project-0.1-SNAPSHOT-jar-with-dependencies.jar
If you're having problems related to dependencies not appearing in the WEB-INF/lib file when running on a Tomcat server in Eclipse, take a look at this:
ClassNotFoundException DispatcherServlet when launching Tomcat (Maven dependencies not copied to wtpwebapps)
You simply had to add the Maven Dependencies in Project Properties > Deployment Assembly.
You could place a settings.xml file in your project directory with a basic config like this:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>.m2/repository</localRepository>
<interactiveMode/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
More information on these settings can be found in the official Maven docs.
Note that the path is resolved relative to the directory where the actual settings file resides in unless you enter an absolute path.
When you execute maven commands you can use the settings file as follows:
mvn -s settings.xml clean install
Side note: I use this in my GitLab CI/CD pipeline in order to being able to cache the maven repository for several jobs so that the dependencies don't need to be downloaded for every job execution. GitLab can only cache files or directories from your project directory and therefore I reference a directory wihtin my project directory.