Friday, January 28, 2011

How to Set Classpath for Java on Windows Unix and Linux

CLASSPATH in Java

I have experience in finance and insurance domain and Java is heavily used in this domain for writing sophisticated Equity, Fixed income trading applications. Most of these investment banks have written test for Java and I always fine at least one question related to CLASSPATH in Java on those interview. Java CLASSPATH is one of the most important concepts in java but I must say mostly overlooked. This should be the first thing you should learn while writing java programs because without understanding of Classpath in Java you can't understand how java locates your class files.

So let’s start with basic and then we will see some example and improvisation of Classpath in Java. In Fact CLASSPATH is an environment variable which is used by Java Virtual Machine to locate user defined classes. 
This article is in continuation of my articles How HashMap works in Java and Why String is immutable in Java and In this tutorial we will see how to setup classpath for java in windows and Linux , java -classpath example in different scenario and use of java -classpath or java -cp.

Setting Java Classpath in Windows

For setting Java Classpath in Windows (any version either Windows XP or Windows 2000) you need to specify value of environment variable CLASSPATH, name of this variable is not case sensitive and it doesn’t matter if name of your environment variable is Classpath, CLASSPATH or classpath in Java.

Here is Step by Step guide for setting Java Classpath in Windows:

    Setting Java Classpath in windows and Unix Linux
  1. Go to Environment variable window in Windows by pressing "Windows + Pause “-->Advanced -->Environment variable " or you can go from right click on my computer than choosing properties and then Advanced and then Environment variable this will open Environment variable window in windows.
  2. Now specify your environment variable CLASSPATH and put the value of your JAVA_HOME\lib and also include current directory by including (dot or period sign).
  3. Now to check the value of Java classpath in windows type "echo %CLASSPATH" in your DOS command prompt and it will show you the value of directory which are included in CLASSPATH

Setting Java Classpath in UNIX or Linux

To set Classpath for Java In Linux you can simply export CLASSPATH="your classpath" from either your .bash_profile or .bashrc script which will run whenever you login into your Linux or Unix Machine.
Now to check value of Java CLASSPATH in Linux type "echo ${CLASSPATH}.
I hope this example for setting classpath in Java will enable to set classpath by yourself let me know if you face any problem while setting up classpath in Java

Overriding Classpath in Java

You can override value of Java classpath defined by environment variable CLASSPATH by providing option "-cp" or "-classpath" while running your program and this is the best way to have different classpath for different application in Java. General way to define classpath is in the startup script of any program. e.g.
CLASSPATH=/home/tester/classes
java -cp $CLASSPATH Test

By default Java CLASSPATH points to current directory denoted by "." and it will look for any class only in current directory.

Different example of using Classpath in Java

In case you have multiple directories defined in CLASSPATH variable, java will look for a class starting from first directory and only look second directory in case it did not find the specified class in first directory. This is extremely useful feature of Classpath in java to understand and it’s very useful for patch release kind of stuff. Let’s see  java -classpath example

I have my CLASSPATH=/home/tester/first:/home/tester/second
Now I have "Test" class of different version in both first and second directory so when I give a command
"java Test" What will happen ? Which Test class would be picked?
Since JVM search directory in the order they have listed in CLASSPATH variable it will first go to the "first" directory and if it finds "Test" over there it will not go to "/home/tester/second" directory.
Now if you delete Test class from /home/tester/first directory it will go to /home/tester/second directory and will pick "Test" class from there.

I have used this feature of Java Classpath to test my patch releases, we used to have a folder called "patch" listed as first element in Java CLASSPATH and any point of time we want to put any debug statement or want to test any bug we just modify Java source file , compile it and generate class file and put that inside patch folder instead of releasing whole new jar and this comes very handy if you are working in a large project where you don't have development environment setup in Windows and your project only runs on Unix server.
Its also worth noting that when you use the -jar command line  option to run your program as an executable JAR, then the CLASSPATH environment variable will be ignored, and also the -cp and -classpath switches will be ignored. 

In this case you can set your Java classpath in the META-INF/MANIFEST.MF file by using the Class-Path attribute.
Now a common question if I have my CLASSPATH variable pointing to current directory "." and I have class called "Test" inside package "testing" and with below directory structure C:\project\testing\Test.class in my computer.
What will happen if I run command "java Test" from directory "C:\project\testing\" will it run?
No it will not run it will give you Exception in thread "main" java.lang.NoClassDefFoundError: Test
Since name of the class is not Test, instead it’s testing. Test even though your classpath is set to current directory.

