I'm trying to figure out how class importing works in Java. I have the following file structure:
testProject
pkgA
A.java
A.class
dir
pkgB
B.java
B.class
The contents of A.java are:
package pkgA;
public class A {
public static String funcA() {
return "funcA in class A in pkgA";
}
}
The contents of B.java are:
package pkgB;
import pkgA.A;
public class B {
public static void main(String[] args) {
System.out.println((new A()).funcA());
}
}
In testProject I run:
javac pkgA/A.java
The above command doesn't print anything.
In testProject/dir I run:
javac pkgB/B.java -classpath ..
The above command doesn't print anything.
In testProject/dir I run:
java pkgB/B -classpath ..
The above command prints the following:
Exception in thread "main" java.lang.NoClassDefFoundError: pkgA/A
at pkgB.B.main(B.java:7)
Caused by: java.lang.ClassNotFoundException: pkgA.A
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
What am I doing wrong?
Giving the classpath as an absolute path doesn't help.
$ java -version
java version "1.7.0_51"
OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.12.04.2)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
OS is Ubuntu 12.04
Thanks!
Note that your classpath spec must preceed classes or .java files e.g.
java -classpath .. pkgB/B
(the same applies to the javac invocation).
I would compile everything at the same time e.g.
javac -classpath {whatever} {complete list of .java files}
for consistency's sake.
Specify the compiler output directory to be separate to your source (e.g. a directory called classes). That makes life simpler in terms of managing your code and the compiled artifacts.
Going forward, you should investigate a build tool such as Maven or Ant (or Gradle or Sbt etc.). That will make life much more manageable as you add source files, config or dependencies.
Check your classpath and make sure the current directory(directory that holds pkgA and pkgB) is in the classpath.
It's not always about the class you first see, it's also about what's in them.
1) You have a class called "com.my.Clazs".
2) The class imports "com.my.other.Clazzzz";
3) You have a static method inside Clazs
public static void doFoo() {
/* The call to Clazs.doFoo() will result in NCDF Error if you
* skip Clazzzz lookup in classpath.
*
*/
Clazzzz anObject = new Clazzzz();
}
if you are trying do something from Clazs statically, it will give you NoClassDefFoundError because it cannot load all the dependencies fully to qualify this as a valid class. In other words, all the URLs cannot be resolved fully.
This kind of problem is not unusual even when you have dependency manager e.g. Maven. You might forget that you have a compile-time dependency on certain jars/classes (e.g. Java Tools.jar) which you also need to load when you start the application.
Related
I am newbie in java. I am running java programs via Ubuntu terminal
I just started java package topic and have been dealing with a problem for several hours.
I tried to create a simple package called pack which has single class Hello.
I created a directory pack. Inside the pack I put Hello.class file intp pack directory via
javac -d ./pack Hello.java
command.
Then I included pack package into a class containing main method. The class's name is test and it is located in test.java file This class is located in another directory. I compile via
javac -cp ./pack test.java
It compiles without any error and everything is ok.
However, when I enter command
java -cp ./pack test
it gives me
Error: Could not find or load main class test
When I tried
java test
command. The following message showed up
Exception in thread "main" java.lang.NoClassDefFoundError: pack/Hello
at test.main(test.java:6)
Caused by: java.lang.ClassNotFoundException: pack.Hello
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
Can anybody explain me what I am doing wrong? Any help is much appreciated.
Sorry, I did bot include my source codes. Here they are.
import pack.Hello;
public class test
{
public static void main(String args[])
{
Hello.HelloMessage();
}
}
This is test.java file which tests if everything is ok. It is located at
/home/uesername/apps
directory.
Then I created "pack" directory. Full path to the pack directory is
home/username/apps/pack
Inside the "pack" I put Hello.java file. The content of Hello.java file is
package pack;
public class Hello
{
public static void HelloMessage()
{
System.out.println("hello, world");
}
}
To begin with I suggest you use an IDE to setup you environment for compiling, running and debugging.
The problem you have is that you have compiled with the wrong path.
javac -cp . pack/Hello.java
javac -cp . pack/test.java
and
java -cp . pack.Hello
or
java -cp . pack.test
The problem is that you compiled a class with package pack in a directory pack and you would end up with
pack/pack/Hello.class
I suggest you check where the Hello.class file has been placed.
I get a NoClassDefFoundError when trying to run a Java class without providing the proper class path. However when added the needed class path, java complaints it cannot find the main method. If you have any idea of what's happening here, please point me in the right direction. Thank you
$ java MyClass
Exception in thread "main" java.lang.NoClassDefFoundError: cern/colt/matrix/DoubleMatrix1D
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
at java.lang.Class.getMethod0(Class.java:2856)
... 6 more
$ java -cp resources/colt.jar MyClass
Error: Could not find or load main class MyClass
Assuming MyClass isn't in a package, you need something like (on Windows)
java -cp resources/colt.jar;. MyClass
or (otherwise)
java -cp resources/colt.jar:. MyClass
To also include the current directory. Alternatively, you can set the CLASSPATH environment variable.
On Windows,
set "CLASSPATH=resources/colt.jar;."
otherwise something like (depending on your shell)
export CLASSPATH="resources/colt.jar:."
then
java MyClass
try to include the current directory in the classpath as well. usually we add new jars to classpath liek this:
java -cp %CLASSPATH%;resource/colt.jar MyClass
or on Linux as:
java -cp $CLASSPATH:resource/colt.jar MyClass
Additionally u can also add .
i.e the currrent directory to the classpath.
When I try to execute the following program from DOS I get the results below..
The following program is in C:\Users\Apostolos\Documents\NetBeansProjects\Java1\src\java1
package java1;
public class MyProgram{
public static void main(String[] args){
System.out.println("Rome wasn’t burned in a day!");
}
}
javac MyProgram.java
works fine
But java MyProgram gives the following:
Exception in thread "main" java.lang.NoClassDefFoundError: MyProgram (wrong name
: java1/MyProgram)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
................
Why this is happening??
My environment variables:
CLASSPATH: .;C:\Program Files (x86)\Java\jre7\lib\ext\QTJava.zip;C:\Program Files\Java\jdk1.7.0_05\bin
PATH: C:\Program Files\Java\jdk1.7.0_05\bin
JAVA_HOME: C:\Program Files\Java\jdk1.7.0_05
I have seen similar problems here but i cannot find the solution to my problem.
Thank you in advance!
This is caused when there is a class file that your code depends on and it is present at compile time but not found at runtime. Look for differences in your build time and runtime classpaths.
Refer this Link
2 points you should keep in mind when using java tool:
Add the class to the classpath.
Use the fully qualified name of the class to be run.
Hence:
java -cp C:\Users\Apostolos\Documents\NetBeansProjects\Java1\bin java1.MyProgram
assuming the following file exists after compilation:
C:\Users\Apostolos\Documents\NetBeansProjects\Java1\bin\java1\MyProgram.class
For more info, see:
Mastering the Java CLASSPATH.
"Setting the class path" Documentation.
NoClassDefFoundError in Java comes when Java Virtual Machine is not
able to find a particular class at runtime which was available during
compile time. For example if we have a method call from a class or
accessing any static member of a Class and that class is not available
during run-time then JVM will throw NoClassDefFoundError.
Obvious reason of NoClassDefFoundError is that a particular class is not available in Classpath, so we need to add that into Classpath or we need to check why it’s not available in Classpath if we are expecting it to be. There could be multiple reasons like:
Class is not available in Java Classpath.
You might be running your program using jar command and class was
not defined in manifest file's ClassPath attribute.
Any start-up script is overriding Classpath environment variable.
Try in this way
run command prompt as Administrator, and
cd C:\Users\Apostolos\Documents\NetBeansProjects\Java1\src
then
javac java1/MyProgram.java
Then
java java1.MyProgram
This will work.
Exception in thread "main" java.lang.NoClassDefFoundError: MyProgram (wrong name
This exception is thrown when the JVM cannot finf your class at run time
From C:\Users\Apostolos\Documents\NetBeansProjects\Java1\src
execute " "java java1.MyProgram" –
everyone.
I used openjdk-7 on arch linux. I started to learn Java recently, and encountered such a problem:
I created a file at /home/hqwrong/Code/java/mew/Mouth.java:
package mew;
public class Mouth{
public static void main(String argv[]){
pickle.Say s = new pickle.Say();
}
}
and another one at /home/hqwrong/Code/java/pickle/Say.java :
package pickle;
public class Say{
public Say(){
System.out.println("Say");
}
}
I compiled Say.java to Say.class,using:
$ cd /home/hqwrong/Code/java/pickle
$ javac Say.java
which is successful.
I compiled Mouth.java ,using:
$ cd ../mew
$ export CLASSPATH=.:/home/hqwrong/Code/java/
$ javac Say.java
no error message.
But after I type:
$ java Say
I got:
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.mew
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:649)
at java.lang.ClassLoader.defineClass(ClassLoader.java:785)
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:472)
It's same when I use:
$ java -cp $CLASSPATH Say
I need your help,please?
Since there is no good answer yet, I'll post mine.
First, you should really have a separate folder for your classes and your sources. I suggest using java/src for your sources, and java/classes for your classes. Since the classes are stored in the classes folder, this is the one that should be in the classpath.
The folder tree of your sources should then match your package tree. This means that the class mew.Mouth must contain the line package mew, be defined in the Mouth.java file, in the java/src/mew folder.
To compile your classes, put you in the java/src directory, and use the following command:
javac -d ../classes mew/Mouth.java pickle/Say.java
The compiler will automatically generate the folder structure matching the package structure in the classes directory. If you make structural modifications in your source tree, just remove everything in the classes folder, and recompile everything.
To run your classes, you must refer to their fully qualified name. And the folder containing your package tree (the java/classes folder) must be in the classpath. Once this is done, from everywhere, you can use
java mew.Mouth
Note that, as you have discovered, the java and javax packages are reserved. You can't use them for your own classes.
Please try this,
open your root folder, Go to view Menu & tick , view hidden files. Now It will display a file called ".bashrc". open this file & write down following lines of code,
PATH=$PATH:/opt/jdk1.6.0_21/bin
export PATH
JAVA_HOME=/opt/jdk1.6.0_21
export JAVA_HOME
I'm following the java tutorials on the Princeton website.
I'm running debian sqeeze 64bit and I have installed Sun java version 6.
I can compile and run the basic hello world program without any problem, using the terminal and the Eclipse IDE.
The problem is:
when I try to compile and run a program, which requires an argument input for example:
public class RandomSeq {
public static void main(String[] args) {
// command-line argument
int N = Integer.parseInt(args[0]);
// generate and print N numbers between 0 and 1
for (int i = 0; i < N; i++) {
System.out.println(Math.random());
}
}
}
I can run this on Eclipse putting an integer argument, however it doesn't work on the terminal.
I get this error:
emes#debian:~/Documents/workspace/IOput/src/randomSeq$ java RandomSeq 21
Exception in thread "main" java.lang.NoClassDefFoundError: RandomSeq (wrong name: randomSeq/RandomSeq)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
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: RandomSeq. Program will exit.
I've tried to update the /etc/profile to include the java-6-sun on the PATH variable.
I'm not sure, what to try from here.
Apparently, you're trying to run your program from the src folder of an Eclipse project. src stands for “source”. The executable version of your program (the compiled classes) is not in src; it's in bin, which stands for “binary”, i.e. machine code.
When using the command line, you should first compile your program:
javac MyClass.java
and then run it:
java MyClass
But please, do not do it inside an Eclipse project's directory structure, or you will create additional files (class files) not expected by Eclipse at this location.
Additionally maybe you are inside a package. You can't run a class if you're within its package folder. You need to be at the top-level of the package hierarchy.
Example: suppose your class is inside a package named mypackage. Then in someFolder/mypackage/MyClass.java you will have something like:
package mypackage;
class MyClass {
...
}
After compiling your code, you must be in somefolder and issue the shell command:
java mypackage.MyClass
It looks as if your class has a package
package randomSeq;
public class RandomSeq {
If so, then when starting it it should be located in the folder randomSeq and the root of that folder should be in your class path and the package must be specified when invoking.
So, if your .class file is in bin/randomSeq then you could run it with java -cp bin randomSeq.RandomSeq 21
Don't bother about the argument as that would give a run-time null pointer exception.
The problem is your classpath.
Make a list (ls or dir) in the directory you run java RandomSeq from.
Do you have a .class file there. If not run javac RandomSeq.java first to generate the class file