I've got a project that is structured liked so:
root/
-- lib/
---- commons-cli-1.2.jar
-- src/
---- my/package/name/*.java
-- bin/
---- my/package/name/*.class
-- .classpath
-- .project
-- manifest.mf
The *.class files in bin/ are made by Eclipse each build. My .classpath has the lib/ included and compiles just fine; it also runs as a "Java Application" just fine with my current stubs.
The issue comes about when I try to create a JAR and include the lib/ dependencies. From the command line I've been issuing:
jar cvfm prog.jar manifest.mf -C bin/ .
The program builds, and then when I try to run java -jar prog.jar, I get:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/Option... (there is more, but I cant copy from the other machine)
My manifest.mf looks like:
Manifest-Version: 1.0
Main-Class: my.package.Main
Class-Path: ./lib/commons-cli-1.2.jar
Seems to me that the Class-Path isn't being included and the JAR cannot find the classes contained in the commons-cli-1.2.jar. I've isolated this to JAR creation, since I can run the compiled classes with no issue.
What am I doing wrong when creating the JAR and including the lib/*.jar?
I have had issues with specifying classpath in the manifest file before. If I were you, I would skip referencing the required libraries in the manifest file and instead include them directly inside your jar. Eclipse allows you to easily do this link
You probably assume that the build process should pull the commons JAR into the new that holds your classes. Wrong assumption.
The default Java approach is that you only include your classes in your jar. But instruct your users that they need to have the commons jar in their class path as well!
Related
So I'm trying to compile my game for my Object-Oriented Programming class into a jar file so it can be ran with java -jar javacoffeeadventure.jar.
My folder structure for a folder with java files removed looks like this:
audiomanager/
commandinterpreter/
gamemanager/
io/
logic/
META-INF/
player/
resources/
rooms/
main.class
Everything is packaged under javacoffeeadventure. For example, the main file is javacoffeeadventure.main. The META-INF folder contains one MANIFEST.MF file that I tried to edit and make the jar invoke main.class's main() method:
Manifest-Version: 1.0
Created-By: 1.8.0_60 (Oracle Corporation)
Main-Class: javacoffeeadventure.main
I know I use jar to compile into a jar file, but how would I use that command to create a jar file that is able to begin with javacoffeeadventure.main? Is my manifest wrong?
as a slight by-the-way, jar puns are funny to me if you guys have any. :)
In my experience, the following has worked, but if you utilize it, you may need to adapt your directory structure.
First, your folder structure needs to be of the form 'containing_folder.com.example.package', where your classes are in the 'package' folder. You need to then place your manifest.mf file in the uppermost directory ('folder'). The manifest file should be as follows:
Manifest-Version: 1.0
Main-Class: com/example/package/javacoffeeadventure
including a carriage return after the second line.
From the initial folder compile with the following command:
jar cmvf manifest.mf javacoffeeadventure.jar com/example/package/*.class
making sure that beforehand you've compiled the classes in your package (use *.java)
Hope this helps.
I'm working on a project where I need to compile .java files 'automaticly'(So not using Eclipse)
And now I have some trouble with the libraries that are required by the sources that I compile.
The problem is that the compiled code extends a class which is inside a library.
I've added classpaths, and made sure the libraries where actually in the correct directory.
But it doesn't seem to be able to run.
I get an error which says that the class can not be found or loaded.
I modified the test source so that it doesn't extend. And then it does work.
How do I make the compiled class be able to actually use the classes from libraries in the class path?
I use this to compile:
javac -d /bin -cp kit.jar src/com/indieveloper/kittest/*.java
The class files compile with no error, and also in the correct package hierarchy
This is the manifest:
Manifest-Version: 1.0
Class-Path: .;lib/kit.jar
Created-By: Me
Main-Class: com.indieveloper.kittest.Main
The folder lib with the jar is in the same folder where the final packed .jar also ends up
Which I build using this code:
jar cvfm test.jar manifest.txt -C bin/ .
The inside of the final jar seems okay to me:
META-INF/
META-INF/MANIFEST.MF
com/
com/indieveloper/
com/indieveloper/kittest/
com/indieveloper/kittest/Main.class
The manifest is still correct(Nothing changed the manifest during 'jarring')
I also tried putting the lib folder with the jar inside the final jar, but that was a hopeless attempt..
The exact error:
java -jar test.jar
Error: Could not find or load main class com.indieveloper.kittest.Main
Does anyone know I can do to make it work?
I have created my JAR on Windows 2000 having java version 1.5 which contains following directories/files:
manifest.txt
com
lib
lib contains all JARS which I want to make part of my JAR. com contains my class files and below is manfiest.txt file
Main-Class: com.as.qst.result.ResultTriggerSchedular
Class-Path: lib/axis.jar lib/c3p0-0.9.1.1.jar lib/commons-discovery-0.2.jar lib/commons-logging-1.0.4.jar lib/jaxrpc.jar lib/log4j-1.2.16.jar lib/medplus-hub-8.2-wsclients.jar lib/medplus-hub-13.1-jaxws-clients.jar lib/quartz-2.2.1.jar lib/quartz-jobs-2.2.1.jar lib/saaj.jar lib/slf4j-api-1.6.6.jar lib/slf4j-log4j12-1.6.6.jar lib/ wsdl4j-1.5.1.jar lib/xercesImpl.jar com\as\qst\result
I used following command to generate my JAR
jar cvfm test.jar manifest.txt com lib
It has successfully created a JAR file but when I try to run it with
java -jar test.jar
it does not execute and throws above exception. I used the same process for Windows 7 which has version 1.7 and it did work out even without class files path in manifest.txt com\as\qst\result. Is something more to do with class-path besides defining in manifest? and why is it working in Windows 7?
You do not need the class file path in your class path entry. So instead of adding com\as\qst\result to your class-path.
More over you must not package other jar files in your runnable jar.
Other required jars must be provided in the same folder as your jar file (may be in separate folder) and Add current directory "." (without quotes) to your class-path.
Hope this helps.
EDIT
Just found this Stackoverflow Link. This might give you more insight. Please read through it.
I have two jar files, A.jar and B.jar. A contains my main function and it relies on classes defined in B.
I put A and B in the same folder, which is in the Windows PATH, and try and run my main in A...
java -jar A.jar -dosomething
This gives me a java.lang.NoClassDefFound error on a method of B that I call in the code underneath -dosomething. Interestingly it has found A.jar and called the main method, but it can't find B.jar, even though it is in the same folder as A.jar.
So I read around (again) about CLASSPATHs and the JAVA_HOME variable and I made sure that my JAVA_HOME is pointing to the right place. This document describes how I should be able to put my extension jar file(s), in my case B, into the /lib/ext folder, so I tred that, but I get the same java.lang.NoClassDefFound error.
I am using Java jdk1.5.0_10, so for good measure I also placed B.jar in the jre/lib/ext folder underneath there.
So now I have it in three places, the local folder on the PATH, JAVA_HOME/lib/ext and JAVA_HOME/jre/lib/ext and I still get the same error.
Should using lib/ext work? Where on earth have I got to put my B.jar file for this to work properly?
JAVA_HOME is not a environment variable used by Java. It's used by other tools such as Ant, but not by Java.
The PATH environment variable is not used by Java either. It's used to find executables in windows, but Java doesn't use it to find jars.
Placing two jars in the same directory doesn't make them automatically in the same classpath. If A.jar is an executable jar (as it seems to be), and it depends on an external B.jar, then its Class-Path entry of its manifest must reference B.jar. Read http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
You need to add a manifest file to your A.jar file like this.
The contents of the manifest file should look like this, where the Main-Class points to your package name and the class name of your main class in A.
Save this in a file named something like Manifest.mf
Manifest-Version: 1.0
Main-Class: com.your.package.name.A
Class-Path: A.jar B.jar
You can manually add this file to your jar by changing your .jar file to a .zip then opening it and modifying the contents of the existing manifest file if there is one or copying the Manifest.mf file into your jar/zip file and changing it back to a .jar file.
You need to have a Manifest file to be able to call classes from another jar. Check this link
I would consider using a build system like Ant or Maven, my personal preference is for Maven. Most have plugins to take care of the complex classpath / dependency issue - in Maven, that's the Shade plugin.
I would do Hello World with a Maven example. Most modern IDEs (IDEA, Eclipse, NetBeans) can generate projects from a pom.xml.
http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
To make executable-jar file you need to add a manifest file which contains the Main-class name and other dependent class paths.
Manifest.txt
Main-class: A
Class-Path: B.jar
Add this manifest file into A.jar
cmd:/folderLocation>jar cvfm A.jar manifest.txt A.class
place both jars in one folder and run A.jar using cmd java -jar A.jar
I saw running jar from command line.
However my case is different. I put the jars needed for the main class under lib folder. So my jar is like this:
lib
META-INF
VideoFieldsResults.class
in the META-INF I have:
Manifest-Version: 1.0
Main-Class: VideoFieldResults
when I try to run:
java -jar VideoFormat.jar onBa32hgnBg,Lh-BKkLYYBU C:\VideoFormat2.csv
Where the last 2 are arguments I get:
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gdata/util
/ServiceException
Which does exists under one of the jars inside!
How can I run a command line specifying that all the jars under lib folder inside are required for the jar?
By default, Java cannot load jars from within jars. To accomplish this, you would need a classloader that can handle it. For example One-Jar. There are other options as well (depending on how set you are with including jars inside of a jar or if flattening jars is an option), I'd recommend the answer to this other question