Now what will happen if I give command “java testing.Test “from” C:\project\testing\, it will again not run and give error?

Exception in thread "main" java.lang.NoClassDefFoundError: testing/Test
Why because now it looking for class called Test which is in package testing, starting from current directory "." but don't find it since there is no directory called "testing after this path "C:\project\testing\".

To run it successfully you need to go back to directory "C:\project" and now run
C:\project>java testing.Test
It will run successfully.

Errors related to Classpath in Java

If you are working in Java you must have faced some errors and exception related to classpath in java, two most common issues related to java classpath is ClassNotFoundException and NoClassDefFoundError. I have seen that most of java developer tries to solve this error by trial and error; they just don’t look beyond the hood and try to understand what the reason for these java classpath related errors is. They often misunderstood that these two errors are same also.

Here is the reason of these java classpath errors:

ClassNotFoundException is an Exception and will be thrown when Java program dynamically tries to load a particular Class at Runtime and don’t find that on Java classpath. Two keyword here “dynamically” and “runtime”. Classic example of these errors is whey you try to load JDBC driver by using Class.forname(“driver name”). So this error essentially comes when Java try to load a class using forName() or by loadClass() method of ClassLoader. Key thing to note is that presence of that class on Java classpath is not checked on compile time. So even if those classes are not present on Java classpath your program will compile successfully and only fail when you try to run.


On the other hand NoClassDefFoundError is an Error and more critical than ClassNotFoundException which is an exception and recoverable. NoClassDefFoundError comes when a particular class was present in Java Classpath during compile time but not available during run-time. Classic example of this error is using log4j.jar for logging purpose and forgot to include log4j.jar on classpath in java during run-time. to read more about logging in Java see . Keyword here is “class present at compile time but not available on run-time”. This is normally occurring due to any method invocation on a particular class which is part of library and not available on classpath in Java. This is also asked as common interview questions as  
What is difference between NoClassDefFoundError and ClassNotFoundException Exception in Java   or
“When do you see NoClassDefFoundError and ClassNotFoundException Exception in Java”.


Summary of CLASSPATH in Java

1.      Classpath in Java is an environment variable used by Java Virtual machine to locate or find java classes during class loading.

2.      You can override value of Classpath in Java defined by environment variable CLASSPATH by providing JVM command line option –cp or –classpath while running your application.

3.      If two classes with same name exist in Java Classpath then the class which comes earlier in Classpath will be picked by Java Virtual Machine.

4.      By default CLASSPATH in Java points to current directory denoted by "." and it will look for any class only in current directory.

5.      when you use the -jar command line  option to run your program as an executable JAR, then the Java CLASSPATH environment variable will be ignored, and also the -cp and -classpath switches will be ignored and In this case you can set your java classpath in the META-INF/MANIFEST.MF file by using the Class-Path attribute.

6.      In Unix of Linux Java Classpath contains names of directory with colon “:” separated , On Windows Java Classpath will be  semi colon “;” separated while if you defined java classpath in Manifest file those will be space separated.

7.       You can check value of classpath in java inside your application by looking at following system property “java.class.path
System.getProperty("java.class.path")

Class-Path attribute is used to contain classpath inside manifest file. Also make sure that your manifest file must end with a blank line (carriage return or new line) , here is an example of java classpath in manifest file.

Main-Class: com.classpathexample.Demo_Classpath
Class-Path: lib/tibco.jar lib/log4j.jar


8.       It’s also important to note that path specified in manifest file is not absolute instead they are relative from application jar’s path. For example in above if your application jar file is in C:\test directory you must need a lib directory inside test and tibco.jar and log4j.jar inside that.

9.       ClassNotFoundException is an Exception and will be thrown when Java program dynamically tries to load a particular Class at Runtime and don’t find that on Java classpath due to result of Class.forName() or loadClass() method invocation.
10. NoClassDefFoundError comes when a particular class was present in Java Classpath during compile time but not available during runtime on Classpath in Java.

I hope you find this Java Classpath tutorial useful , please let me know if you have any doubt or any question related to "How to set classpath for java" and I would be happy to answer :) keep learning. Your suggestions and comments are always welcome.  If you like to read UNIX command tips you may find  10 tips of using find command in Linux 10 tips to increase speed on Unix command and  10 basic networking Commands in Unix useful.



Related post:



Please vote +1 or consider sharing if your like this article

35 comments:

Anonymous said...

Appreciate great patience for writing in detail.

http://extreme-java.blogspot.com

Adam S. said...

