JDK-6835451 : Change in javac 6 forces recompilation of all source
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-04-29
  • Updated: 2011-02-16
  • Resolved: 2010-10-29
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) Client VM (build 11.3-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP version 2002 SP 2

A DESCRIPTION OF THE PROBLEM :
We've recently upgraded from Java 5 to Java 6 and are encountering a problem with compilation dependencies. Our developer environment is structured as follows:

- an overnight build holding all our classes in a single jar file: classes.jar
- a source directory, /source, holding all of our java files
- a class directory, /classes, holding any class files compiled since the build

We compile using the options:

-sourcepath /source -d /classes

Assume we want to compile a source /source/package/aSampleSource.java that depends on one other source /source/package/aSampleDependency.java by running:

javac -sourcepath /source -d /classes /source/package/aSampleSource.java

In Java 5, the compiler would always compile aSampleSource.java but only compile aSampleDependency.java if the dependency source post-dated the corresponding class file in classes.jar. In Java 6, the compiler always compiles aSampleDependency.java unless it's class file in /classes/ postdates the source. In other words, the compiler is ignoring the date/time stamp of classes in the jar.

As we have over 30K classes, we'd prefer not to unjar the build class files to resolve this issue. We believe the problem was introduced with the Jar extraction time changes for Java 6. We've tried adding -Dsun.tools.jar.useExtractionTime=true to a program using the compiler API, but this had no effect.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create a class directory /classes
2. Create a class A dependent on another class B
3. Compile B to /classes and place it in a jar file b.jar
4. Remove B from /classes
5. Add b.jar to the classpath
6. Compile A with -verbose

The compilation of A should not require the recompilation of B unless B's source postdates the B class in b.jar. Under Java 6 javac, it does.

8. Create an alternate class directory /classes2
9. Compile B to /classes2
10. Compile A

In this case the compilation of A does not force a recompilation of B. This shows the problem is in the jar entry timestamp.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We expect timestamps in jar classes to be respected when determining whether a class requires implicit recompilation.
ACTUAL -
In Java 5, jar timestamps were respected; in Java 6 all our dependent classes are recompiled.

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
The only workaround is to unjar our classes into a separate classes directory and add that directory to the classpath. This is undesirable because:

1) The unjar is a twice daily action slowing development
2) We need to remove all classes to bring in a new build
3) Reading a directory with 30K files is slower due to Windows I/O
4) We eat up more disk sectors

Release Regression From : 5.0
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.