6/03/2006

6 Ways of Setting Java Classpath

How to set Java classpath? List as many ways as you can. This can be an interesting Java job interview question. Here are what I came up with:

  1. Use -classpath JVM option:
    java -classpath C:\hello\build\classes com.javahowto.test.HelloWorld
  2. Use -cp JVM option, a short form of -classpath:
    java -cp C:\hello\build\classes com.javahowto.test.HelloWorld
  3. Use -Djava.class.path system property:
    java -Djava.class.path=C:\hello\build\classes com.javahowto.test.HelloWorld
  4. Use CLASSPATH environment variable:
    set CLASSPATH=C:\hello\build\classes;
    java com.javahowto.test.HelloWorld
  5. Use current directory as the default classpath:
    cd C:\hello\build\classes;
    java com.javahowto.test.HelloWorld
  6. Package all classes into a self-containing jar file that has this in its META-INF/MANIFEST.MF.
    Main-Class: com.javahowto.test.HelloWorld
    java -jar hello-world.jar
    Note: when you run java with -jar option, any -classpath, or -cp options, or CLASSPATH environment variable are ignored, as JVM thinks all classes are already contained inside the jar file, or referenced via the Class-Path entry in its META-INF/MANIFEST.MF.
Among all those options, I usually use option 1, and occasionally 6. I don't like my Java apps have dependency on environment settings like CLASSPATH, which is totally unpredictable. Using current directory as the default classpath is not a good idea either, since your classes may be scattered in several directories, folders and jar files.

Can I set classpath at java runtime dynamically and programmatically? No. Although you can set the system property java.class.path in your application, but its new value doesn't affect the system classloader. If you need to reset classpath, it's time to consider using a custom classloader as the child loader of the system classloader.

With a custom classloader, you have full control where to load class files, from local file system, remote url, or even database. Classes loaded by such a custom loader are only visible by this loader and its child loaders, but not to its parent loader nor the system classloader.

For the same reason, you can't dynamically set minimum/maximum heap size of a JVM. These JVM options are all set once when JVM is started and unchanged throughout its life.

JDK 6 now support * in classpath, so you can include all jar files in a directory to the classpath easily. But you may run into problems described in http://javahowto.blogspot.com/2006/07/jdk-6-supports-in-classpath-but-be.html


17 comments:

Anonymous said...

This would be a complete waste of time as a question in an interview. This info is needed so rarely (if ever) when developing. This wouldn't tell you anything at all about the interviewee.

howto said...

These knowledge is used in everyday Java. How can one debug any classpath problems if he/she doesn't understand this?

You won't need them when you are coding, but you do when you are running and debugging apps.

Anonymous said...

Setting the classpath in Eclipse or tomcat is important knowledge. It's also knowledge that can easily be found by a google search.

Requiring interviewees to memorize obsure details about command line Java is of little use.

Asking questions about how many obsure ways you can do some trivial little thing is not a good interview question.

howto said...

Maybe using -Djava.class.path sysprop is a little unusual. Others are pretty common, I sould say. I didn't go out of my way to memorize them. If I were to ask it in a job interview, I wouldn't expect the candidate to list all. If he/she can name 3 or 4, I know he/she has done some real java programming and debugging.

Guy said...

Another way is to put your archives in the lib/ext directory of the JRE. Then you don't have to add anything at all to the classpath.

Anonymous said...

How it is working for javaw?

admin said...

How to specify classpath for javaw? It should be the same as for java.

http://java.sun.com/javase/6/docs/technotes/tools/windows/java.html

The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you don't want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.

Anonymous said...

First I launched my application as java -cp lib/psc-config.jar;jboss-4.0.4.GA/client/* com.lps.setup.gui.PSCSystemTray
and it works fine
then I tried with javaw
javaw -cp lib/psc-config.jar;jboss-4.0.4.GA/client/* com.lps.setup.gui.PSCSystemTray
In this case java didn't find all libraries from jboss/client
and i set it as
javaw -cp jboss-4.0.4.GA/client/jbossall-client.jar;jboss-4.0.4.GA/client/concurrent.jar;jboss-4.0.4.GA/client/jboss-common-client.jar;jboss-4.0.4.GA/client/jboss-transaction-client.jarjboss-4.0.4.GA/client/jboss-j2ee.jar;jboss-4.0.4.GA/client/jbosssx-client.jar;jboss-4.0.4.GA/client/jnp-client.jar;lib/psc-config.jar com.lps.setup.gui.PSCSystemTray

admin said...

It's a bug in JDK 6:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=b0701b215aaf592795fb034cbfc35:WuuT?bug_id=6510337

With javaw, you will need to explicitly list all jars/directories, until this bug is fixed.

tax hair said...
This comment has been removed by a blog administrator.
Anup said...

Really Helpful..!! I was searching this for so loooong....

Florent Georges said...

By the way, you sample 2 is the same as sample 1 ;-)

javahowto said...

Typo fixed. Thanks!

Javin @ classpath in java said...

Great post, nice simple and effective. just to add Its worth noting that if you have two classes with same name in classpath in that case one which comes earlier in classpath will get picked up. this concept is very useful to test patch releases where you update only few classes to quickly test patch release or have added some debug print statement to troubleshoot any issue. to read more about How classpath works in Java

Sandeep@classpath said...

classpath should be one of the first thing developers should learn but alas that is not the case. Yesterday only I was being asked about classpath on Facebook by a beginner. So I wrote a blog post for common classpath problems

GeekDude said...
This comment has been removed by the author.
GeekDude said...
This comment has been removed by the author.