Very nice article. I did not know about the -jar classpath implications. How do you specifiy classpath in META-INF (relative and absolute) ?

You forgot to mention "endorsed" folder.

Javin @ Tibco RV Tutorial said...

Thanks Sandeep. Given importance of Classpath and its usages this is my small effort :)

Javin @ Tibco RV Tutorial said...

Hi Adam,

Thanks you liked the article. A Class-Path entry is used to specify jar's you would like to include in your Claspath, for example:

Class-Path: tibco.jar tibrvjms.jar tibco/tibcohawk.jar

With this header, the classes in the files tibco.jar, tibrvjms.jar, and tibco/tibcohawk.jar will serve as extensions for purposes of the applet or application. The URLs specified in Class-Path entry are given relative to the URL of the JAR file of the applet or application.

I do not about "endorsed" folder though , would be great if you could provide some more details to us.

Thanks
Javin

Adam S. said...

JAVA_HOME/lib/endorsed - jars from this directory are also loaded. Intended use is to replace classes shipped with java, especially for technologies are in development between major java releases.

Location of this directory can be changed by setting system properties.

There are also these parameters, but I am not sure what the "intended" use is for them.

-Xbootclasspath:bootclasspath
-Xbootclasspath/a:bootclasspath
-Xbootclasspath/p:bootclasspath


Also comment to this:
"By default CLASSPATH points to current directory denoted by "." and it will look for any class only in current directory."

The way it works, if you do not specify neither -cp nor -classpath and CLASSPATH is not set, then the classpath defaults to "."

