Monday, August 27, 2007
Java "class"-ic errors
Few errors are so common (Frequently Faced Errors or FFEs?) - asked many times in forums, email lists (internal/external) - and it is frustating to face one of these "starting problems". I am talking about the classloading errors with Java. I'll try to list few common errors and most probable reasons.
Two possible reasons:
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/Object
- You are trying to run 64-bit JVM (SPARCv9 or AMD-64) with -d64 option. But, you did not install 32-bit JVM. Yes, to run 64-bit JVM you have to install a 32-bit JVM and then install 64-bit binary on the same directory
- You are playing with -Xbootclasspath option (why? - in most scenarios it is wrong!) and you didn't include rt.jar in boot class path
Reason: You are trying to run a class compiled with newer version of JDK. For example, you have compiled the class with JDK 5.0 and try to run on JDK 1.4.2. Class file major/minor version evolves with major JDK releases. Each JDK version supports only upto a specific class file major.minor version.
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
(or)
Unsupported major.minor version 49.0
- Java SE 6 class file version 50.0 or below
- JDK 5.0 class file version 49.0 or below
- JDK 1.4.2 class file version 48.0 or below
Reason: The class name as in .class file is different from what is specified in command line. In the above error scenario, the .class file has the name "t" (in unnamed global package) but user attempted to load it as "tmp.t" (t in tmp package). You have to check package declaration in your source files and confirm that the files are under proper subdirectories (use javac's -d option to put .class files under correct subdirectories). Also you may want to check directory, file name case -- remember to do this on case insensitive file systems as well. It is better to use jar files whenever possible (rather than directories)
Exception in thread "main" java.lang.NoClassDefFoundError: tmp/t (wrong name: t)
This is good (bad?) old error! It is better to check
Exception in thread "main" java.lang.NoClassDefFoundError: x
- the value of CLASSPATH environment variable
- the value passed as -classpath or -cp option
- check that proper path separator (; on Windows, : on Unix - it is easy to miss or use wrong separator for your OS) is used in your classpath specification
- Remember that "." (the current directory) is included by default in classpath - but if you have specified CLASSPATH, then that overrides. i.e., With CLASSPATH specified, "." is not automatically added to classpath.
- With Mustang (Java SE 6) you can put all your all jar files in one or fewer directories and use classpath wildcards to avoid typos in jar file names.
- When in doubt, check again before posting to forums Yes, typos are quite common
- Turn on -verbose:class. This prints debug info on each class load. The source of the class file loaded (rt.jar , foo.jar) is also printed along that.
- Check your configuration. There are many ways to pass arguments to running JVM. (command line argument, environment variables, config files of app/web servers). You may want to check what actual arguments were "seen" by the JVM. You can check these using The value of the System property java.class.path is the application classpath used. Similarly, the value of the System property sun.boot.class.path is value of bootstrap class path (Sun specific).
No comments yet