link GetOpt to main jar - java

I have a folder gnu\getopt contains Getopt.class which is need by ChatDemo.jar for parser argument parameters, when I ran with java -cp xSocket.jar;. ChatDemo.jar it produce:
Exception in thread "main" java.lang.NoClassDefFoundError: gnu/getopt/Getopt
at ChatDemo.main(ChatDemo.java:24)
Caused by: java.lang.ClassNotFoundException: gnu.getopt.Getopt
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)
... 1 more
ChatDemo.java:
import gnu.getopt.Getopt;
ChatDemo Manifest:
Manifest-Version: 1.0
Created-By: 1.6.0_22 (Sun Microsystems Inc.)
Main-Class: ChatDemo
Class-Path: xSocket.jar

Run it with java -classpath "xSocket.jar;.;ChatDemo.jar ChatDemo (no .jar after the name of the main class).
Note that you must add the folder which contains "gnu" to the classpath. Another solution is to put the getopt classes in a JAR and add that to the classpath. Make sure that the folder structure (gnu\getopt) is preserved.

It looks like you are mixing up the two ways of running java. You should either supply a classpath (e.g. using the -cp argument), or launch from a JAR file. You cannot do both.
If you launch using a JAR file, the -cp argument is ignored. In that case, you must specify the complete classpath in the JAR file's manifest.
The manifest in the ChatDemo.jar file apparently doesn't include. You can remedy this in two ways:
Update the manifest classpath to be "Class-path: xSocket.jar ." ... note we use a space to separate the entries here, not ; or :.
Add Getopt.class to the JAR file as gnu/getopt/Getopt.class.
However, if you launch using a JAR file you have to use the -jar option. If you try to your application like this:
java -cp xSocket.jar;. ChatDemo.jar
it will fail telling you that it cannot find a class called ChatDemo.jar ; i.e. it will misinterpret the JAR filename as a qualified classname.

Add Main-Class - as fully qualified (I mean as per package structure) class name of your class which contains main method.

Related

Java: NoClassDefFoundError: org/json/JSONException

So, I've spent the whole day with this problem.
I'm sure, that I'm using correct classpath.
Also, I have other packages as dependences, and they work perfectly.
I have a class that uses org.json.*
Also there are some other outer packages used in this class.
All this dependences are placed as jar files in my /path/to/libs/.
json-20160212.jar is among them.
I'm compiling my sources with
javac \
-cp "src/:/path/to/libs/json-20160212.jar:/path/to/libs/other.jar:/path/to/libs/another.jar" \
-d dst/ \
src/com/example/Source.java
Compilation goes without issues.
Then, I'm creating jar from my class-files.
Manifest:
Main-Class: com.example.Source
Class-Path: /path/to/libs/json-20160212.jar
/path/to/libs/other.jar
/path/to/libs/another.jar
Command line:
jar cfm output.jar manifest -C dst/ ./com
I'm getting jar with this manifest:
Manifest-Version: 1.0
Class-Path: /path/to/libs/json-20160212.jar /path/to/libs/other.jar /p
ath/to/libs/another.jar
Created-By: 1.7.0_101 (Oracle Corporation)
Main-Class: com.example.Source
As I've understood, this is ok for compiled manifest to have splitted lines.
Now, I'm running my app from command line and get this error:
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: org/json/JSONException
at com.example.Source.run(Source.java:30)
Caused by: java.lang.ClassNotFoundException: org.json.JSONException
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 1 more
As I know, that means, that org.json.JSONException was ok at compile time but missing at run time.
But what must I do with this info?
I have that file. It was at its place during compilation and at runtime.
Also there are other dependences, and their jars are also at that place.
If I remove JSON usage from my app, everything is working ok.
So, I can make conclusion, that it is the package org.json itself, that makes the problem.
What must I do, to make it work?
UPDATE
Now, I've made this changes:
My directory structure:
libs/
json-20160212.jar
other.jar
another.jar
src/
com/
example/
Source.java
dst/
Manifest:
Main-Class: com.example.Source
Class-Path: libs/json-20160212.jar
libs/other.jar
libs/another.jar
Compilation:
javac \
-cp "src/:libs/json-20160212.jar:libs/other.jar:libs/another.jar" \
-d dst/ \
src/com/example/Source.java
Jarchiving:
jar cfm dst/output.jar manifest -C dst/ ./com ./libs
I'm getting jar with the structure as excepted:
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/Source.class
libs/
libs/json-20160212.jar
libs/other.jar
libs/another.jar
And I'm running it with java -jar dst/output.jar.
Result is the same: java.lang.NoClassDefFoundError: org/json/JSONException
The problem is your runtime classpath. There's no magic with this error. It quite simply means that org.json.JSONException is not on your runtime classpath. Find the jar that has this class in it and put it on your runtime classpath.
Note that the jars / classes needed for runtime are not necessarily the same as those needed for compiling. You quite often need more on your runtime classpath than your compile classpath. If JSONException isn't used explicitly in the code you are compiling, then it won't have to be on your compile classpath. However, if one of the dependencies to your code needs JSONException and it's not on your runtime classpath, you will get a NoClassDefFoundError.
One other issue that can possibly occur is that you have 2 different versions of the json jar on your classpath. Usually the first version of the class on the classpath gets loaded and the other ignored. If the first jar didn't have the version / signature of JSONException you needed in it but the second did, the correct class you would still get ignored, since it was further down on the classpath.
The issue would appear to be that you are not adding the dependent jars to your resultant jar.
I have created a similar test jar, with the following structure (checking using jar tf)...
META-INF/
META-INF/MANIFEST.MF
BeanIt.class
TestBean.class
lib/
lib/opencsv-3.7.jar
lib/commons-lang3-3.4.jar
My manifest...
Main-Class: BeanIt
Class-Path: lib/opencsv-3.7.jar lib/commons-lang3-3.4.jar
In order to create this jar, you need to perform a command something similar to this...
jar cfm App.jar MANIFEST.MF BeanIt.class TestBean.class lib
You can see that I've added my lib folder to the jar and referred to its contents on the classpath in the manifest.
So, you can update your existing lib, like this...
jar uf App.jar path
Where path is the root path of your path/to/lib directory. And it will simply add that to your jar.
You can check your jar first using jar tf, to see what it contains.
If you are still having difficulties getting it to work, then you can look at a "FAT JAR" solution whereby you expand all the internal jars classes and flatten them all out to a single JAR containing all the necessary classes. They use decision mechanisms to deal with class conflicts in different JARs. Tools such as sbt-assembly or OneJar may be what you need here, if you are unable to get your JAR working the way you expect.
So, the solution:
As I've understand, the only way to access the content of the jar files that are inside your jar, is to write your own class loader.
Without it, jar files must be extracted and that extracted content must be included to output.jar.

