Discussion:
JDK 8: Second Release Candidate
mark.reinhold
2014-02-11 22:31:52 UTC
Permalink
Last week a serious flaw in a new API was reported [1]. We decided to
fix that bug, along with an unrelated JCK failure on Mac OS X [2], so
we now have a second JDK 8 Release Candidate, build 129.

Binaries available here, as usual: https://jdk8.java.net/download.html

- Mark


[1] https://bugs.openjdk.java.net/browse/JDK-8033590
[2] https://bugs.openjdk.java.net/browse/JDK-8033642
Brenden Towey
2014-02-14 18:54:07 UTC
Permalink
I'd like to make a bug report. Java has had for a while now a bug in
its regex system which I'd like to see fixed.

The short of it is that the \z pattern does not return 'requiresEnd' and
it should.

public void endTest()
{
Matcher m = Pattern.compile( "\\z" ).matcher( "" );
m.find();
System.out.println( m.requireEnd() );
assert ( m.requireEnd() );
}

This prints 'false'. It shouldn't take much thought to convince
yourself that if the end of input is required, then 'requiresEnd()'
should always be true. There's never a case for the \z pattern that you
want to match less than all of input. The above code snippet would make
a fine unit test for this bug, btw.

You can see the results of this bug if you use other parts of the API,
for example java.util.Scanner. Since the the requiresEnd() method
always returns false, the Scanner will match its own internal buffer
(usually 1024 characters) and not the end of input.


public void demo()
{
StringBuilder str = new StringBuilder( 4 * 1024 );
for( int i = 0; i < 1024; i++ ) {
str.append( i );
str.append( ',' );
}
Scanner s = new Scanner( str.toString() );
String result = s.useDelimiter( "\\z" ).next();
String expected = str.toString();
System.out.println( result.length()+", "+expected.length() );
assert( expected.equals( result ) );
}

Output:
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)

C:\Users\Brenden\Dev\proj\Test2\build\classes>java -cp . quicktest.RegexBug
1024, 4010

You can see that the length of the matched string is 1024, not 4010 from
the original string.

Finally, if you need more convincing, you can test the \Z (capital Z)
pattern, which does essentially the same thing as \z. \Z always sets
its requiresEnd() flag, and it works as expected in the tests above.

Summary: \z should always set its 'requiresEnd' flag.

Thanks for taking the time to read this!
Post by mark.reinhold
Last week a serious flaw in a new API was reported [1]. We decided to
fix that bug, along with an unrelated JCK failure on Mac OS X [2], so
we now have a second JDK 8 Release Candidate, build 129.
Binaries available here, as usual: https://jdk8.java.net/download.html
Martijn Verburg
2014-02-15 13:31:24 UTC
Permalink
Hi Brenden,

Thanks for reporting this issue, but it should be submitted via bugs.sun.com:-).

Cheers,
Martijn
I'd like to make a bug report. Java has had for a while now a bug in its
regex system which I'd like to see fixed.
The short of it is that the \z pattern does not return 'requiresEnd' and
it should.
public void endTest()
{
Matcher m = Pattern.compile( "\\z" ).matcher( "" );
m.find();
System.out.println( m.requireEnd() );
assert ( m.requireEnd() );
}
This prints 'false'. It shouldn't take much thought to convince yourself
that if the end of input is required, then 'requiresEnd()' should always be
true. There's never a case for the \z pattern that you want to match less
than all of input. The above code snippet would make a fine unit test for
this bug, btw.
You can see the results of this bug if you use other parts of the API, for
example java.util.Scanner. Since the the requiresEnd() method always
returns false, the Scanner will match its own internal buffer (usually 1024
characters) and not the end of input.
public void demo()
{
StringBuilder str = new StringBuilder( 4 * 1024 );
for( int i = 0; i < 1024; i++ ) {
str.append( i );
str.append( ',' );
}
Scanner s = new Scanner( str.toString() );
String result = s.useDelimiter( "\\z" ).next();
String expected = str.toString();
System.out.println( result.length()+", "+expected.length() );
assert( expected.equals( result ) );
}
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -cp .
quicktest.RegexBug
1024, 4010
You can see that the length of the matched string is 1024, not 4010 from
the original string.
Finally, if you need more convincing, you can test the \Z (capital Z)
pattern, which does essentially the same thing as \z. \Z always sets its
requiresEnd() flag, and it works as expected in the tests above.
Summary: \z should always set its 'requiresEnd' flag.
Thanks for taking the time to read this!
Post by mark.reinhold
Last week a serious flaw in a new API was reported [1]. We decided to
fix that bug, along with an unrelated JCK failure on Mac OS X [2], so
we now have a second JDK 8 Release Candidate, build 129.
Binaries available here, as usual: https://jdk8.java.net/download.html
Brenden Towey
2014-02-14 20:48:17 UTC
Permalink
Also, I have another gripe. I was reminded of this as I was installing
the new Java 8 bits, and I temporarily removed the older Java 8 version.

