Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put all required JAR files in a library folder inside the final JAR file with Maven?

I am using Maven in my standalone application, and I want to package all the dependencies in my JAR file inside a library folder, as mentioned in one of the answers here:

How can I create an executable JAR with dependencies using Maven?

I want my final JAR file to have a library folder that contains the dependencies as JAR files, not like what the maven-shade-plugin that puts the dependencies in the form of folders like the Maven hierarchy in the .m2 folder.

Well, actually the current configuration does what I want, but I am having a problem with loading the JAR files when running the application. I can't load the classes.

Here's my configuration:

<plugins>      <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-jar-plugin</artifactId>         <configuration>             <archive>                 <manifest>                     <addClasspath>true</addClasspath>                     <classpathPrefix>lib/</classpathPrefix>                     <mainClass>com.myapp.MainClass</mainClass>                 </manifest>             </archive>         </configuration>     </plugin>      <plugin>         <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-compiler-plugin</artifactId>         <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>install</id>                 <phase>install</phase>                 <goals>                     <goal>sources</goal>                 </goals>             </execution>         </executions>     </plugin>      <plugin>         <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-resources-plugin</artifactId>         <version>2.5</version>         <configuration>             <encoding>UTF-8</encoding>         </configuration>     </plugin>  </plugins> 

The project runs fine from Eclipse, and the JAR files are put in the library folder inside my final JAR file as I want, but when running the final JAR file from the target folder I always get ClassNotFoundException:

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext         at java.net.URLClassLoader$1.run(Unknown Source)         at java.security.AccessController.doPrivileged(Native Method)         at java.net.URLClassLoader.findClass(Unknown Source)         at java.lang.ClassLoader.loadClass(Unknown Source)         at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)         at java.lang.ClassLoader.loadClass(Unknown Source) Could not find the main class: com.myapp.MainClass. Program will exit. 

How can I fix this exception?

like image 757
Mahmoud Saleh Avatar asked Aug 01 '12 11:08

Mahmoud Saleh


People also ask

What is the difference between jar and library?

A JAR serves the same function an an Assembly in the C#/. net world. It's a collection of java classes, a manifest, and optionally other resources, such as properties files. A library is a more abstract concept, in java, a library is usually packaged as a JAR (Java ARchive), or a collection of JARs.

Where should JAR files go?

As of Java 6, extension JAR files may also be placed in a location that is independent of any particular JRE, so that extensions can be shared by all JREs that are installed on a system. It says that for Windows you should place your extensions here %SystemRoot%\Sun\Java\lib\ext .

Does a jar contain all dependencies?

java is a main starting point which has main(String args[]) method inside. pom. xml file in which we will add Maven Plugins which will build executable . jar project with all included dependancies.


2 Answers

The following is my solution. Test it if it works for you:

<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-jar-plugin</artifactId>     <configuration>         <archive>             <manifest>                 <addClasspath>true</addClasspath>                 <!-- <classpathPrefix>lib</classpathPrefix> -->                 <!-- <mainClass>test.org.Cliente</mainClass> -->             </manifest>             <manifestEntries>                 <Class-Path>lib/</Class-Path>             </manifestEntries>         </archive>     </configuration> </plugin> 

The first plugin puts all dependencies in the target/classes/lib folder, and the second one includes the library folder in the final JAR file, and configures the Manifest.mf file.

But then you will need to add custom classloading code to load the JAR files.

Or, to avoid custom classloading, you can use "${project.build.directory}/lib, but in this case, you don't have dependencies inside the final JAR file, which defeats the purpose.

It's been two years since the question was asked. The problem of nested JAR files persists nevertheless. I hope it helps somebody.

like image 105
gmode Avatar answered Nov 07 '22 14:11

gmode


Updated:

<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>  
like image 37
Ahmet Karakaya Avatar answered Nov 07 '22 13:11

Ahmet Karakaya