Maven - Build with Dependencies [duplicate] - maven

This question already has answers here:
How can I create an executable/runnable JAR with dependencies using Maven?
(33 answers)
Closed 9 years ago.
I've downloaded a source code from internet and I'm trying to build it with maven. Here is the pom.xml file that came with the source code:
<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.mycompany</groupId>
<artifactId>myArtifact</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>myArtifact</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>myArtifact.Main</mainClass>
</manifest>
</archive>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.4-701.jdbc4</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
The mvn install command is generating the jar file but I'm unable to execute this file because of the missing dependencies (class not found exception related to postgresql dependency in this example).
I've noticed that maven has downloaded the dependencies correctly (the jar libraries are all at the local maven repository directory) but mvn install is not copying these libraries into the generated jar file. How can I do this?
Thanks.

Remove the descriptorRefs and archive tag from your maven-compiler-plugin section.
In order to generate a JAR with all the dependencies self contained. You need to put this into the build plugins section of your pom.xml:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>
com.test.your.main.class.goes.Here
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
Create the JAR file by running the following at the command prompt:
mvn clean compile assembly:single

Related

Error running stand-alone jar with ojdbc jar dependency

I have the following pom:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>org.example</groupId>
<artifactId>do_can_proj</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11-production</artifactId>
<version>21.1.0.0</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.do.can.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>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Running,
$ mvn clean package assembly:single
generates a jar in the target folder.
When I run the jar file from the command line:
java -jar target/do_can_proj-1.0-SNAPSHOT-jar-with-dependencies.jar
I get the following error:
SQL State: 08001
No suitable driver found for jdbc:oracle:thin:#hostname:1521:SID
And this is how I have my project setup:
When running with the -jar argument, the classpath is set to the entry in the manifest in the jar file. By default this is empty. It can be argued that the assembly target should be improved to allow this.
It needs to be set to include all libraries used by your code for this to work and the libraries needs to be added from the Maven repository. How exactly to do this depends on your needs. See How can I create an executable JAR with dependencies using Maven? for suggestions.

No main class in manifest with maven

I have my IntelliJ maven project and I am trying to build the jar but whenever I run it it throws no main manifest attribute, in Project.jar
Here is my pom.xml build. I am trying to set the main class in the manifest with Maven I read online to do it in the maven-compiler-plugin. When I open the jar in WinRar the manifest is generated by Apache Maven but has not got the main class.
<?xml version="1.0" encoding="UTF-8"?>
<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>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<archive>
<manifest>
<mainClass>com.bwfcwalshy.ssbbot.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Add the maven-jar-plugin and make sure you use the maven directory structure (src/main/java) for your java files.
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.bwfcwalshy.ssbbot.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
...

Maven multimodules w. assembly options per module?

I've a multimodule maven setup, where I'd like to pack one of the jars with their dependencies and all others could stay as they are. My configuration looks like this:
Root:
<project...>
<modelVersion>4.0.0</modelVersion>
<name>Foo</name>
<artifactId>Foo</artifactId>
<groupId>org.example</groupId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>Bar1</module>
<module>Bar2</module>
<module>Bar3</module>
</modules>
</project>
Module (Bar1):
<project...>
<modelVersion>4.0.0</modelVersion>
<name>Foo - Bar1</name>
<artifactId>Bar1</artifactId>
<groupId>${project.parent.groupId}</groupId>
<parent>
<artifactId>Foo</artifactId>
<groupId>org.exmaple</groupId>
<version>1.0</version>
</parent>
<build>
<finalName>Bar1</finalName>
<plugins>
...
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.exmaple.bar1.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
...
</plugins>
</build>
</project>
With that running mvn package would give me all jar/war files for the modules. But to generate the jar with dependencies I have to switch into the module and trigger the assembly in addition cd Bar1; mvn assembly:single.
Is there any chance to change the setup so that after mvn package one of the jars is build with dependencies included?
Cheers.
Include the assembly plugin to the execution of the package phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
<finalName>apache-maven-cookbook-${pom.version}</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
As described on maven assembly page
You need to define an execution for the assembly plugin. Otherwise it won't be executed. The site of the plugin may be a bit misleading as there is a section on configuration which looks like yours. But if you want the execution to actually happen, you need to define it.

How to expose a dependency of a dependency in a maven project

I have a maven web application that is using a jar I created and is referenced as a dependency in my pom file.
The jar file I created has another jar file as a dependency.
When I deploy the web application, it says that a class in the dependency of the jar file I created cannot be found.
The only way to work around this was to add the dependency of the jar file as a dependency of the war file. This seems unnecessary.
Is there a way I can configure the war file to be able to see the classes defined in a dependency of a dependent jar file?
my jar pom file looks like: The dependency that has the class that can't be found is the the QRS one.
<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>group</groupId>
<artifactId>artifact</artifactId>
<packaging>jar</packaging>
<version>1.0.7</version>
<name>name</name>
<dependencies>
<dependency>
<groupId>group2</groupId>
<artifactId>QRS</artifactId>
<version>8.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
</manifest>
</archive>
</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>
my war pom looks like:
<dependency>
<groupId>group</groupId>
<artifactId>artifact</artifactId>
<version>1.0.7</version>
</dependency>
and the war plug in is configured:
<plugin>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
</dependency>
</dependencies>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warName>${project.name}-${project.version}-${env}</warName>
<webResources>
<resource>
<directory>src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<include>jboss-web.xml</include>
<include>web.xml</include>
<targetPath>/WEB-INF</targetPath>
</resource>
</webResources>
<warSourceExcludes>**/toAggregateAndRemove/**</warSourceExcludes>
<goal>war:manifest</goal>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
Maven already resolves transitive dependencies.
That it isn't indicates you're likely not doing it right: the other jar you've created should be a Maven project with its own pom, installed at least locally via mvn install, and listed as a dependency in the second project (the one that uses it).
The project using the jar only needs to specify that artifact as its dependency, the other project's dependencies will be transitively determined and included as a project dependency.
#Dave Newton has answered, this should happen by default.
A few observations from the snippets in the question - if that helps...
Packaging dependant jars as a folder of artifact project's jar.
Defining the maven war plugin jar itself as a dependency for maven war plugin - this is not required at all!
war:manifest goal in the maven war plugin configuration.
It is possible that the war:war which actually creates the war is not run.

maven embed dependency artifact code in jar

I have a multi-module maven project. I have a main "base-code" module which creates a jar of all the compiled source code in my project.
I have another module, "executable", which creates an executable jar from the same source code. To avoid duplication I want to pull the classes in from the "base-code" module.
I thought that all I had to do was make the "base-code" module a dependency of the "executable" module to do this. But I just get an empty jar. What am I doing wrong?
(my "executable" pom is below)
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.myproject/groupId>
<artifactId>myproject</artifactId>
<version>1</version>
</parent>
<artifactId>executable</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.myproject/groupId>
<artifactId>code-base</artifactId>
<version>1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>runnable</finalName>
<archive>
<manifest>
<mainClass>com.myproject.Main</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
What you are looking for is probably uber-jar: a single jar file with all embedded jar dependencies, the newly version of maven-assembly-plugin support this as one of the 4 pre-defined descriptor, check out here.
Try using maven-assembly-plugin replace your maven-jar-plugin like this:
<!-- Create single executable jar with all dependencies unpacked and embedded -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.myproject.Main</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals><goal>single</goal></goals>
</execution>
</executions>
</plugin>
Alternatively, you can also use maven-shade-plugin to do this.
Hope that helps.

Resources