I'm using a cloud VM in which Ubuntu is installed. Java version installed is:
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
I've never used terminal to compile and run programs. However, this program works using Eclipse.
I have to use two jars when I compile my java program: disco-2.1.jar and sqlite-jdbc-3.8.11.2.jar. The terminal command I use is:
javac -cp '/home/ubuntu/workspace/sem/*' USem.java
Using /home/ubuntu/workspace/sem/* adds disco and sqlite jars to the classpath.
This creates my USem.class file in sem directory, without errors. Those jars are contained in sem directory.
USem.java contains this part of code, starting from the beginning:
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.lucene.index.CorruptIndexException;
import de.linguatools.disco.CorruptConfigFileException;
import de.linguatools.disco.DISCO;
import de.linguatools.disco.TextSimilarity;
import de.linguatools.disco.DISCO.SimilarityMeasure;
public class USem {
//irrelevant code here
public static void main(String[] args) throws IOException, CorruptConfigFileException, SQLException{
The problem starts when I run this in the terminal:
java USem
The terminal shows me:
Error: A JNI error has occurred, please check your installation and
try again Exception in thread "main" java.lang.NoClassDefFoundError:
de/linguatools/disco/CorruptConfigFileException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException:
de.linguatools.disco.CorruptConfigFileException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
I think there's a problem with disco-2.1.jar. I checked the jar classes contained in it and everything was ok.
My workspace is organized like so:
home/ubuntu/workspace/sem
In the sem directory I have my .java file and the .jar files are added there.
What am I doing wrong? I tried uninstalling JDK and reinstalling it, changing the terminal folder in which I run commands, but nothing changed.
--Update--
Now I wrote
java -cp '/home/ubuntu/workspace/sem/*' USem
However, I obtained
Error: Could not find or load main class USem
Add Disco jar (or any other required jar for that matter) to classpath while executing java command
java -cp "Whatever.jar" my.package.MainClass
The default classpath when there's no -classpath argument and no CLASSPATH environment variable is .. Now when your class file is in your working directory and you call java USem, Java finds your class but not the classes in the other jar files because these are not in the classpath.
When you add -cp '/home/ubuntu/workspace/sem/*' Java will find the classes in the jar files. But this also overrides the default classpath, so . is no more in there, therefore Java doesn't find your own class anymore. You need to explicitly add . (or /home/ubuntu/workspace/sem) again: -cp '.:/home/ubuntu/workspace/sem/*'
All your comments were useful. I'd like to post my solution.
I declared CLASSPATH environment
export CLASSPATH=/home/ubuntu/workspace/sem/disco-2.1.jar:**other paths for other external jars**:.
I moved into workspace and compiled .class file
javac -cp 'sem/*' sem/USem.java
Then I moved into sem and run
java USem
and worked.
move all the required jars in thejre/lib/ext folder and simply run the command
java filename
worked for me!
Related
System details:
Ubuntu 17.10
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.17.10.2-b12)
I can't get my java program to run. I don't know why it won't find the class. It compiles with the -classpath flag, but doesn't find the class when running.
$ ls -ltra
total 668
-rw-rw-r-- 1 bvpx bvpx 653275 Jan 19 14:45 javax.mail.jar
drwxr-xr-x 3 bvpx bvpx 4096 Jan 19 14:59 ..
-rw-r--r-- 1 bvpx bvpx 960 Jan 19 15:07 Example.java
drwxr-xr-x 2 bvpx bvpx 4096 Jan 19 15:07 .
Compiling without -classpath does not work (I thought -classpath defaulted to .?)
$ javac Example.java
Example.java:2: error: package javax.mail does not exist
Specifying the -classpath helps, the program now compiles and produces Example.class:
$ javac -classpath javax.mail.jar Example.java
$
Here's the source code:
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class Example {
static final int PORT = 587;
/* ... */
public static void main(String[] args) throws Exception {
/* ... */
Transport transport = session.getTransport();
try
{
System.out.println("Sending...");
transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
transport.sendMessage(msg, msg.getAllRecipients());
System.out.println("Email sent!");
}
catch (Exception ex) {
System.out.println("Error message: " + ex.getMessage());
}
}
}
Running the program produces this error:
$ java -Xdiag -classpath javax.mail.jar Example
Error: Could not find or load main class Example
java.lang.ClassNotFoundException: Example
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
Running java without -classpath causes the JNI to not find javax/mail even though it's in the directory.
$ java -Xdiag Example
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Address
at java.lang.Class.getDeclaredMethods0(Native Method)
Why can't java find the Example class?
You seem to be missing some fundamental concepts here.
The classpath gives a list of directories and JAR files to search for needed classes. When trying to load a class foo.bar.MyClass that is not part of the standard library, the default classloader will look for it in each classpath element in turn, in order, until it finds the class or runs out of elements.
Note well, however, that it searches by fully-qualified name. For classpath entries that are directories, that means that it looks for foo/bar/MyClass.class relative to the directory. For classpath entries that are JAR files, it looks for foo/bar/MyClass.class relative to the root of the JAR. Classes that belong to the unnamed default package are a little special, or so it may seem, because their class files (e.g. InDefaultPackage.class) are expected to be located directly in the root of the designated JAR or directly in the specified directory.
Compiling without -classpath does not work (I thought -classpath
defaulted to .?)
$ javac Example.java
Example.java:2: error: package javax.mail does not exist
The classpath does default to .. This is the name of a directory, so when searching it for classes in, say, the javax.mail package, it looks for a subdirectory javax/mail, and if that is found, it examines the class files within. Note that it does not descend into JAR files it discovers in the directory tree. It looks only in those JARs explicitly named in the classpath.
The error message is telling you that javac didn't find any classes at all from the javax.mail package. You could have solved it either by specifying the JAR in the compilation classpath (as ultimately you did) or by unpacking the JAR in the current directory.
Specifying the -classpath helps, the program now compiles and produces
Example.class:
$ javac -classpath javax.mail.jar Example.java
$
Note that the compiler will store the classfile in a directory structure corresponding to its package, just where the java command will look for it.
Running the program produces this error:
$ java -Xdiag -classpath javax.mail.jar Example
Error: Could not find or load main class Example
java.lang.ClassNotFoundException: Example
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
You clarified in your answer that you solved this problem by removing a package statement from Example.java. That's ok, but it doesn't really explain the problem, which is that java expects you to give it the fully-qualified name of the class. That includes the package name if the class is in a named package. Thus, if Example.java contained this package statement:
package com.my;
then the class name you would need to specify to java would be com.my.Example. You specified just Example, which designates a class named "Example" in the default package, and your solution to the class not found problem was to move your class into the default package.
Note also that it is conventional and helpful to lay out your Java source files, too, in a directory structure matching their package structure. Thus, the source file for class com.my.Example would conventionally be located in com/my/Example.java. The Java compiler will rely on this scheme to locate sources for classes that it does not find.
Running java without -classpath causes the JNI to not find
javax/mail even though it's in the directory.
$ java -Xdiag Example
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: javax/mail/Address
at java.lang.Class.getDeclaredMethods0(Native Method)
No, javax/mail/Address was not in the directory. It was in a JAR file in the directory. That's not at all the same thing, and the difference is significant.
I had to set -classpath to include the current directory. According to the documentation classpath is delimited by :. The correct classpath string was:
javax.mail.jar:.
Below is a working example.
$ javac -classpath javax.mail.jar:. Example.java
$ java -classpath javax.mail.jar:. Example
Sending...
Email sent!
Another thing to note was that there was originally a package definition at the top of Example.java. I had to remove it.
I have some java files and I want to run them in the linux cmd mode. In those java files I used aws java sdk, so I need to set the classpath for aws java sdk. Here is what I did:
export CLASSPATH=/home/ubuntu/loadbalancer/aws-java-sdk-1.10.20/lib/aws-
java-sdk-flow-build-tools-1.10.20.jar:/home/ubuntu/loadbalancer/aws-java-
sdk-1.10.20/lib/aws-java-sdk-1.10.23-sources.jar:/home/ubuntu
/loadbalancer/aws-java-sdk-1.10.20/lib/aws-java-sdk-1.10.20.jar:
/home/ubuntu/loadbalancer/aws-java-sdk-1.10.20/lib/aws-java-sdk-1.10.20-
javadoc.jar:/home/ubuntu/loadbalancer
echo $CLASSPATH /home/ubuntu/loadbalancer/aws-java-sdk-1.10.20/lib/aws-
java-sdk-flow-build-tools-1.10.20.jar:/home/ubuntu/loadbalancer/aws-java-
sdk-1.10.20/lib/aws-java-sdk-1.10.23-sources.jar:/home/ubuntu
/loadbalancer/aws-java-sdk-1.10.20/lib/aws-java-sdk-1.10.20.jar:
/home/ubuntu/loadbalancer/aws-java-sdk-1.10.20/lib/aws-java-sdk-1.10.20-
javadoc.jar:/home/ubuntu/loadbalancer
When I did javac *.java
I got this stack trace
javac *.java
LoadBalancer.java:15: package com.amazonaws.auth does not exist
import com.amazonaws.auth.BasicAWSCredentials;
^
LoadBalancer.java:16: package com.amazonaws.services.ec2 does not exist
import com.amazonaws.services.ec2.AmazonEC2Client;
^
LoadBalancer.java:17: package com.amazonaws.services.ec2.model does not exist
import com.amazonaws.services.ec2.model.CreateTagsRequest;
Anyone could help?
Side question: Is there a specific reason why you cannot do this through a proper dependency management system? (for example: maven).
What the error are telling you is that parts of your app are referencing things that are not in the classpath.
Are the jars that you've put in the classpath actually at that location? i can see at least 1 problem in /home/ubuntu/loadbalancer/aws-java-
sdk-1.10.20/lib/aws-java-sdk-1.10.23-sources.jar
I found my problem, I did not import all the jar files into the classpath.
I am a Java beginner and trying to figure out how to use the apache commons lib.
Here is a source file Randstr.java:
import org.apache.commons.lang3.RandomStringUtils;
class Randstr {
public static void main(String[] args) {
String s = RandomStringUtils.random(12);
System.out.println(s);
}
}
I have the commons-lang3-3.1.jar file in /usr/share/java/ and have created a symlink in the current dir. Then I compiled it like this: javac -cp commons-lang3-3.1.jar Randstr.java, the complilation was fine, but when I execute java Randstr, I got the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/RandomStringUtils
at Randstr.main(Randstr.java:5)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.RandomStringUtils
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:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more
And if I don't specify the jar file in the classpath, it will not even compile:
javac -cp . Randstr.java
# Randstr.java:1: error: package org.apache.commons.lang3 does not exist
# import org.apache.commons.lang3.RandomStringUtils;
# ^
# Randstr.java:5: error: cannot find symbol
# String s = RandomStringUtils.random(12);
# ^
# symbol: variable RandomStringUtils
# location: class Randstr
# 2 errors
javac -cp /usr/share/java/ Randstr.java
# Randstr.java:1: error: package org.apache.commons.lang3 does not exist
# import org.apache.commons.lang3.RandomStringUtils;
# ^
# Randstr.java:5: error: cannot find symbol
# String s = RandomStringUtils.random(12);
# ^
# symbol: variable RandomStringUtils
# location: class Randstr
# 2 errors
From reading other questions on stackoverflow, I see this can be solved by using an IDE, but I prefer a simple editor at the moment.
If you can compile it with
javac -cp commons-lang3-3.1.jar Randstr.java
then you can run it with
java -cp commons-lang3-3.1.jar:. Randstr
The JAR file has to be in the classpath.
Edit your profile file. vim ~/.bashrc
In your profile file add the following line:
export CLASSPATH=/usr/share/java/commons-lang3-3.1.jar:.
Log out and back in. Or source your profile file in the windows you have open. You can always add your classpath to every java and javac command you invoke but that becomes a pain. With the CLASSPATH environmental variable you don't have to add it on the command line any more. Note that if you are using an IDE such as NetBeans or Eclipse you still might have to add the library to your project's libraries within the IDE.
Clearly the contents of /usr/share/java/ don't automatically get added to the classpath - it's just a common location where APT packages put Java libraries. It's up the developer to reference them correctly.
JARs in the ext/ subdirectory of a Java installation do get added to the classpath automatically. However, do not put your own JARs in there. It's a terrible practice because it doesn't match how Java apps are deployed "in the real world".
The correct way is using the -cp parameter explicitly when compiling AND running your app. Java doesn't compile library code into your .class files, a .class file only refers to names of other classes which are then loaded as-needed from the class path when your app runs. The -cp parameter takes only .jar files, or directories with .class files in them. You can also use wildcards in the value of that parameter. For more information on wrangling the class path, check the tool documentation on setting the class path.
You using a build tool that sets it for you automatically, like an IDE or Maven or another build system with dependency management. (Gradle or Ant+Ivy.) If you're writing a Java app that uses third party libraries, I very strongly suggest you learn and use one of those. (Also, most IDEs can work with Maven's configuration files letting you use the same build settings in a team with people using mixed or no IDEs.) Generally if you're invoking a compiler directly you're not doing it right.
I've been working on this for about an hour and thumbing through Q&As on stackoverflow but I haven't found a proposed solution to my problem. I'm sorry if this is a duplicate, but I couldn't find any duplicate question with an answer that solved my specific problem.
I am trying to write and compile a java program from terminal for the first time (up until this point I have been using Eclipse for java and VIM for everything else, but I feel its time to switch entirely to VIM). Here is my current HelloWorld code:
package main;
public class HelloWorld {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
I compile and run using the following commands (specifying the classpath to ensure that isn't the problem):
javac -cp "./" HelloWorld.java
java -cp "./" HelloWorld
This gives me the following error message:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: main/HelloWorld)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
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:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:480)
I know it is seeing the file HelloWorld.class and trying to access the class HelloWorld because if I change the run command to:
java -cp "./" Foo
I get an entirely different error message:
Error: Could not find or load main class Foo
I have tried several dozen pages worth of troubleshooting and come up short, including the following:
Exception in thread "main" java.lang.NoSuchMethodError: main
http://introcs.cs.princeton.edu/java/15inout/mac-cmd.html
java -version yields:
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode)
My operating system is LinuxMint and uname -a yields:
Linux will-Latitude-D620 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:50 UTC 2011 i686 i686 i386 GNU/Linux
package main;
This means that your class resides in the main package, and its canonical name is main.HelloWorld.
Java requires that package names should also be mirrored in the directory structure. This means that:
Your HelloWorld.java file should be in a directory named main
You should execute javac and java from the directory containing main, not from main itself
The classpath should contain the directory where the main directory is, not main itself
java expects the canonical name of the class to execute, so main.HelloWorld
So, to recap:
You should have something like myproject/main/HelloWorld.java
From myproject, run javac main/HelloWorld.java
From myproject, run java -cp ./ main.HelloWorld
You've put your class in a package named "main", but you're trying to treat it like it isn't in a package. Since you put package main; at the top of your source file, you need to put HelloWorld.java in ./main, then run javac ./main/HelloWorld.java, followed by java -cp . main.HelloWorld.
These commands will get you the working example you're trying to build:
mkdir main
echo 'package main; public class HelloWorld { public static void main(String... args) { System.out.println("Hello World"); } }' > main/HelloWorld.java
javac main/HelloWorld.java
java -cp . main.HelloWorld
As a beginner you might encounter a very similar scenario where the error output is the same. You try to compile and run your simple program(without having any package set) and you do this:
javac HelloWorld.java
java HelloWorld.class
This will give you the same java.lang.NoClassDefFoundError since java thinks HelloWorld is your package and class your class name. To solve it just use
javac HelloWorld.java
java HelloWorld
See the Java page - Lesson: Common Problems (and Their Solutions)
Problem:
Basically, the Exception in thread "main" java.lang.NoClassDefFoundError:
means, that the class which you are trying to run was not found in the classpath.
Solution: you need to add the class or .jar file which contains this class into the java classpath. When you are running a java class from the command line, you need to add the dot (.)
java YourSingleClass -cp .
into the classpath which tells the JVM to search for classes in actual directory.
If you are running a class from a .jar file, you need to add this jar file into the classpath:
java org.somepackage.SomeClass -cp myJarWithSomeClass.jar
I have been mostly using eclipse so far. Now I'm trying to run java from terminal but I have a problem with packages.
This is my Main.java file:
package main;
class Main {
public static void main(String[] args) {
System.out.println("it's working");
}
}
I compile this using javac Main.java and then run with java Main which gives me:
java Main
Exception in thread "main" java.lang.NoClassDefFoundError: Main
Caused by: java.lang.ClassNotFoundException: Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: Main. Program will exit.
When I remove package Main everything works fine. What am I missing?
java -version gives:
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
You need to run the java command up one directory level and give it in the fully qualified package name, eg: java main.Main
See How the Java Launcher Finds User Classes to learn how this works.
You can use this command:
java main.Main
Make sure the main (lowercase) package directory is on the classpath.
It is possible that your classpath is not set correctly.
Since you gave your .java file a package it is unnamed no longer.
An example:
java -cp ./package1/ main.Main //from the current directory and
//if main package is contained in package1
You need to fully qualify the class name.
For future reference if you want to run from the command line you must stop the indirection (for lack of a better term) at the package level.
Say your class was in the package package1.package2.Main.java
I would run it like so java -cp /blah/blah package1.package2.Main
Compile
Windows:
javac main\Main.java
Mac:
javac main/Main.java
Run
java main.Main
If you add package Main, then you must put your source file in folder Main/Main.java. After that you can compile. When you run the program, go to Main folder using "cd", then write java -cp Main.Main
See my question similiar to yours noclassdeffounderror
try this...
In window , you just compile the code as
javac - d . Main.java
then a package(folder) with the name you specified in your class is created (in your code, package with name "main" is created) in the same path where your program reside...
Then you just run the program as
java main.Main
or
java main/Main