292

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.

Lii
  • 11,553
  • 8
  • 64
  • 88
Michael
  • 3,049
  • 3
  • 19
  • 5

16 Answers16

294

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>
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Georgy Bolyuba
  • 8,355
  • 7
  • 29
  • 38
116
mvn install dependency:copy-dependencies 

Works for me with dependencies directory created in target folder. Like it!

Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
user3286149
  • 1,161
  • 1
  • 7
  • 4
  • 1
    Thank you for this simple option. I used the package target instead but otherwise did what I was looking for. – jla Jul 16 '20 at 01:40
  • 8
    dont know how this is not hte accepted answer? anyway , if you want to send dependencies to specific dir, for example called 'lib' , can use `mvn dependency:copy-dependencies -DoutputDirectory=lib/` – niken Apr 23 '22 at 15:12
94

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...
informatik01
  • 16,038
  • 10
  • 74
  • 104
John Stauffer
  • 16,150
  • 10
  • 40
  • 35
43

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
isapir
  • 21,295
  • 13
  • 115
  • 116
39

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.

Travis B. Hartwell
  • 3,124
  • 21
  • 11
  • 15
    Alternatively, you could use ${project.build.directory}/lib rather than ${basedir}/target/lib – Cuga Jul 06 '10 at 14:42
35

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.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • 3
    thanks! this is the easiest way to just copy the libs that would be required by a project into a folder somewhere so you can copy them somewhere else if need be, e.g. a non maven based project. Note that of course you can just pass in a hardcoded folder to use if you like, e.g. `mvn dependency:copy-dependencies -DoutputDirectory=./lib ` – Brad Parks May 15 '15 at 13:18
  • Can you do it out of pom.xml? – Gobliins Oct 19 '15 at 14:50
34

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

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
ruhsuzbaykus
  • 13,240
  • 2
  • 20
  • 21
25

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>
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
adjablon
  • 502
  • 4
  • 9
11

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
Jeffrey Knight
  • 5,888
  • 7
  • 39
  • 49
mambolis
  • 173
  • 3
  • 6
5

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>
John Topley
  • 113,588
  • 46
  • 195
  • 237
Rich Seller
  • 83,208
  • 23
  • 172
  • 177
4

If you make your project a war or ear type maven will copy the dependencies.

Eduard Wirch
  • 9,785
  • 9
  • 61
  • 73
3

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>
Community
  • 1
  • 1
RubyTuesdayDONO
  • 2,350
  • 2
  • 25
  • 37
  • 2
    Your code example doesn't solve the problem, it just bundles everything into a single JAR. Yes, the assembly plugin can be used to achieve this goal, but not like this. – Duncan Jones Aug 22 '14 at 07:00
  • Although, on further reading, maybe you are responding to [this comment](http://stackoverflow.com/questions/97640/force-maven2-to-copy-dependencies-into-target-lib/25441276#comment15792_97640). – Duncan Jones Aug 22 '14 at 07:01
  • it's been so long that i don't really remember … plus i've gotten rather rusty since focusing on Linux administration at my last firm — but thank you for the feedback! – RubyTuesdayDONO Aug 22 '14 at 18:54
1

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

OleVV
  • 11
  • 1
1

You can use the the Shade Plugin to create an uber jar in which you can bundle all your 3rd party dependencies.

Brian Matthews
  • 8,506
  • 7
  • 46
  • 68
0

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.

Community
  • 1
  • 1
0

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.

times29
  • 2,782
  • 2
  • 21
  • 40