Java NoClassDefFoundError Error - java

I wrote the basic code below and saved to a file called pdf.java.
package pdf;
import java.util.*;
import java.io.*;
import com.lowagie.text.DocumentException;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.util.regex.*;
public class pdf {
public static void main(String[] args) throws IOException, DocumentException{
System.out.println("Hello World2!");
}
}
I then compiled it like this,
javac pdf.java -cp core-renderer.jar:iText-2.0.8.jar
Which seemed to work as I got a pdf.class file. I then tried to run it with the following command.
java pdf
And I got the following output,
Exception in thread "main" java.lang.NoClassDefFoundError: pdf (wrong name: pdf/pdf)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
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)
What am I doing wrong?
Thanks in advance.

Didn't you mean java pdf.pdf as your pdf class is in the pdf package ?
If your pdf class is in the pdf package it should be in a pdf directory (as in if your MyClass class is in my.package package, it should be in my/package/ directory).
Either you go into the pdf directory and use the -d option javac -d . pdf or you go in the parent directory and do javac pdf/pdf.java`

When you compiled it so, the pdf.class was generated in current directory. Change it to:
javac -cp core-renderer.jar:iText-2.0.8.jar -d . pdf.java
Which will generate pdf.class in ./pdf subdirectory. Then run it as follows:
java -cp .:core-renderer.jar:iText-2.0.8.jar -d . pdf.java

First, since the class is declared as in a package, you have to store it and call it using the package path.
You need to create a directory structure that matches the package structure. In your case, you need to create a directory called pdf and move pdf.class into it.
Then you would call with `java pdf.pdf' as pointed out in Colin's answer.
This might be sufficient to run your current sample code, since it doesn't really do much of anything. Once you get to adding more functionality, you will likely need to include your libraries on the classpath when executing, as described in Richard's answer.
BTW, it is conventional in Java programming to initcap class names, e.g. Pdf would be the class name in your example, while pdf would be the package name.

Classpath for compile-time and for run-time are two different things. However, they are often identical since compilation dependencies are identical as runtime dependencies. Since your main() method throws something defined in iText-2.0.8.jar (I think), you sould define your classpath accordingly:
java -cp .:iText-2.0.8.jar pdf.pdf

Related

Java Classpath NoClassDefFoundError During Runtime

