Solved

How to include jars in a package (.jar) using Maven?

Posted on 2011-03-08
19
858 Views
Last Modified: 2012-05-11
Hi,
I have a simple Java code that connects to server a updates a field in the object and exits.

Here is my code:

package com.mywork.tools.GeckoPrequal;

import com.mywork.tools.GeckoPrequal.ws.*;
import java.util.*;
import java.lang.*;


class myfirstjavaprog
{  

        public static void main(java.lang.String args[])
        {
        	java.lang.String soapEndpointURL="http://SOMEPATH/main/WebService";
		
			   try {
					GeckWebServiceSoapBindingStub stub = new GeckWebServiceSoapBindingStub(new java.net.URL(soapEndpointURL), new org.apache.axis.client.Service());
					
					Geck g = stub.lockGeck(java.lang.Integer.parseInt(args[0]),args[1]);
					
					System.out.println(g.getSolution());
					java.lang.String solution = g.getSolution();
					solution = solution.concat(args[2]);
					
					System.out.println(solution);
					g.setSolution(solution);
					
					stub.saveGeck(g,args[1]);
					
				  } catch(Exception e) {
					System.out.println(e.getMessage());
				  }	
        }
}

Open in new window


To compile this code I use Maven due to some internal reason.

Here are the commands I use to run the program:

mvn clean

mvn package

setenv CLASSPATH `pwd`/target/GeckoPrequal-2.0.jar:/opt/glassfish/lib/javaee.jar:/home/tolgar/.m2/repository/axis/axis/1.4/axis-1.4.jar:/home/tolgar/.m2/repository/org/apache/axis/axis-jaxrpc/1.4/axis-jaxrpc-1.4.jar:/home/tolgar/.m2/repository/org/apache/axis/axis-saaj/1.4/axis-saaj-1.4.jar:/home/tolgar/.m2/repository/axis/axis-wsdl4j/1.5.1/axis-wsdl4j-1.5.1.jar:/home/tolgar/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:/home/tolgar/.m2/repository/commons-discovery/commons-discovery/0.2/commons-discovery-0.2.jar

java com.SOMEDOMAIN.tools.GeckoPrequal.myfirstjavaprog 333333 tolgar sometext

Open in new window



Everything works fine and I can update the solution field with "sometext" as the 3rd input argument.

Now my question is:

I want to put this program in a package (.jar) with the jar files that I add to CLASSPATH as I showed above. Then the users will not need to do anything other than just running the following command:

java com.SOMEDOMAIN.tools.GeckoPrequal.myfirstjavaprog 333333 tolgar sometext

Open in new window



Can you please give me step by step instructions on how to make it?

Thanks,
0
Comment
Question by:Tolgar
  • 11
  • 8
19 Comments
 
LVL 92

Expert Comment

by:objects
ID: 35074110
you can use the maven archiver to create an executable jar
http://maven.apache.org/shared/maven-archiver/examples/classpath.html#Make

you'll then run it with


java -jar my.jar 333333 tolgar sometext
0
 

Author Comment

by:Tolgar
ID: 35074465
Thank you for your quick reply.

I added the following lines into my pom as referred in the Maven documentation:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.SOMEDOMAIN.tools.my.myfirstjavaprog</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>

Open in new window


Then ran the following commands:

mvn clean

mvn package

Open in new window


When I look at the target directory I can see that the my.jar file was created.

Then I go to command line and typed:

java -jar my.jar 333333 tolgar sometext

Open in new window


And I got the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/rpc/Service
Caused by: java.lang.ClassNotFoundException: javax.xml.rpc.Service
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: com.SOMEDOMAIN.tools.my.myfirstjavaprog. Program will exit.

Open in new window


I remember this error before I wanted to create this jar. I fixed this kind of errors by doing setenv CLASSPATH to certain jar files. I guess while creating the jar file these jar files are not included in it.

As I showed you above they do not locate inside this project folder. They are mostly under the following directory:

/home/tolgar/.m2/repository/


Do you know a way of making these part of the .jar file? One idea can be to copy them under the project. But into which directory should I put these jars?

Thanks,
0
 
LVL 92

Expert Comment

by:objects
ID: 35074498
try putting them in the same directory.
you can check the manifest for the jar to see where it is lookinmg for them
0
 

Author Comment

