Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 17 Jan 2019 17:44:22 +0000
From:      bugzilla-noreply@freebsd.org
To:        java@FreeBSD.org
Subject:   [Bug 235018] java/openjdk8: adding millisecond resolution to get/setLastModified breaks many apps
Message-ID:  <bug-235018-8522-6h0D44W0Ev@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-235018-8522@https.bugs.freebsd.org/bugzilla/>
References:  <bug-235018-8522@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D235018

--- Comment #3 from aryeh.friedman@gmail.com ---
Java 8 !=3D Java 11=20

Java makes the absolute guarantee that if you compile for one language spec
version it will work on all JVM's on all platforms of the same language spec
version.  Changing the granularity of a method fundamentally breaks that
promise.  The original source for OpenJDK8 is 1 second resolution and peopl=
e do
count on that.

Additionally RFC 7231 section 7.1.1.1 (as "imported" from RFC 5322, the
provided EBNF does not include sub-second resolutions) specifies only second
resolution it makes no provisions for having/not having sub-second resoluti=
ons
(i.e. that is undefined behavior which again violates Java's portability
promise if a specific JVM on a specific platform [OpenJDK 8 on FreeBSD] dec=
ides
to arbitrarily change how one of the standard library's computes/returns
values).

The way it can break a tomcat-based web app is that one of the practices us=
ed
in some REST-like API's (such as the one that triggered this bug report) is
that when a PUT/POST is made it is required to be proceeded by a GET, and t=
hen
the PUT/POST request contains an If-Unmodified-Since header echoing back the
Last-Modified header of the response to proceeding GET, to help minimize
concurrent update issues, consistent with RFC-based standards.   The server=
's
processing of the PUT/POST then involves comparing the re-sent header to the
actual file modification time.   Since the HTTP standard time format for th=
ese
headers is second resolution but the Java 11 (but NOT Java 8) standard libr=
ary
one is millisecond resolution, they almost never agree and therefore the
PUT/POST is rejected as being out of date.

In a tomcat-based web app using Java 11, this problem could be solved by
rounding down the time to a one-second resolution.  However, this step shou=
ld
not be necessary in a Java 8 application, because of Java's portability pro=
mise
within any given language spec version.

Here is the specific line that fails:

if ( ! ifUnmodifiedSinceTime.equals(lastModifiedTime) )
                        throw new HResVersionConflictException(
                                   "Write conflict:  Up-to-date"
                                           + " If-Unmodified-Since"
                                           + " timestamp must be"
                                           + " obtained, as"
                                           + " Last-Modified"
                                           + " timestamp metadata,"
                                           + " via GET "
                                           + writeID.toUrlPath(
                                                      pathPrefix));

As proven by following debugging output:

-----------------------------------
MethodProcUtil.checkWriteConflict:
  -- ifUnmodifiedSinceTime =3D 1547742518000 | Thu Jan 17 11:28:38 EST 2019
  -- lastModifiedTime =3D 1547742518769 | Thu Jan 17 11:28:38 EST 2019
-----------------------------------

Here is the same debugging output from a pre-patch openjdk 8 on same versio=
n of
FreeBSD (identical VM's running on the same host machine except that one VM
uses the post-patch openjdk and the other VM uses pre-patched):

-----------------------------------
MethodProcUtil.checkWriteConflict:
  -- ifUnmodifiedSinceTime =3D 1546916804000 | Mon Jan 07 22:06:44 EST 2019
  -- lastModifiedTime =3D 1546916804000 | Mon Jan 07 22:06:44 EST 2019
-----------------------------------

Other factors being equal, millisecond resolution would, of course, be bett=
er
than second resolution.  But the move to millisecond resolution should not
break existing applications that depend on a particular version of Java.

If, for whatever reason, it is deemed necessary to take such a radical step=
 as
to make such an improvement without waiting for the appropriate version of
Java, then any such change should AT LEAST be documented MUCH, MUCH more
conspicuously than this one was.  (I found no documentation of this change =
at
all except for a comment within the commit.)

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-235018-8522-6h0D44W0Ev>