Starting with java 1.6 you can also specify a * in a classpath, e.g.:
/mylibs/*

this is going to be expanded to include all files ending in .jar or .JAR

Javin @ Tibco RV Tutorial said...

Thank you very much Adam for letting us know about "endorsed" directory and adding value to this blog. I am too not sure about -Xbootclasspath:bootclasspath but will post when I come to know about it.

Thanks
Javin

Anonymous said...

We have urjent requirement for CMM Level 5 company at hyderabad.4-8yrs, send cv s to suhasini@further2gether.com

Anand said...

nice explanation on the usage of classpath. I blog on finance topics also. You may wanna check it out :)

Anands Blog

Keep blogging!!!

Anand.

Srinivas Reddy said...

I have a doubt in this tutorial sir.
You said that classpath is an env var which locates .class files stored in our computer.
But while writing programs, we generally give something like "C:\jdk1.4.1\bin;"
But the .class files of our programs may be in any directory.
So how does the system locate the .class file.

Anonymous said...

i appreciate your efforts in providing detailed information about class paths. Unfortunately, it makes me feel even dense because I still cannot figure out the solution to my problem when trying to run my own projects in sphinx

is there a more detailed sphinx link (besides what they have on their main site) that will help me more with my problem im having? thank you in advance! :) Exception in thread "main" java.lang.NoClassDefFoundError: cmu.edu.sphinx.demo.RobotTest
Caused by: java.lang.ClassNotFoundException: edu.cmu.sphinx.demo.RootTest

I know this might not have enough information but i really need someone to help me walk through this. HELP!

Kind regards,

Dekita

Anonymous said...

last comment was sent by dekitamoon@hotmail.com. Thanks

Anonymous said...

great article about java classpath mate, I have read couple of articles on java claspath but this one is simply great especially your tip on using classpath for debugging in java. by any chance do you know how to set classpath for eclipse and netbeans IDE ?

Javin said...

Thank Anonymous you like my java classpath tutorial.I really like you find my experience useful.as far as setting java classpath on eclipse and netbeans they have there own build configuration in Eclipse just right click the project and select properties--> build path it will show you libraries which are in java classpath.

Sujata said...

Hi, Can we set java classpath at run time ? for example setting java classpath to find out new .class files or modified class files ?

Anonymous said...

You can also use java -verbose option to find out what classes are loading at run-time from classpath in java. Also from JDK 6 onwards you can use
wild-cards in classpath for example C:\java-classpath-test> javac -cp C:\Java\JDK1.6\lib\* and it will include all jar files form lib folder.

Anonymous said...

what is difference between PATH and Classpath in Java ? I always get confused between these two Can you please help ? Also how to set both PATH and CLASSPATH ?

Anonymous said...

I have read many articles on Java classpath but most of them don’t explain how exactly classpath works in Java and How does JVM finds java classes. This becomes more important if you have same class in more than two jars in classpath

Anonymous said...

If you are using Java 1.6 and using wildcard to specify classpath make sure you don't have anything else than .jar file in your directory specified by wildcard , otherwise you could run into problem of "invalid classpath".

e.g. C:\Java\JDK1.6\lib\* will include everything inside lib , so if you have something which is not jar e.g. a directory test , you will run into problem.

Nay Lin Soe said...

Hi Javin,

Great article you've got there. I have a small problem. I happened to add the line
CLASSPATH=""
into /etc/environment file. Perhaps a stupid thing to do.

Now, though I can still compile (javac) from the terminal, I can't run (java) anymore. All return NoClassDefFoundError. Even after removing the line I added. Please help.

Regards,
Nay

Anonymous said...

perhaps you would like to change the title of post as "How to set Classpath for Java" which is more suitable.Claspath in Java is tricky until you have complete knowledge and it can be pick and overridden from various places e.g.

1) default classpath current directory "."
2) Classpath Environment variable
3) path provided by option -cp and -classpath
4) Classpath specified in Manifest file if you are running using java -jar option.

Anonymous said...

Hi, is there any difference on setting classpath in windows XP and windows 7, I am going to buy new windows 7 license and wondering about setting PATH and Classpath on that,Please help.

Anonymous said...

Can you also write about how to set CLASSPATH and PATH in Eclipse IDE and Ubuntu Linux.

Sandeep Kumar said...

Nice tutorial. You can also refer this link to to set environment variables PATH, CLASSPATH and JAVA_HOME for compiling and running of Java applications. http://www.a2ztechguide.com/2011/10/setting-environment-variables-javahome.html

Javin @ hostname to IP address in windows said...

Thanks for comment Sandeep. You may also like my article How to Set Path for Java

Anonymous said...

i had no problem, until i have installed "window builder pro" and have deleted again. Then i could not run my project. But thank you very much. "Classic example of this error is using log4j.jar for logging purpose and forgot to include log4j.jar on classpath in java during run-time." it was the answer of my problem..:) i dont know, how it was deleted from my classpath. But it's going now.

Anonymous said...

Why do you need to set ClassPath in Java explicitly, Can't it get it from jar file and execute from there ?

Javin @ Enum examples in java said...

@Anonymous, yes you can setup Classpath inside Jar file in Java. Manifest file is used for same purpose.

Indira Pudale said...

Very nice article. I have been reading your posts for some time. I really enjoyed all this brain food. Thanks a lot for sharing...Keep writing..

Anonymous said...

why don't you set a smaller font? this is too big!

vinayaka dj said...

i am not able to execute jar command. i dont know what to install for executing jar command,it showing command not found, also their is no file called jar in "C:\Program Files\Java\jdk1.6.0\bin".

Thank you,

Anonymous said...

I agree Understanding of ClassPath is important in order to avoid and debug notorious ClassNotFoundException and NoClassDefFoundError and you have done a good job on explaining both how java picks classes based on classpath and how to set classpath for java.

Anonymous said...

when i have compiled my servlet program its compiling successful while running its generating class not found exception and i am using windows vista

Anonymous said...

Hi, This my attempt to get some advice on an issue we're experiencing. Evrytime an auto update takes place our server gets wacked. here's the classpath setup.
Here is what I think the problem is…

There is a batch file named setclasspath.bat in D:\SafeWatch\Tomcat\bin on the Safewatch server.
This batch file references an environment variable named JAVA_HOME.
This environment variable has a value of C:\Program Files\Java\j2re1.4.2_08.
Java version 1.4.2_08 is the current java version running on the server…

I wonder if there could be a “Variable’ inserted in the Java-Home path setup that provides the latest “Java update Version” value after the update takes place.

ex: C:\Program Files\Java\%UpdateVersioNumber%

I'm don't know Java but been asked to resolve this challange.

thanks for your consideration.

Javin @ how to run Java Program said...

@Anonymous. you could possibly write a script which can check each java folder and can setup JAVA_HOME accordingly. look on PERL or shell script or even a simple DOS script if you are running on windows.

Anonymous said...

Thanks will pursue this.

Post a Comment

What is this blog about

This blog is about my experience in Java, Tibco Rendezvous and FIX protocol. FIX is a technology which is used to build equity trading system and heavily used in electronic trading , high frequency trading and Algorithmic trading, so on most of Investment bank job you need to know FIX Protocol on the other hand Tibco Rendezvous is used to implement messaging backbone on many big commercial and global banks. This blog help you to get clear any FIX protocol job interview. It also includes Java and Tibco Rendezvous article written for new user mainly my experience in my own word.