Maven: jar-with-dependencies include external jar [duplicate] - java

I want to build a .jar file with dependencies in maven. Unfortunately I have to include some external .jars in my buildpath. When I now try to build this project with maven package I will get an error that those external .jars are not found.
How to adapt my pom file to add those jars?
current:
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>

You can include the external jars in your build path as dependency with <scope>system</scope>
.
Check this link

You need use below command to add external jar into .m2 folder
mvn install:install-file -Dfile=[JAR] -DgroupId=[some.group] -DartifactId=[Some Id] -Dversion=1.0.0 -Dpackaging=jar
This will add the given jar in to your .m2 folder. After that go to pom.xm and just add the dependency with given group id, artifact id and version.

A simple solution for this is to add it into local maven repository
One way to do is via mvn install commands as suggested in previous post .
Another easy way is,
In your eclipse ide right click on project select Maven option.
Select Install or deploy an artifact to a maven repository option and click on next.
Click on browse next to the Artifact file checkbox & select your jar file.
Enter the GroupId and ArtifactId and version ensure generate pom & create checksum are checked & packaging is jar
Click on finish, Wallah!!! your job is done the jar is added in your local repository which you can define in setting.xml or m2 directory.
Now just add the simple maven dependency as per the GroupId,ArtifactId & jar version that you have entered as per the import and that's it your external jar will be packaged by maven.

Related

Copy resulting fat jar to another target folder in Spring boot project

I have Spring boot project. Everything is built OK in /target folder but I'd like to change destination folder.
I tried to use maven-jar-plugin as described below but it copies only jar with compiled classes of project (small jar).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>${maven.multiModuleProjectDirectory}/output/bin</outputDirectory>
</configuration>
</plugin>
Instead I want to make Maven to copy FAT jar.
Maven builds FAT jar and puts the Jar to /target folder. How to change destination?
UPDATE 1
this is needed by project requirements - need to build folder structure with properties, bash scripts(as entry point) and fat jar:
Try to add this plugin:
<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>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<outputDirectory>${maven.multiModuleProjectDirectory}/output/bin</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

How to rename the jar downloaded as dependency in maven

I am trying to include a jar from the repository but I want to rename the jar when I use it.
Currently I am doing like
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<finalName>test</finalName>
<includes>
<include>original-jar-name</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
But there is no effect of the above.
I have already taken help from :
Maven - How to rename the output classifier of a jar name?
Controlling maven final name of jar artifact
Is it possible to rename a maven jar-with-dependencies?
But that did not worked.
How is it achievable ?

Force Maven 3 to copy 'provided' dependencies

I use copy-dependencies goal to copy dependencies for current artifact.
But it doesn't copy dependencies with scope 'provided'.
How to fix it?
The xml configuration is standard:
<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>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeArtifactIds>project-services</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<finalName>project-web</finalName>
</build>
Why do I want to do this?
Because I have to support both ant and maven builds working.
Therefore, I want to copy all dependencies into separate directory by running mvn install -o. In Ant build.xml I include path to that directory as classpath. After that Ant builds ear file and includes whole lib directory withoud system tools.jar and other 'provided' jars.
Version of Apache Maven is 3.0.3
As documented by the plugin use includeScope:
http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html#includeScope
Edit:
Why do I want to do this? Because I have to support both ant and maven
builds working.
Consider to use Ivy to manage your dependencies with Ant:
http://ant.apache.org/ivy/
Here a post how you can configure Ivy to connect to Nexus:
https://support.sonatype.com/entries/21627528-how-do-i-configure-my-ivy-build-to-download-artifacts-from-nexus

Maven deploy jar with dependencies to repo

I can deploy a jar by using the following in my pom.xml and running mvn deploy:
<distributionManagement>
<repository>
<id>releases</id>
<url>http://${host}:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://${host}:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
And I can build an executable jar-with-dependencies using the following:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>deploy</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Problem is I don't know how to stitch these together to deploy the executable jar to my Maven repo. I don't really know if this is accomplished by a new plugin or by adding a goal or other step to the existing assembly plugin.
If you bind the assembly to the packaging phase, it will install in your repository both the "regular" jar and the with-dependencies jar when you do a build:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Then simply run mvn clean install deploy to upload both jars to your repository.
In order to build a (so-called) Über JAR and deploy it using maven, you could also use the shade plugin. The following code is taken from their website but I've made one or two projects using this feature.
<project>
...
<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>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
In this configuration you get the Über JAR as one deployment besides the normal JAR. The user of your JAR can then decide to pull the all-in-one package or the JAR with dependencies based on the classifier.
I'll usually use the shade plugin to build Über JARs (or modify the JAR in a way) and use the assembly plugin to build things like installation packages (containing the JAR and possibly other things). I am unsure what the intended goals of the single plugins are however.
The following worked. I'm going to leave this question open a bit because I'm not positive this is best practice, but working is something.
Problems I notice are that I made up the ID name and I don't know if this is usual practice and that I have to hard code the jar name; it isn't inferred from anything else.
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>deploy-executable</id>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<file>target/Monitoring-Client-1.0-SNAPSHOT-jar-with-dependencies.jar</file>
</configuration>
</execution>
</executions>
</plugin>
Essentially my difficulty doing this revealed the fact that my pom.xml was way off the rails already. Everything would have snapped into place on its own. I was formerly doing:
Save all the dependencies into a lib folder
Build a jar with a classpath slurping up that lib folder
Use the assembly plugin to make another deployable jar
I think there were several reasons this sort of made sense along the way, especially when my libraries were not well-factored from my applications.
However by deleting 1 and 2 all that is needed is the distributionManagement section and the deploy phase works automagically. So all in all this is an amazing case of literally adding functionality by deleting large swathes of code.
First you shouldn't do the creation of the ueber jar in the deploy phase it's better to do this in the package phase. Furthermore the created jar file is usually automatically attached to your artifact and will be transfered to the remote repository (in your case Nexus). You can check this if you simply try to do a mvn install and take a look at the output if the created jar is installed into the local repository.
To deploy the results into nexus you need to call mvn deploy.

Make Maven to copy dependencies into target/lib

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.

Categories

Resources