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
Related
I have created an application that uses selenium-server-standalone-2.47.1.jar and javax.mail.jar. The code works on eclipse, but I would like to run the same from command line. So I exported the project to a runnable jar file which contains both selenium and javax.mail.jar.
My code contains RTC.java which has the Main function and another Ex.java.
Both the class files are generated in com folder.
My App1.jar file is located in C:\installers.
I used the command:
c:\installers> java -cp App1.jar com.RTC
It says:
Exception in thread "main" java.lang.NoClassDefFoundError: org.openqa.selenium.WebDriver
Further I used:
java -cp .App1.jar com.RTC
Then it says could not find or load main class com.RTC.
What am I doing wrong?
I used the command:
c:\installers> java -cp App1.jar com.RTC
It says:
Exception in thread "main" java.lang.NoClassDefFoundError:
org.openqa.selenium.WebDriver
That exception usually means that a .class file was found but it didn't contain the right class. Check how you're putting it into the JAR. It's directory and file name must match its package and class name.
It sometimes also seems to mean that a secondary class wasn't found. Normally secondary JAR files are mentioned in the class-path entry of the manifest of the main JAR file, along with the main-classname, so you can use
java -jar App1.jar
Further I used:
java -cp .App1.jar com.RTC
Then it says could not find or load main class com.RTC.
I'm not surprised. If the first command got as far as it did, the JAR filename doesn't start with a dot. Cannot imagine why you tried this. It is nonsense.
I found the solution. I need not create a jar file which has the reference jars. I have to mention my jar which has my code and the reference jars that I am using in the class path.
My code is in App.jar.The reference jars are
selenium-server-standalone-2.47.1.jar and
javax.mail.jar.
so I used
c:\installers> java -cp selenium-server-standalone-2.47.1.jar;javax.mail.jar;App.jar com.RTC
Thank You.
I have the following problem trying to execute a jar file (created from my project) into the Windows shell (the DOS prompt).
I have a file named Main.jar. If I unzip this file it contains a mainPkg folder (that is the name of the package containing the Main class that itself contains the main() method).
So into the mainPkg folder there is the Main.class file that contains the main() method.
Ok so, from the shell, I go into the directory that contains the Main.jar and I perform:
C:\Projects\edi-sta\build\jar>java -jar mainPkg.Main.jar
Error: Unable to access jarfile mainPkg.Main.jar
But as you can see I obtain the Unable to access jarfile mainPkg.Main.jar. Why? What am I missing? How can I solve this issue and execute my Main.jar file?
Basically you've two types of JARs
Normal JAR - to package your classes into a single archive
Runnable JAR - This is similar to Normal jar except that you can run this with java -jar command like this java -jar RunnableMain.jar.
In this one we already configure the class having main(),so no need to pass the class name in jar command
Assuming that yours is a normal JAR, you can execute your class of interest like this
C:\Users\arkantos\work>java -classpath C:\Project\Main.jar mainPkg.Main
Notice that i've mentioned the absolute path of the JAR to add it to classpath, because I'm in a different directory, if not you can cd to that dir containing your Main.jar and then invoke your Main class like this
C:\Project>java -classpath Main.jar mainPkg.Main
Here Main.jar is inside Project directory so no need to give absolute path
The syntax for executing a class containing a main method in a jar is:
java -classpath <jarFile> <class>
In your case:
java -classpath Main.jar mainPkg.Main
If you want to execute the jar using java -jar you must create an executable jar file. That can be done in different ways depending on which build tools you use.
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').
I have written the following Java source file (Hello.java):
package com;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello!");
}
}
I save this to C:/tmpjava/Hello.java.
From the command line, I navigate to that directory and run javac Hello.java. Then I run dir:
Hello.class
Hello.java
Then, from the same directory that I just ran javac from, I run java Hello.class and get:
Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
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:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Hello.class. Program will exit.
What's going on here?!? How can javac run fine, but not java?
Your class Hello belongs to the package com. So the fully qualified name of your class is com.Hello. When you invoke a program using java on the command-line, you should supply the fully-qualified class name of the class that contains your main method and omit the .class, like so:
java com.Hello
The java program needs this fully-qualified class name to understand which class you are referring to.
But you have another problem. The java program locates packages, sub-packages, and the classes that belong to them using the filesystem. So if you have a package structure like com.Hello, the java program expects to find a class file named Hello.class in a directory named com, like this: com/Hello.class. In fact you can observe this behavior in the Exception that you see; you've incorrectly used Hello.class, which java is interpreting as a package named Hello, and a class named class, and is looking for the directory structure Hello/class:
java.lang.NoClassDefFoundError: Hello/class
But the compiler javac doesn't set up this directory structure by default. See the documentation for javac, but the important bit is this: when you do your compiles, you can specify a destination directory using the -d flag:
-d directory
Set the destination directory for class files. The destination directory must already exist; javac will not create the destination directory. If a class is part of a package, javac puts the class file in a subdirectory reflecting the package name, creating directories as needed. For example, if you specify -d c:\myclasses and the class is called com.mypackage.MyClass, then the class file is called c:\myclasses\com\mypackage\MyClass.class.
If -d is not specified, javac puts the class file in the same directory as the source file.
The last bit in bold is the source of much confusion for beginners, and is part of your own problem.
So you have two alternatives:
In your case, it's fine if you supply the current directory as the destination directory, like so (the period . means current directory):
javac -d . Hello.java
If you invoke the compiler like this, it will create the com directory for you, and put your compiled class file in it, the way that the java program expects to find it. Then when you run java as above, from c:\tmpJava, your program should execute.
You could set up your source code using a directory structure that mirrors your package structure: put your source file Hello.java inside a directory called com, in your case: c:\tmpJava\com\Hello.java. Now, from c:\tmpJava you can run your javac compile like this:
javac com\Hello.java
You haven't supplied the -d flag, but that's fine, because you've created the directory structure yourself, and quoting again from the documentation above:
If -d is not specified, javac puts the class file in the same directory as the source file.
Again, when you run java as above, your program should execute.
Note that this second alternative is one that is commonly employed by java programmers: the source code files are organized in a directory structure that mirrors the package structure.
In this explanation we've ignored the concept of the classpath. You'll also need to understand that to write java programs, but in your case of simply compiling a program in the current directory - if you follow one of the two alternatives above when compiling your class - you can get away without setting a classpath because, by default, the java program has the current directory as a classpath. Another quote, this one from the documentation for java:
-cp classpath
Specify a list of directories, JAR archives, and ZIP archives to search for class files. Class path entries are separated by semicolons (;). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.
If -classpath and -cp are not used and CLASSPATH is not set, the user class path consists of the current directory (.).
Note that when you use an IDE like Eclipse to run your java code, this is mostly handled for you, but you'll still run into classpath issues.
The syntax of the Java command is:
java [classname]
not
java [filename]
Java looks in its classpath for a class of the name you have provided. Usually the classpath includes the current directory, so:
java Hello
... will find Hello.class in the current directory, and run its main() method.
However, if the class is somewhere else (like in a .jar, or somewhere else in the filesystem) you can specify it with the CLASSPATH environment variable, or on the commandline:
java -cp build/classes Hello
java -cp build/jars/myjar.jar Hello
The class should be in C:\tmpjava\com\Hello.class
And you should run from C:\tmpjava: java -cp . com.Hello
When you put a class in a package it defines the file structure of the class. I.e. your class which in package com should be in folder com
Run the following command
java -cp . com.Hello
java -classpath c:\tmpjava com.Hello
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.