-1

I am new to maven. I have created a maven project which will be packaged to JAR. I did clean package then jar is created. When i extracted the same jar, i could not see any dependencies (jars) i added in pom.xml inside the packaged jar. If i give this jar to third party clients how will the code work without any dependent jars ? Please help me how maven manages the jars?

Thanks!

user755806
  • 6,565
  • 27
  • 106
  • 153
  • Possible duplicate of: [How can I create an executable jar with dependencies using Maven?](http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven) – Ryan J Jul 16 '14 at 06:43
  • Ryan, am not asking how to create an executable jar file. When i packaged, the jar did not have any dependencies in it. I just asked how maven manages them ? – user755806 Jul 16 '14 at 06:45
  • Did you go to the link? It specifically answers how to make a jar that you can give to people, with your dependencies. Maven manages them by putting them in a 'dependency' folder when you package (which can be overridden in the plugin) and you're responsible for then figuring out how to distribute them. – Ryan J Jul 16 '14 at 06:46
  • This might shed some light: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html – mike Jul 16 '14 at 06:48
  • when i packaged, i dont see any dependencies folder? – user755806 Jul 16 '14 at 06:49
  • If i give the jar file to third party, again does third party app will get all the dependencies downloaded based on the pom file in the packaged jar ? – user755806 Jul 16 '14 at 06:50

3 Answers3

0

Maven handles dependencies based on how you configure the dependency plugin.

See this reference for a simple example of how to do this.

In this example, the following code configures where your dependencies will end up:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.5.1</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <includeGroupIds>log4j</includeGroupIds>
                <outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

Then this code sets up the classpath for your main jar, which will allow anyone running it to find these dependencies

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <mainClass>com.mkyong.core.App</mainClass>
            <classpathPrefix>dependency-jars/</classpathPrefix>
          </manifest>
        </archive>
    </configuration>
</plugin>

Your other option would be to create a single jar, with all dependencies included, by following this example here

You could distribute the jar and the POM file if you want to try and provide your users with the files in that manner, but they'd need to be able to access your Maven repository where those dependencies are kept.

Community
  • 1
  • 1
Ryan J
  • 8,275
  • 3
  • 25
  • 28
0

Core maven doesn't handle this. Maven is a build tool, its work is to build an artifact (a jar in your case). Dependencies you define in your module's pom.xml file are needed to get the code compiled. You'll need maven plugins to do so.

Now, you're asking not about the build, but the distribution of your compiled binaries.

If I understand it should be a lot of jars (your and your dependencies). Alternatively you may distribute the code as a jar + dependencies inside.

Example:

A first case:

If your code resides in module A (say, the code is in packages org.a.*) and depends on some thirdparty (say, log4j, whose classes reside in org.apache.log4j) than you can expect that you jar will only contain the classes of module a and you expect that the log4j will be added by the user of your module automatically (The first case).

A second case:

module a.jar will contain both org.a.* and org.apache.log4j.* classes, everything in the same module.

In general the first approach is more "healthy" and in this case you shouldn't do anything in maven. Maybe your distribution tool/documentation should contain this information. If someone uses the module a in his/her code like a thirdparty (if you develop a framework or something) and if his/her project is mavenized, than the fact you've defined a dependency on log4j will make the maven to download the log4j as well as your a.jar (In maven notation, this is called "transitive dependencies").

If you're interested in the second case (this can be relevant if you define some "client application", like "jndi client for some server" for example) you might want to take a look on Maven shade plugin

Beware this can lead to dependency hell (what if the application that uses your client also makes use of log4j? what if the log4j-s are of different version)/

Bottom line, you probably want the first approach, think twice before you decide the second approach :)

One more tip, if you just want to download all the dependencies of your module "a" you might want to use maven dependency plugin - type the following in the command prompt

 mvn dependency:copy-dependencies

and you'll find all the dependencies in target/dependencies folder

Hope this helps and happy mavening

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • dependency:copy is not the right way, better use the described way via maven-assembly-plugin. Apart from that if you like to compile code in Maven this is also handled by a plugin (maven-compiler-plugin) creating a jar file is also handled by a plugin (maven-jar-plugin) etc. Maven itself is a IoC container which calls plugins etc. – khmarbaise Jul 16 '14 at 09:46
0

The simplest solution to the problem is to use the maven-assembly-plugin which can create such jar with dependencies like the following:

 <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <executions>
          <execution>
            <id>distro-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Afterwards you can distribute the created jar xyz-1.0-jar-with-dependencies which contains the defined dependencies.

If you need more control on how the resulting artifact is created or if some files needed to be overwritten etc. you might take a deeper look into maven-shade-plugin

khmarbaise
  • 92,914
  • 28
  • 189
  • 235