Unable load jar from my jar: NoClassDefFoundError

I have this jar:
/weekly/
/database.class
/report.class
/META-INF
/MANIFEST.MF
The MANIFEST.MF
Manifest-Version: 1.0
Main-Class: weekly.report
Class-Path: /root/java
In this jar i used two external jar files, postgresql-9.1-901.jdbc4.jar, javax.mail.jar. I also put those into /root/java.
but when i run it use
java -jar weekly.jar
It shows those two jars class can't find
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/internet/AddressException
Caused by: java.lang.ClassNotFoundException: javax.mail.internet.AddressException
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)
even i try to put those two jars to my $CLASSPATH
/usr/java/jdk1.6.0_21/lib:/usr/java/jdk1.6.0_21/jre/lib
It also shows same error result. I can successfully run it in my Mac, but when i try to remove it to my server CentOS system ,it shows those NoclassDefFounderror.
Finding a JAR file using a classpath is similar to finding a package
file in a classpath. The difference is that when you specify a path
for a JAR file, you must include the name of the JAR file at the end
of the path.
So you can try something like this:
java -classpath /usr/java/jdk1.6.0_21/lib/javax.mail.jar:/usr/java/jdk1.6.0_21/jre/lib/postgresql-9.1-901.jdbc4.jar -jar weekly.jar
Another option is to put your jars into jre/lib/ext (but I don't think it's a good idea)

Error while running jar file on system