by:Tolgar
ID: 35074945
First, I tried to put these 8 jar files in the following directory:

src\main\resources

I got the same error.

Then I put it with the same directory as my java code. The error message did not change.

The manifest file inside the generated jar looks like this:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: tolgar
Build-Jdk: 1.6.0_20
Main-Class: com.SOMEDOMAIN.tools.my.myfirstjavaprog
Class-Path: commons-lang-2.5.jar jung-api-2.0.1.jar collections-generi
 c-4.01.jar jung-graph-impl-2.0.jar jung-io-2.0.1.jar jung-algorithms-
 2.0.1.jar colt-1.2.0.jar concurrent-1.3.4.jar wstx-asl-3.2.6.jar stax
 -api-1.0.1.jar jung-jai-2.0.1.jar jung-visualization-2.0.1.jar json-s
 imple-1.1.jar mysql-connector-java-5.1.12.jar jaxb-api-2.0.jar jsr173
 _api-1.0.jar activation-1.1.jar axis-1.4.jar axis-jaxrpc-1.4.jar axis
 -saaj-1.4.jar axis-wsdl4j-1.5.1.jar commons-logging-1.0.4.jar commons
 -discovery-0.2.jar jaxb-impl-2.0.2.jar

Open in new window



Do you have an idea why I am still getting this error?

Thanks,
0
 
LVL 92

Expert Comment

by:objects
ID: 35075047
they need to be in the same directory as you are running it from.
0
 

Author Comment

by:Tolgar
ID: 35075191
I am really sorry but I did not understand what you mean by saying the same directory as I am running it from.

I am running the jar file which is in the target directory. But these jars should be somewhere under src. And they will be embedded into the jar during packaging.

Can you please explain bit a little bit in detail?

Thanks,
0
 
LVL 92

Expert Comment

by:objects
ID: 35075205
put all the jars (including the application jar) in one directory
then try and run it from there
0
 

Author Comment

by:Tolgar
ID: 35075439
I put them all in the same place and I got this error:
Exception in thread "main" java.lang.NoClassDefFoundError: org.apache.commons.logging.LogFactory
        at org.apache.axis.components.logger.LogFactory.class$(LogFactory.java:45)
        at org.apache.axis.components.logger.LogFactory$1.run(LogFactory.java:45)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.apache.axis.components.logger.LogFactory.getLogFactory(LogFactory.java:41)
        at org.apache.axis.components.logger.LogFactory.<clinit>(LogFactory.java:33)
        at org.apache.axis.description.OperationDesc.<clinit>(OperationDesc.java:65)
        at com.mywork.tools.GeckoPrequal.ws.GeckWebServiceSoapBindingStub._initOperationDesc1(GeckWebServiceSoapBindingStub.java:29)
        at com.mywork.tools.GeckoPrequal.ws.GeckWebServiceSoapBindingStub.<clinit>(GeckWebServiceSoapBindingStub.java:20)
        at com.mywork.tools.GeckoPrequal.myfirstjavaprog.main(myfirstjavaprog.java:16)

Open in new window



I again remember this error message before using setenv CLASSPATH. Then I used CLASSPATH with the jar files and the problem was solved. It looks like it cannot see one the jars again.

I basically copied the my.jar file and the following jar files into one separate directory and ran the same command.

The jar files are:

axis-1.4.jar
axis-jaxrpc-1.4.jar
axis-saaj-1.4.jar
axis-wsdl4j-1.5.1.jar
commons-discovery-0.2.jar
commons-logging-1.1.1.jar
javaee.jar

I think it still cannot see one or more of these jars. Because it works fine when I put them in the class path.

0
 
LVL 92

Expert Comment

by:objects
ID: 35075731
thats not all the jars that are listed in the manifest, do you not need the others?

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Tolgar
ID: 35077071
Actually I don't know. I didn't create the manifest by myself. And I don't know where these jars locate.

So do you mean I also need to put the jars in the manifest in the same directory?

Thanks,
0
 
LVL 92

Accepted Solution

by:
objects earned 500 total points
ID: 35077210
> commons-logging-1.0.4.jar

the manifest is looking for a different version than you have
0
 

Author Comment

by:Tolgar
ID: 35077811
Awesome!!!

 It worked. Thank you for your continuous help on this issue.

I appreciate
0
 

Author Comment

