This discussion is archived
13 Replies Latest reply: Oct 28, 2012 11:12 AM by jschellSomeoneStoleMyAlias RSS

Current Working Directory in Java classpath

srikanth vallabhaneni Newbie
Currently Being Moderated
Can someone explain why the current working directory is getting added to the classpath in these scenarios when I did not include "." in the CLASSPATH?

http://docs.oracle.com/javase/6/docs/technotes/tools/windows/classpath.html says that current working directory gets added only when CLASSPATH is not set.


C:\TEMP>set CLASSPATH=;;;



C:\TEMP>%JAVA_HOME%\bin\java test.Test

java.class.path=;;;

classloader:sun.misc.Launcher$AppClassLoader@1cde100

classloader path:[file:/C:/TEMP/, file:/C:/TEMP/, file:/C:/TEMP/, file:/C:/TEMP/]



C:\TEMP>set CLASSPATH=



C:\TEMP>%JAVA_HOME%\bin\java test.Test

java.class.path=.

classloader:sun.misc.Launcher$AppClassLoader@1a16869

classloader path:[file:/C:/TEMP/]



C:\TEMP>set CLASSPATH=a



C:\TEMP>%JAVA_HOME%\bin\java test.Test

Exception in thread "main" java.lang.NoClassDefFoundError: test/Test

Caused by: java.lang.ClassNotFoundException: test.Test

at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

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: test.Test. Program will exit.



C:\TEMP>set CLASSPATH=a;



C:\TEMP>%JAVA_HOME%\bin\java test.Test

java.class.path=a;

classloader:sun.misc.Launcher$AppClassLoader@1a16869

classloader path:[file:/C:/TEMP/a, file:/C:/TEMP/]



C:\TEMP>set CLASSPATH=;a



C:\TEMP>%JAVA_HOME%\bin\java test.Test

java.class.path=;a

classloader:sun.misc.Launcher$AppClassLoader@1a16869

classloader path:[file:/C:/TEMP/, file:/C:/TEMP/a]