I am having a java file like the following:
import org.xBaseJ.DBF;
import org.xBaseJ.fields.CharField;
import org.xBaseJ.fields.NumField;
import org.apache.log4j.*;
public class Example2 {
public static void main(String args[]){
..........
}
}
I have created the this to 'Example2.jar' file to run by following the steps below:
1) javac Example2.java
2) java Example2
3) This will produce a .class file needed for the JAR file.
4) Next create a manifest file (saved using the extension .txt) using the text editor and input the following
Main-Class: Example2
or whatever your file's name is.
5) Next create the JAR file using this code:
jar cfe Example2.jar Example2 Example2.class
After step 5, I got a jar file named 'Example2.jar' . I tried to run the jar file using the following command:
java -jar HelloWorld.jar
But I am getting the following Errors:
Exception in thread "main" java.lang.NoClassDefFoundError: org/xBaseJ/DBF at Example2.main(Example2.java:14) Caused by: java.lang.ClassNotFoundException: org.xBaseJ.DBF at java.net.URLClassLoader$1.run(URLClassLoader.java:372) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 1 more
I did not understand, what is the reason? Please guide me?
Well one thing is that when u are creating Jar just look this menifest first that is what can help for the including the External Libraries.
http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html
While creating and giving chages to the menifest just have to run that class with the configuration
http://docs.oracle.com/javase/tutorial/deployment/jar/modman.html
so seeing both of that link.
just look this Example.
run your java and get class file
javac Test.java
and if u having some other external libraries working then do like this.
javac -classpath xxx.jar Test.java
and see the menifest configuration and make that file with external changes like this.
menifest.txt
Main-Class: Test
Class-Path: xxx.jar xxxx.jar
then u need to make jar file like this.
run this command
jar cfm jarName.jar manifest.txt Test.class
and hence we done u can have jarfile in that same path.
The error you're seeing is caused by having an incorrect classpath. I'm assuming that when you compiled the class, you somehow provided a classpath (either by passing the '-classpath' arg or by setting the 'CLASSPATH' environment variable). The problem is that the compilation classpath is separate from the runtime classpath. So, you just need to ensure that all of the dependencies (other jar files, most likely) that were on the classpath when you compiled the class are also added to the classpath when running the jar. For a jar file, this is typically done by adding a 'Class-Path'header to the manifest.
An alternative method would be to specify the classpath using either the command line arg or the environment variable and include your Example2.jar file in that classpath, and run java Example2 (without the '-jar').

Why edit to Manifest file provides solution that CLASSPATH does not

I'm writing a short utility that performs a short task on a remote Oracle instance. The utility uses the Oracle jdbc driver found in ojdbc6.jar.
The Oracle jar is properly included in my classpath. When I export my project to a jar and run the jar on the command line using "java -jar ", I get:
Exception in thread "main" java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver
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)
at java.lang.Class.forName0(Native Method)
After moving the Oracle jar into the same directory as my runnable jar file, I changed my Manifest file to include the the Oracle jar in the classpath. This fixed the problem, and my jar ran fine.
Can anyone explain why including the Oracle jar in my classpath didn't solve the problem, and why editing the Manifest file did?
Thanks!
From Sun (Oracle) documentation for the java -jar command:
Execute a program encapsulated in a JAR file. The first argument is
the name of a JAR file instead of a startup class name. In order for
this option to work, the manifest of the JAR file must contain a line
of the form Main-Class: classname. Here, classname identifies the
class having the public static void main(String[] args) method that
serves as your application's starting point. See the Jar tool
reference page and the Jar trail of the Java Tutorial for information
about working with Jar files and Jar-file manifests. When you use this
option, the JAR file is the source of all user classes, and other user
class path settings are ignored.

Setting Java Classpath to Load a Class File

I'm new to Java, and I'm unsure how to access a class file located in a specific directory from a separate program jar.
For example, I have an third party jar file located in /, which is supposed to load MyClass located in /mylib/MyClass.class, so I tried running:
java -jar mainprog.jar -classpath "/mylib" MyClass
but I'm getting the error:
Exception in thread "main" java.lang.NoClassDefFoundError: MyClass
Caused by: java.lang.ClassNotFoundException: MyClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:221)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:209)
at java.lang.ClassLoader.loadClass(ClassLoader.java:324)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:269)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:337)
What am I doing wrong?
When you use "-jar" then only the Class-Path attribute defined in the META-INF/MANIFEST.MF file inside the jar file will influence the classpath.
It will also ignore the MyClass argument (or more specifically: interpret it as an argument to the main-class defined in the MANIFEST.MF).
If you simply want to call a class from that jar call it like this:
java -cp mainprog.jar:/mylib MyClass
// or using this one on windows:
java -cp mainprog.jar;/mylib MyClass
In your command line you are trying to run MyClass as a program, which based on your description is not what you want.
You need to figure out what the main class is that is used to execute the program in the jar. You could unpack the jar file with jar -xf mainprog.jar and look at the META-INF/MANIFEST.MF file. It should have an entry that indicates that the main class of the jar is (I can't remember the name of the entry right now).
After than change your command line to something like this:
java -classpath /mainprog.jar:/mylib package.name.to.jar.MainClass

Categories