RFR: timestamp oddities -sourcepath vs zip/jar
Jonathan Gibbons
jonathan.gibbons at oracle.com
Mon Sep 23 11:57:51 PDT 2013
On 09/22/2013 06:41 AM, Fredrik Öhrström wrote:
> The preferredFileObject test in ClassReader.java does cause confusion
> when timestamps inside zip files are too new.
>
> Lets say that you have in src/alfa/A.java
> public class A { void a() { java.lang.Object.foo = 42; } }
> and in src/java/lang/Object.java
> public class Object { public static int foo; }
>
> You can now always compile using the following command:
> javac -d bin src/alfa/A.java src/java/lang/Object.java
>
> But you can only >>sometimes<< compile using the following command:
> javac -d bin -sourcepath src src/alfa/A.java
>
> When it fails, javac has picked up java.lang.Object from rt.jar and
> not from the sourcepath. This happens when the timestamp inside rt.jar
> is newer than the source file.
>
> The net result is that when compiling the OpenJDK with --enable-sjavac
> everything works fine, then you upgrade your jdk and the compilation
> fails in very weird ways. And will fail until you touch all your
> source files.
>
> There are several ways to fix this, but all require some thought.
> However a simple fix, would be to ignore the timestamps of class files
> inside zip/jars because they probably do not mean anything important....
>
> Thus in preferredFileObject, if b is a ZipFileIndexFileObject, then
> use the source!
> protected JavaFileObject preferredFileObject(JavaFileObject a,
> JavaFileObject b) {
> if (preferSource)
> return (a.getKind() == JavaFileObject.Kind.SOURCE) ? a : b;
> else {
> if (b instanceof
> com.sun.tools.javac.file.ZipFileIndexArchive.ZipFileIndexFileObject) {
> return a;
> }
> long adate = a.getLastModified();
> long bdate = b.getLastModified();
> // 6449326: policy for bad lastModifiedTime in ClassReader
> //assert adate >= 0 && bdate >= 0;
> return (adate > bdate) ? a : b;
> }
> }
>
> What do you think?
>
> //Fredrik
>
>
>
>
Fredrik,
There is no guarantee that items in zip files are presented to javac in
the class you test for, so the instanceof test is highly suspicious and
likely to be a source of inconsistent behavior. For example, what
happens if someone using using javac via the CompilerAPI (JSR 199) and
provides their own custom file manager?
If you want to make sure you're compiling source code, use
-Xprefer:source. Or, keep your timestamps straight.
-- Jon
More information about the compiler-dev
mailing list