C:\TEMP>
  • 1. Re: Current Working Directory in Java classpath
    EJP Guru
    Currently Being Moderated
    You've specified an empty CLASSPATH. Probably the wording in the link could be improved, but logically that's equivalent to not setting it at all.
  • 2. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    Thank you. I am ok with the empty classpath being interpreted as current working directory. I am talking about other scenarios like "set CLASSPATH=;;;" being treated as current working directory added four times to the classpath.
  • 3. Re: Current Working Directory in Java classpath
    EJP Guru
    Currently Being Moderated
    That's what I'm talking about. Logically that is still an empty CLASSPATH. Four times nothing is still nothing.
  • 4. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    When we are constructing the CLASSPATH variable from other variables, we just concatenate different variables with the path separator to come up with the final path. If any of those variables are empty or if we ended the whole path with a path separator, the current working directory is coming into the classpath. Is it the intent? Users may not even notice that the current working directory is getting added to the CLASSPATH as they are not deliberately adding '.'

    I noticed this behavior when code(in a J2EE WAR in a J2EE EAR) is loading a property file from classpath (and it is working). However the property file is not in the WAR or EAR or anywhere in the application server classpath except that it is in the directory where the application server is getting started(which I later found out is also getting added to the CLASSPATH).

    So any simple misplacement of a path separator character can result in the current working directory getting added to the CLASSPATH. I did not expect this at all.
  • 5. Re: Current Working Directory in Java classpath
    EJP Guru
    Currently Being Moderated
    If any of those variables are empty or if we ended the whole path with a path separator, the current working directory is coming into the classpath.
    I'd be surprised, in fact I'd be astonished. I would expect that if you put anything into the classpath other than empty elements, it won't use '.'. However this is not what you have done. What you have done is specify four empty elements, which is equivalent to specifying nothing at all, which is causing it to use '.'.
    Is it the intent? Users may not even notice that the current working directory is getting added to the CLASSPATH as they are not deliberately adding '.'
    I don't believe it's even happening.
    So any simple misplacement of a path separator character can result in the current working directory getting added to the CLASSPATH. I did not expect this at all.
    I think you are misinterpreting what I said.
  • 6. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    If you look at the setDomainEnv.cmd of a weblogic domain, you will find this

    set CLASSPATH=%PRE_CLASSPATH%;%WEBLOGIC_CLASSPATH%;%POST_CLASSPATH%;%WLP_POST_CLASSPATH%

    If any of these variables is empty or their paths start with or end with ; (path separator) or they have something like this ;; then current working directory can get added to the classpath one to many times.
  • 7. Re: Current Working Directory in Java classpath
    EJP Guru
    Currently Being Moderated
    As I said above, I don't believe that happens. I believe it happens if the entire CLASSPATH is logically empty, not just elements of it. If you have some counter-evidence, let's have it. Not just more speculation. We're going round in circles here.
  • 8. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    I put all this in test.cmd file and ran it from c:\temp; c:\temp\test\Test.class is where the class file is

    @echo on

    set PRE_CLASSPATH=

    set WEBLOGIC_CLASSPATH=C:\bea103\wlserver_10.3\server\lib\weblogic.jar

    set POST_CLASSPATH=

    set WLP_POST_CLASSPATH=

    set CLASSPATH=%PRE_CLASSPATH%;%WEBLOGIC_CLASSPATH%;%POST_CLASSPATH%;%WLP_POST_CLASSPATH%

    echo %CLASSPATH%

    c:\bea103\jdk6\bin\java test.Test

    and this what I see


    C:\TEMP>test.cmd

    C:\TEMP>set PRE_CLASSPATH=

    C:\TEMP>set WEBLOGIC_CLASSPATH=C:\bea103\wlserver_10.3\server\lib\weblogic.jar

    C:\TEMP>set POST_CLASSPATH=

    C:\TEMP>set WLP_POST_CLASSPATH=

    C:\TEMP>set CLASSPATH=;C:\bea103\wlserver_10.3\server\lib\weblogic.jar;;

    C:\TEMP>echo ;C:\bea103\wlserver_10.3\server\lib\weblogic.jar;;
    ;C:\bea103\wlserver_10.3\server\lib\weblogic.jar;;

    C:\TEMP>c:\bea103\jdk6\bin\java test.Test
    java.class.path=;C:\bea103\wlserver_10.3\server\lib\weblogic.jar;;
    classloader:sun.misc.Launcher$AppClassLoader@1a16869
    classloader path:[file:/C:/TEMP/, file:/C:/bea103/wlserver_10.3/server/lib/weblogic.jar, file:/C:/TEMP/, file:/C:/TEMP/]

    C:\TEMP>
  • 9. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    package test;

    public class Test
    {
         public static void main(String[] args)
         {
              System.out.println("java.class.path="+System.getProperty("java.class.path"));
              System.out.println("classloader:"+Test.class.getClassLoader());
              System.out.println("classloader path:"+java.util.Arrays.toString(((java.net.URLClassLoader)Test.class.getClassLoader()).getURLs()));
         }
    }
  • 10. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    Mr. EJP,
    Have you any further comments on this?
  • 11. Re: Current Working Directory in Java classpath
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    Your definition of classpath is not precise, which isn't necessarily your problem since it is used to apply to many things.

    Your code demonstrates that your real question is about the urls of the system class loader.

    I verified your code output on my system (windows) using 1.7.0_07-b10.
    And also 1.6.0_12-b04 and even 1.4.0_01-b03.
    All the same, so the behavior isn't new.

    Conversely the java.class.path output demonstrates that the "classpath" per that description doesn't really resolve to anything meaningful.

    I would say that myself I find the implementation which adds multiples certainly not ideal. Although one might suppose that in the actual resolution that it optimizes that away (but then why not do it originally anyways?)
    user623867 wrote:
    Can someone explain why the current working directory is getting added to the classpath in these scenarios when I did not include "." in the CLASSPATH?
    In terms of the class loader - because it is coded that way.

    It has been that way for a long time so it doesn't matter to a lot of people. Resolution is based on the first find so it would only ever be a problem if you were not finding classes. And doing that a lot. That isn't a typical situation. And only then if isn't somehow not optimizing it.

    If it is a problem for you then you can replace the system class loader using java VM command line options. You can also replace the URLClassLoader
  • 12. Re: Current Working Directory in Java classpath
    srikanth vallabhaneni Newbie
    Currently Being Moderated
    Thank you for the reply. My main issue is that folks may not be even aware of the fact that the current working directory is getting added to the classpath (as they did not explicitly put '.' in the classpath). At least I did not know until I recently started looking at some code where a property file is getting loaded from the classpath and the property file is no where in the J2EE WAR/EAR or any classpath hierarchy of the application server but it is in the directory where the app server is getting started.

    Now that I know that current working directory can be added automatically in certain cases (by a simple misplacement of a path separator character), I can better troubleshoot any classloading issues. Obviously, we can override the classloader hierarchy to control where things are loaded from etc. Before, I did not even think of looking at current working directory (as '.' is not in the classpath explicitly); now that I know, I will start looking in current working directory also.
  • 13. Re: Current Working Directory in Java classpath
    jschellSomeoneStoleMyAlias Expert
    Currently Being Moderated
    user623867 wrote:
    Thank you for the reply. My main issue is that folks may not be even aware of the fact that the current working directory is getting added to the classpath (as they did not explicitly put '.' in the classpath).
    Except of course that I have shown that this has been going on for years and this is the first time anyone noted it. Thus it would suggest that regardless of the lack of knowledge it is not a problem. Not a problem for a lot of people.

    At least I did not know until I recently started looking at some code where a property file is getting loaded from the classpath and the property file is no where in the J2EE WAR/EAR or any classpath hierarchy of the application server but it is in the directory where the app server is getting started.
    That to me sounds like an install problem.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points