JDK-6738530 : Up-to-date class in archive on 'sourcepath' is recompiled
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2008-08-19
  • Updated: 2011-02-16
  • Resolved: 2008-09-17
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
javac -version:
javac 1.6.0_10-rc
Also tested with 1.6.0_5 and 1.6.0_7.

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP Professional Service Pack 2 (build 2600)

A DESCRIPTION OF THE PROBLEM :
This is a simplified situation to explain the case:

I try to compile class A (I explicitly specified just this class).
Class A uses class B.
Class B is in an archive on the classpath.
Class B can also be found via the sourcepath.

When compiling with javac 1.6 it tries to re-compile class B. This should not happen, because this class is up-to-date in the archive on the classpath.

When compiling with javac 1.5.0_11 it does not re-compile class B, but grabs it from the jar on the classpath, as expected.

In my case class B uses another library, not used by class A. This library is not on the classpath when compiling A, so compilation of B fails. In fact, class A is compiled succesfully, but javac fails, because it cannot compile class B subsequently.

Note: when the class B is not in a jar on the claspath, but in a directory on the classpath (not archived), the class is not re-compiled and compilation of class A succeeds without error.

Note: this simplified case could be worked around by not putting class B on the sourcepath. In my actual project class A uses class B and C from the same project, where B can be found on the classpath and also on sourcepath, but C is only on the sourcepath. I just want to compile C when needed, but not B. That is why both paths are needed.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the following command on the class specified below:

javac project_1\sources\package_1\A.java -d project_1\classes -classpath package_216.zip -sourcepath project_2\sources -verbose

The following command uses class B un-archived (which succeeds):

javac project_1\sources\package_1\A.java -d project_1\classes -classpath project_2\classes -sourcepath project_2\sources -verbose

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both cases above should compile class A without error messages.
ACTUAL -
The first command fails, because it cannot compile class B.
The second command succeeds.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
First command:

javac project_1\sources\package_1\A.java -d project_1\classes -classpath package_216.zip -sourcepath project_2\sources -verbose
[parsing started project_1\sources\package_1\A.java]
[parsing completed 15ms]
[search path for source files: project_2\sources]
[search path for class files: C:\Program Files\Java\jdk1.6.0_10\jre\lib\resources.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_10\jre\classes,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunpkcs11.jar,package_216.zip]
[loading java\lang\Object.class(java\lang:Object.class)]
[checking package_1.A]
[loading project_2\sources\package_2\B.java]
[parsing started project_2\sources\package_2\B.java]
[parsing completed 0ms]
[wrote project_1\classes\package_1\A.class]
[checking package_2.B]
project_2\sources\package_2\B.java:4: package lib does not exist
    public static int CONSTANT_B = lib.LibClass.LIB_CONSTANT;
                                      ^
[total 234ms]
1 error

Second command:

C:\Projects_sv\Test Javac>javac project_1\sources\package_1\A.java -d project_1\classes -classpath project_2\classes -sourcepath project_2\sources -verbose
[parsing started project_1\sources\package_1\A.java]
[parsing completed 15ms]
[search path for source files: project_2\sources]
[search path for class files: C:\Program Files\Java\jdk1.6.0_10\jre\lib\resources.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\rt.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\sunrsasign.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\jsse.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\jce.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\charsets.jar,C:\Program Files\Java\jdk1.6.0_10\jre\classes,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\dnsns.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\localedata.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunjce_provider.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunmscapi.jar,C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext\sunpkcs11.jar,project_2\classes]
[loading java\lang\Object.class(java\lang:Object.class)]
[checking package_1.A]
[loading project_2\classes\package_2\B.class]
[wrote project_1\classes\package_1\A.class]
[total 141ms]

Note: when run with javac 1.5 the first command succeeds:

C:\Projects_sv\Test Javac>javac project_1\sources\package_1\A.java -d project_1\classes -classpath package_215.zip -sourcepath project_2\sources -verbose
[parsing started project_1\sources\package_1\A.java]
[parsing completed 31ms]
[search path for source files: [project_2\sources]]
[search path for class files: [C:\bea10\jdk150_11\jre\lib\rt.jar, C:\bea10\jdk150_11\jre\lib\jsse.jar, C:\bea10\jdk150_11\jre\lib\jce.jar, C:\bea10\jdk150_11\jre\lib\charsets.jar, C:\bea10\jdk150_11\jre\libext\dnsns.jar, C:\bea10\jdk150_11\jre\lib\ext\localedata.jar, C:\bea10\jdk150_11\jre\lib\ext\sunjce_provider.jar, C:\bea10\jdk150_11\jre\lib\ext\sunpkcs11.jar, package_215.zip]]
[loading C:\bea10\jdk150_11\jre\lib\rt.jar(java/lang/Object.class)]
[checking package_1.A]
[loading package_215.zip(package_2/B.class)]
[wrote project_1\classes\package_1\A.class]
[total 312ms]

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Class A:

package package_1;

public class A {
    public static int CONSTANT_A = package_2.B.CONSTANT_B;
}

Class B:

package package_2;

public class B {
    public static int CONSTANT_B = lib.LibClass.LIB_CONSTANT;
}

Class LibClass:
package lib;

public class LibClass {
    public static int LIB_CONSTANT = 0;
}

I compiled class LibClass and put it in lib15.zip or lib16.zip depending on the java version.
I compiled class B and put it in package_215.zip or package_216.zip depending on the java version.
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I now have to include all libraries used by class B on the classpath for class A.
Our codebase is quite large with dozens of libraries, so I end up with needing almost all libraries for compiling every project.