I am coming back to Java after quite some time. Having a little trouble with classpath. Would really appreciate it if someone could please point me in the right direction!
My folder structure is as follow:
├── lib
│ └── algs4.jar
└── src
└── HelloWorld.java
HelloWorld.java
import edu.princeton.cs.algs4.StdOut;
public class HelloWorld {
public static void main(String[] args) {
StdOut.println("Hello World");
}
}
I compiled my program with the following cmd
cd src
javac -cp ../lib/* HelloWorld.java
However, when I run my program using java HelloWorld, I get the following error.
Exception in thread "main" java.lang.NoClassDefFoundError: edu/princeton/cs/algs4/StdOut
at HelloWorld.main(HelloWorld.java:5)
Caused by: java.lang.ClassNotFoundException: edu.princeton.cs.algs4.StdOut
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
I dont understand how it compiles fine, but then its unable to find classes at runtime. Could someone please shed some light on this ? Thank you in advance!
It was painful, but I finally fixed it. Turns out when running the program, you not only have to specify the location of the JAR files, but you also have to specify the location of your own file. (Seems obvious now >.<)
For example, in my case, running the following is not good enough.
java -cp ../lib/* HelloWorld
We included the the JARs but didn't include the folder that actually contains HelloWorld.class.
To fix this, I had to run the following. We are including the location of the JAR and the location of the file being executed.
java -cp ../lib/*:. HelloWorld
(Some of you might have to escape * depending on your OS / shell settings)
To execute your program you also need to pass the classpath to the java command like this.
java -cp ../lib/* HelloWorld
When you've compiled your code you told the compiler to use the ../lib/* directory(and files) to look up for class definitions, of course, the compiler found them, and write the byte code in the HelloWorld.class file but this bytecode only contains your code (the lines you wrote in HelloWorld.java) for any external library you use there the compiler will only store a sort of reference with the full package name and the method name. No bytecode from the jar will be stored in the HelloWorld.class file.
So to execute HelloWorld you need to tell the JVM to load first all the external classes that you in the code passing them with the -cp parameter.
Then, the JVM will execute your code, look for the reference to the jar code via package/method name and execute them.
If you don't provide -cp ../lib/* the JVM will load only the standard library (All the classes in JDK) and your HelloWorld.class thus it won't find the external jar in memory.

Java error - bad source file: file does not contain class x . Please remove or make sure it appears

Recently started studying Java for an exam.
While learning packages, tried this and got an error message. What I did was
//Creating class A (Within package the package: com.test.helpers)
package com.test.helpers;
public class A {
public void sayHello(){
System.out.println("Hello World");
}
}
//And then the class App utilising the class A
import com.test.helpers.*;
public class App{
public static void main(String args[]){
A a = new A();
a.sayHello();
}
}
I had both of these files in a directory called 'JavaTest' (on Windows 7), and first compiled the A.java using the command javac -d . A.java
And then, while attempting to compile App.java, I got the following error message:
App.java:5: error: cannot access A
A a = new A();
^
bad source file: .\A.java
file does not contain class A
Please remove or make sure it appears in the correct subdirectory of the source path.
1 error
However, the problem seems to resolve in two ways,
Deleting the Source file A.java
Changing the import statement from import com.test.helpers.*; to import com.test.helpers.A in the file App.java.
I'd be highly grateful if you can explain what happens here. Or I might be making a goofy human mistake or a syntax error.
Here's the link to the source files
Hi the problem here is that the JVM confuses the class file due to the ambiguous class file name in both the directory (the JavaTest as well as the com.test.helpers directory).
when you do javac -d . A.java the compiler makes a class file in the directory com.test.helpers and now it confuses it with the sourcefile there in JavaTest
Deleting the Source file A.java
When you delete the source file A.java from JavaTest, JVM knows now that the class file in com.test.... is to be used, ambiguity goes away.
Changing the import statement from 'import com.test.helpers.*;' to 'import com.test.helpers.A' in the file, 'App.java'.
Here you are specifying which particular file to use in your class implementation that is you are telling the compiler to use the file A.java from com.test... and not from JavaTest package
Now, the solution for this ambiguity to not ever be a problem for you, you must import the specific files with import statement i.e. import com.test.helpers.A; or if you want to do import com.test.helpers.*; then you must specifically use com.test.helpers.A in place of A everywhere in your current class implementation to tell the compiler not to confuse it with the source at JavaTest
I know it's a lot late for this particular answer, but I wanted to share my views for the upcoming readers, if it could help them in any way, it would be great.
Thanks!
move the A.java under folder JavaTest to com/test/helpers. the error you are seeing is for the compiler complaining that A.java is in a folder that does not match its package declaration. Remember, you cannot access A from App without A being in a package.
from under src driectory run the following command to compile your classes
src> javac ./*.java ./com/test/helpers/*.java
then from under src folder
src>java App
that should run your program.
the file A.java should be in the path JavaTest\com\test\helpers\A.java
and don't forget to compile it like this:
javac -d . com\test\helpers\A.java
every thing is in right place, java does not ask to put your A.java file, in the helpers folder
the whole reason why your code ran with the A.java file removed and not otherwise is:
when your app.java (or the main java file which is importing other classes in it, -->) is in a default package then while importing the classes it gives priority to the same directory and not to the package directory(if there exist any file that has the same name as the class file -> and thats why it gives error bad source file A.java -> as it wanted A.class)
And because of that there is a rule in java : That never place a .java file (of the same name)in parallel to the packages
so to solve this problem you have to either remove the file, A.java
or rename it (to any other name that does not present in the package)
or you can use fully qualified import statement
I have the same problem finally,
I was solved.
//Use like this
import com.test.helpers.A;
If u have a more than class in com.test.helpers then u can use import com.test.helpers.*;
If you are not using an editor with auto-save, it might be helpful to check if the code you have written has actually been saved to the java file previously created
The bad source file error may be wrong if it is preceded by another error (below) which, in my case, provided guidance for how to fix the real problem. From my log file:
Error 1: a\g\GoodClass error:duplicate class: a.g.GoodClass //Not the problem
Error 2: a\b\BadClass error: cannot access GoodClass //The problem
bad source file: a\g\GoodClass //No, it's fine
file does not contain class x.y.GoodClass //How to fix it
Please remove or make sure it appears in the correct subdirectory of the sourcepath.
Java reports the first line of Error 2 because BadClass is using a wildcarded import, either import x.*; or import x.y.*;.
THE FIX: remove the wildcarded import from BadClass and add only the specific imports you need from library x.y.

Setting up my Java Environment. Jar/CLASSPATH

So I started working with Java. I am currently on Ubuntu Platform. I installed the jdk and it was working fine during the initial stages. Then I turned to chapter 'ACCESS CONTROL' and there it started talking about the CLASSPATH and jars.
Here's what I have done.
On my Desktop I create a folder A and in that I create file Aa.java
package home.kraken.Desktop.A;
class Aa{
public doSome(){
System.out.println("AA");
}
}
On Desktop I have another folder B and file Bb.java in that
package home.kraken.Desktop.B;
import home.kraken.Desktop.A.*;
class Bb{
public static void main(String[] args){
Aa a = new Aa();
a.doSome();
}
}
Now, when I run Bb.java I get error that it can not find Aa.
Ok, I understand that CLASSPATH is something, some variable that provides the location to search for other classes. Now here are my questions
How do I know what my CLASSPATH is?
In the first statement, I have written the complete address of the folder it is in. Even then it wont find it? Does my project has to be pointed by CLASSPATH only?
Say my CLASSPATH points to Desktop [i.e. I set the value of CLASSPATH], now for every file I create, if I want to import some other class, then I will import RELATIVE_ADDRESS_TO_DESKTOP?
How do I set the value of CLASSPATH?
What exactly is jar. I understand it is the collection of Class FIles but do I explicitly make a jar file using some command or ...How does it work?
Thanks.
EDIT
So here's what I did
My classpath originally was empty so I did
export CLASSPATH="$CLASSPATH:/home/kraken/Desktop"
Now Inside folder Desktop/A, I have
package A;
public class Aa{
public void doSome(){
System.out.println("AA");
}
}
And inside folder Desktop/B, I have
package B;
import A.*;
class Bb{
public static void main(String[] args){
Aa a = new Aa();
a.doSome();
}
}
Now, I do javac Aa.java
And javac Bb.java
And when I do java Bb [ Inside folder Desktop/B To run the program, it says ]
Exception in thread "main" java.lang.NoClassDefFoundError: Bb (wrong name: B/Bb)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
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: Bb. Program will exit.
What is happening here?
EDIT 2
When I do java B.Bb [Inside Folder B.Bb] It prints out AA.
If someone can explain what is going on?
1) How do I know what my CLASSPATH is?
It is a system environment variable. On UNIX/Linux, you type "echo $CLASSPATH" to see what it is set to.
2) In the first statement, I have written the complete address of the
folder it is in. Even then it wont find it? Does my project has to be
pointed by CLASSPATH only?
That is a package name. It tells Java where to look within the classpath. Normally, the package name doesn't match the absolute path of the file. For example, suppose I have a class located on my file system /user/local/com/stackoverflow/foo. Java needs the classpath set to /usr/local so it knows where to look for the class. Similarly, the file might be in the jar and the classpath says were to look in the jar.
3) Say my CLASSPATH points to Desktop [i.e. I set the value of CLASSPATH], now for every
file I create, if I want to import some other class, then I will import
RELATIVE_ADDRESS_TO_DESKTOP?
Yes. Your CLASSPATH points to the "root" of your package statement.
4) How do I set the value of CLASSPATH?
export CLASSPATH="$CLASSPATH:textToAddToClasspath"
5) What exactly is jar. I understand it is the collection of Class FIles but do I explicitly
make a jar file using some command or ...How does it work?
Yes, a jar is a collection of class files. You create it using "jar -cvf jarname.jar *.class" or the like
Put Aa.java and Bb.java in the same folder.
I believe that the JDK packages are set by default.
So, if you put the two files in the same folder, all you have to do is set the classpath to the folder that you have everything in.
java -classpath /home/user/myprogram org.mypackage.AA.java
or whatever your file structure is ^^
this should get your program to work

Hadoop: strange ClassNotFoundException

I am getting a classnotfound exception. The class which is claimed to be not found does not exist, but the class name is set as the path to the list of input files for my map reduce jobs.
INFO server Running: /usr/lib/hadoop/bin/hadoop --config /var/run/cloudera-scm-agent/process/155-hue/JOBSUBD/hadoop-conf jar tmp.jar /user/hduser/datasets/ /user/hduser/tmp/job_20/ mongodb://slave15/db_8.job_20
Exception in thread "main" java.lang.ClassNotFoundException: /user/hduser/datasets/
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.apache.hadoop.util.RunJar.main(Runjar.java:190)
As we can see, the /user/hduser/datasets/ is the path to the input files. Why am I getting this error as ClassNotFoundException? Why does it see it as a class?
I found my own error. I have a package structure. I need to specify my package information
/usr/lib/hadoop/bin/hadoop
--config /var/run/cloudera-scm-agent/process/155-hue/JOBSUBD/hadoop-conf
jar tmp.jar org.myorg.tmp /user/hduser/datasets/
/user/hduser/tmp/job_20/ mongodb://slave15/db_8.job_20
In my tool, there is no option for giving the package as argument to Java. So I need to have no packaging. But then I am having the following error since the argument before this input file path is missing.
My classes are directly in the tmp.jar in its root. I mean no org.myorg etc...
SOLUTION:
jar cmf [manifest_file] [jar_name.jar] -C [folder_of_classes] [path_for_jar_file]
it will merge the content of the manifest_file with the generated manifest file in the jar archive. Include the following line in the manifest_file
Main-Class: [Name_Of_Class]
Whether or not there's a package hierarchy (and if there isn't, you've done Something Wrong) you still need to give it the name of the class containing main.
For example, the docs have an example where the main class is org.myorg.WordCount. Even if WordCount was in the default package, it should be specified if the jar file doesn't include a main class in the manifest:
bin/hadoop jar /usr/joe/wordcount.jar WordCount /usr/joe/wordcount/input /usr/joe/wordcount/output
I'd assume you could also specify the main class in the manifest as with any jar; the class argument is shown as optional in those same docs.

Can you run a .class file from terminal that is outputted by an IDE

I am trying to run a file from command line. The file is a .class file and is apart of a larger project that I compiled in Netbeans. I navigated to the .class file and ran
java MyFile
And I got:
Exception in thread "main" java.lang.NoClassDefFoundError: PersonTest/class
Caused by: java.lang.ClassNotFoundException: PersonTest.class
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: PersonTest.class. Program will exit
Whats up with that? (I should mention that i'm running ubuntu)
You need to check this useful link java - the Java application launcher:
By default, the first non-option
argument is the name of the class to
be invoked. A fully-qualified class
name should be used
So, you have to write the full qualified name of the class (this includes the package name).
So, the right way to execute your command is this (from the root dir where your class files are stored):
> java my.package.MyFile
Also, make sure to include all the needed dependencies at the classpath (-cp) argument (check the referenced link).
UPDATE: to include a classpath setting example:
java -classpath C:\MyProject\classes;C:\MyProject\lib\utility.jar my.package.MyFile
With this, the java runtime will search for the classes at the C:\MyProject\classes directory, and at the C:\MyProject\lib\utility.jar JAR file. You'll need not only your class direct dependencies, but the dependencies needed by the referenced files (the whole tree).
The answer appears to be in this line:
Exception in thread "main" java.lang.NoClassDefFoundError: PersonTest/class
It means you didn't type:
java MyFile
as you said in your original post, you typed
java PersonTest.class
you should have typed
java PersonTest
Yes you can, they are compiled by a java compiler. If you have the right version of the jvm (often other versions work aswell) than it can be run. The information about your error is not enough to tell what went wrong.
Your probably in the wrong folder, mistyped the classname, used a class in your code that couldn't be found, etc.
Unless your class is entirely standalone (i.e. only references java.lang classes like String), you'll need to add other classes/JARs to the classpath when you invoke Java.
The NoClassDefFoundError (which usually states the name of the class by the way, and always includes a stacktrace) indicates that an external class that was available when your class was compiled, is not available on the classpath at runtime.
EDIT based on update:
You're invoking your process incorrectly. You don't need to append the .class suffix of the file - doing so makes Java look for a file class class in a subpackage.
(P.S. you said you ran java MyFile. That's a lie, you actually ran java PersonTest.class. If you'd noted that to start with, it would have made it much easier for people to answer the question!)
Just consider this example
say I already have a folder src and I wrote in my notepad
package test.oye;
class testclass {
static public void main (String [] args)
{
int a=3;
System.out.println(a);
}
}
then what go to src folder and you ,yourself create a folder named test and inside it oye . Then put your .java file in it . Then cd src/test/oye only(in Command prompt or terminal).From there itself
javac testclass.java
cd src
java test.oye.testclass
This will work for sure.
If you don’t want to put .java file there … then just compile your .java file and get the .class file .
Now create the test folder and then oye inside it ….and put .class file inside it ….
Now go back to src …and then type
java test.oye.testclass;
according to terminal ide, android requires classes in DEX format when running them.
Try:
dx --dex --output=practice.jar practice.class
Then run using this:
java -jar practice.jar practice

Categories

Resources