JDK-4356783 : Running java.exe with "-jar" ignores the classpath
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 1.3.0,1.4.2
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_2000,windows_xp
  • CPU: x86
  • Submitted: 2000-07-26
  • Updated: 2001-05-14
  • Resolved: 2001-05-14
Related Reports
Duplicate :  
Relates :  
Description

Name: skT45625			Date: 07/26/2000


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)java

When using the "Main-Class" feature of a jar's manifest file and the "-jar"
option to java.exe, the classpath environment variable seems to be ignored. I
have created a testcase:

Other.java:
-------------------------------------------------
    public class Other { }
-------------------------------------------------

Main.java:
-------------------------------------------------
    public class Main
    {
        public static void main (String [] args)
        {
            Other other = new Other();
        }
    }
------------------------------------

manifest:
------------------------------------
    Manifest-Version: 1.0
    Main-Class: Main
-------------------------------------

Instructions for setting up the test:
1. Create the files "Other.java", "Main.java", and "manifest" with the contents
listed above.
2. javac Main.java
3. javac Other.java
4. jar -cf other.jar Other.class
5. jar -cfm main.jar manifest Main.class

Now, execute this sequence of commands:

    SET CLASSPATH=other.jar
    java -jar main.jar
    
    SET CLASSPATH=other.java;main.java
    java Main

    java -cp other.jar;main.jar Main

In the first execution, there is an exception:

    Exception in thread "main" java.lang.NoClassDefFoundError: Other

even though class Other is in the classpath. The other two commands run
correctly (no exceptions, no output, as expected). It seems that the "-jar"
option is causing java.exe to ignore the classpath, which is incorrect: the
classpath should be used like it is in the last two example executions.

It is possible to use the "Class-Path" header field name in the manifest to
work around this issue. This is inappropriate for many applications for because
the "Class-Path" header field requires the JAR creator to know the location of
the classes it depends on. The application should not have to know the location
of the file.

I noticed this bug when using JAXP. Since I wanted to be able to switch parser
implementations at runtime (one of the goals of JAXP), I did not know the
locations of the SAX classes: they could be in "parsers.jar" or "xerces.jar"
or "xml4j.jar", for example. Because of this I could not put the "Class-Path"
header in my JAR file to reference any one of these. I can send a more
elaborate testcase that uses JAXP to demonstrate this problem if needed.
(Review ID: 107498) 
======================================================================

Comments
EVALUATION fred.oliver@East 2001-05-14 This is the intended behavior. As documented in the SDK docs (regarding the -jar option of the java command): http://java.sun.com/j2se/1.3/docs/tooldocs/win32/java.html "When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored." An alternative approach is for the application to choose its parser at runtime and explicitly load it with a new URLClassLoader. fred.oliver@East 2001-06-06 Additional comments with respect to JDC ... This feature request (not bug) could be implemented fairly trivially, but would create backward compatibility issues. In particular, users who were (perhaps unknowingly) depending on their classpath NOT interfering, could see new failures. This is adequate reason to reject the change request. In general, it is quite appropriate for the application to be insolated from the vagaries of the user environment. Since the CLASSPATH variable is set by the user, and not by the application writer, it is desirable that it have no effect on the application. In the example from the original bug report, the submitter wanted to use the classpath to provide a user selectable software component (XML parser) for the application. While this may have been a convenient hack, this is certainly not a mechanism to be used by product quality software. This application could certainly have been coded to use another argument or property or GUI to choose a parser, and load it with a new classloader. Another user also indicates a problem with Java Web Start, but does not give any details. I don't understand why the classpath is required in addition to the jar file. Another user has another variation which is similar to javac (in that it processes java souce code), which does use the CLASSPATH (in the absense of other options). In this case, using the CLASSPATH variable saves some typing, but introduces ambiguity. The classpath used to run the application is not (should not) be the classpath used to process the input application. We shouldn't be encouraging this kind of amibiguity.
11-06-2004

WORK AROUND Name: skT45625 Date: 07/26/2000 Use the "Class-Path" header in the manifest. ======================================================================
11-06-2004