United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6725036 javac returns incorrect value for lastModifiedTime() when source is a zip file archive
JDK-6725036 : javac returns incorrect value for lastModifiedTime() when source is a zip file archive

Details
Type:
Bug
Submit Date:
2008-07-11
Status:
Closed
Updated Date:
2013-10-01
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
tools
OS:
generic,windows_xp
Sub-Component:
javac
CPU:
x86,generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u10,6u21,7
Fixed Versions:

Related Reports
Backport:
Backport:
Duplicate:
Duplicate:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
The proposed new javap -sysinfo option has revealed a bug in the value of lastModifiedTime() used internally by javac when a class comes from a zip file archive.

Here is the output for java.lang.String:

JavapTask: /usr/lib/jvm/java-6-sun-1.6.0.03/jre/lib/rt.jar(java/lang/String.class) 
Classfile jar:/usr/lib/jvm/java-6-sun-1.6.0.03/jre/lib/rt.jar!java/lang/String.class
Last modified Jan 11, 1970; size 15572 bytes
MD5 checksum 6977f62c32cd39574a15a1fde238fc74

(Note:  Jan 11, 1970)

Here is the corresponding output from unzip:
    15572  09-24-07 22:49   java/lang/String.class
and from jar
 15572 Mon Sep 24 22:49:32 PDT 2007 java/lang/String.class

This needs to be fixed, as javac uses last modified time internally to determine if class files are up to date.

                                    

Comments
EVALUATION

The following code in ZipFileIndex looks "suspicious"

        // From java.util.zip
        private static long dosToJavaTime(int nativetime) {
            // Bootstrap build problems prevent me from using the code directly
            // Convert the raw/native time to a long for now
            return (long)nativetime;
        }
                                     
2008-07-11
EVALUATION

For reference, here is the relevant code from dosToJavaTime in java.util.Zip

    /*
     * Converts DOS time to Java time (number of milliseconds since epoch).
     */
    private static long dosToJavaTime(long dtime) {
	Date d = new Date((int)(((dtime >> 25) & 0x7f) + 80),
			  (int)(((dtime >> 21) & 0x0f) - 1),
			  (int)((dtime >> 16) & 0x1f),
			  (int)((dtime >> 11) & 0x1f),
			  (int)((dtime >> 5) & 0x3f),
			  (int)((dtime << 1) & 0x3e));
	return d.getTime();
    }

Note however, this code uses a deprecated Date constructor, with the following comment
     * @deprecated As of JDK version 1.1,
     * replaced by <code>Calendar.set(year + 1900, month, date,
     * hrs, min, sec)</code> or <code>GregorianCalendar(year + 1900,
     * month, date, hrs, min, sec)</code>.
                                     
2008-07-11



Hardware and Software, Engineered to Work Together