C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

C:\Users\Brenden\Dev\proj\Test2\build\classes>
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)

This is before and after. Notice that the Java 7 version is not updated
(it should be update 51, I think, not 45). Your updater fails to update
an older version if it detects a newer version of Java. That is, if the
updater sees Java 8 is installed, it won't ever update Java 7 to the
latest patch level. In light of all the recent bad press Java has
received because of security issues (especially not updating older
versions of Java) I think this is unacceptable.

Always, always, always update a version of Java if is possible to do
so. Sure, don't make an old version of Java the default installation,
but please update the bits that are sitting on the disc. There's really
no good reason not to, and if this sort of scenario ever happens (a user
uninstalls a current version to expose an older version) you're left
with known bad bits running on a live installation. I hope I don't have
to expound on how lousy an idea that is.

When you do update an older version, you need to check if *any* part of
that version is still in use. For example, I don't think the Java 8 RC
installs a browser plug-in, so I'm still actually using an (unupdated,
old, u45) Java 7 plug-in. Getting the most recent plug-in updated to
all browsers should be a high priority during a Java update.

Thanks again for reading my little missive.
Post by mark.reinhold
Last week a serious flaw in a new API was reported [1]. We decided to
fix that bug, along with an unrelated JCK failure on Mac OS X [2], so
we now have a second JDK 8 Release Candidate, build 129.
Binaries available here, as usual: https://jdk8.java.net/download.html
Martijn Verburg
2014-02-15 13:32:57 UTC
Permalink
Hi Brenden,

Oracle's installer is separate from OpenJDK itself, I'm afraid you'll also
need to report this issue to bugs.sun.com!

Cheers,
Martijn
Post by Brenden Towey
Also, I have another gripe. I was reminded of this as I was installing
the new Java 8 bits, and I temporarily removed the older Java 8 version.
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
C:\Users\Brenden\Dev\proj\Test2\build\classes>
C:\Users\Brenden\Dev\proj\Test2\build\classes>java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)
This is before and after. Notice that the Java 7 version is not updated
(it should be update 51, I think, not 45). Your updater fails to update an
older version if it detects a newer version of Java. That is, if the
updater sees Java 8 is installed, it won't ever update Java 7 to the latest
patch level. In light of all the recent bad press Java has received
because of security issues (especially not updating older versions of Java)
I think this is unacceptable.
Always, always, always update a version of Java if is possible to do so.
Sure, don't make an old version of Java the default installation, but
please update the bits that are sitting on the disc. There's really no
good reason not to, and if this sort of scenario ever happens (a user
uninstalls a current version to expose an older version) you're left with
known bad bits running on a live installation. I hope I don't have to
expound on how lousy an idea that is.
When you do update an older version, you need to check if *any* part of
that version is still in use. For example, I don't think the Java 8 RC
installs a browser plug-in, so I'm still actually using an (unupdated, old,
u45) Java 7 plug-in. Getting the most recent plug-in updated to all
browsers should be a high priority during a Java update.
Thanks again for reading my little missive.
Post by mark.reinhold
Last week a serious flaw in a new API was reported [1]. We decided to
fix that bug, along with an unrelated JCK failure on Mac OS X [2], so
we now have a second JDK 8 Release Candidate, build 129.
Binaries available here, as usual: https://jdk8.java.net/download.html
Loading...