by:Tolgar
ID: 35077865
One last question.

I am going to give this code to other people. And I don't want to give the library jar and the my.jar separately.

 Is there a way of combining these two into one jar file and call it as a package?

Thanks,
0
 
LVL 92

Expert Comment

by:objects
ID: 35077907
there are a few products around eg. fat jar http://one-jar.sourceforge.net/

simply though to just zip up all the jars and have them unzipped when installed.
0
 

Author Comment

by:Tolgar
ID: 35083577
I have found something that may help to create one jar file in Maven. It says:

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.

This is the link to the page:

http://stackoverflow.com/questions/97640/force-maven2-to-copy-dependencies-into-target-lib

But when I put the following in my pom.xml it gave me the same error again.

<assembly>
		<id>jar-with-dependencies</id>
		<formats>
			<format>jar</format>
		</formats>
		<includeBaseDirectory>false</includeBaseDirectory>
		<fileSets>
			<fileSet>
				<directory>target/classes</directory>
				<outputDirectory>/</outputDirectory>
			</fileSet>
		</fileSets>
		<dependencySets>
			<dependencySet>
				<outputDirectory>/</outputDirectory>
				<unpack>true</unpack>
				<scope>runtime</scope>
			</dependencySet>
		</dependencySets>
</assembly>

Open in new window



The only thing that I want is to copy all the jars that is required (they are declared in the manifest file) into one jar including the application itself.

Can you please explain me how I can make it work?

Thanks,
0
 

Author Comment

by:Tolgar
ID: 35083815
I also tried the following in pom.xml:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <id>copy</id>
            <phase>compile</phase>
            <goals>
              <goal>copy</goal>
            </goals>
            <configuration>
              <artifactItems>
                <artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>javaee.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>axis-1.4.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>axis-jaxrpc-1.4.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>axis-saaj-1.4.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>axis-wsdl4j-1.5.1.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>commons-logging-1.0.4.jar</destFileName>
                </artifactItem>
				
				<artifactItem>
                  <!-- Artifact gets loaded from repository at build time. -->
                  <groupId>com.mywork.tools.GeckoPrequal</groupId>
                  <artifactId>GeckoPrequal</artifactId>
                  <version>2.0</version>
                  <type>jar</type>
                  <!-- Per artifact configuration here: -->
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/lib</outputDirectory>
                  <destFileName>commons-discovery-0.2.jar</destFileName>
                </artifactItem>
				
				
              </artifactItems>
              <!--
              <outputDirectory>${project.build.directory}/lib</outputDirectory>
              -->
              <overWriteReleases>false</overWriteReleases>
              <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
          </execution>
        </executions>
      </plugin>

Open in new window


When I run:

mvn clean

Open in new window


it did fine. But when I say:

mvn package

Open in new window


I got the following error:

Embedded error: Unable to download the artifact from any repository

Try downloading the file manually from the project website.

Then, install it using the command:
    mvn install:install-file -DgroupId=com.mywork.tools.GeckoPrequal -DartifactId=GeckoPrequal -Dversion=2.0 -Dpackaging=jar -Dfile=/path/to/file

Alternatively, if you host your own repository you can deploy the file there:
    mvn deploy:deploy-file -DgroupId=com.mywork.tools.GeckoPrequal -DartifactId=GeckoPrequal -Dversion=2.0 -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]


  com.mywork.tools.GeckoPrequal:GeckoPrequal:jar:2.0

from the specified remote repositories:
  central (http://repo1.maven.org/maven2),
  java.net (http://download.java.net/maven/1),
  jung.cvs.sourceforge.net (http://jung.cvs.sourceforge.net/viewvc/jung/jung2/)

Open in new window



Can you please help me to fix this issue?

Thanks,
0
 

Author Comment

by:Tolgar
ID: 35085301
Any idea??
0
 
LVL 92

Expert Comment

by:objects
ID: 35089445
you appear to be adding the artefact you are building as a dependency. why are you doing that?
0
 

Author Comment

by:Tolgar
ID: 35090571
Actually we can close this question. Because your last solution helped me a lot. And it is not really required to put them in one jar. Placing all jar in one directory works fine for me.


Thank you so much
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
java continue statement 10 72
count8 challlenge 13 85
ArrayLists in ArrayLists/HashMaps? 4 39
word0 challenge 3 56
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now