Wednesday, May 30, 2018

JEP 181, JEP 315, and JEP 333 Proposed to Target JDK 11

Three more Java Enhancement Proposals were proposed for targeting JDK 11 today. The three JEPs are JEP 181 ["http://openjdk.java.net/jeps/181"], JEP 315 ["JEP 315: Improve Aarch64 Intrinsics"], and JEP 333 ["JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)"]. The targeting of these three JEPs for JDK 11 was announced today on the OpenJDK jdk-dev mailing list in the respective posts "JEP proposed to target JDK 11: 181: Nest-Based Access Control", "JEP proposed to target JDK 11: 315: Improve Aarch64 Intrinsics", and "JEP proposed to target JDK 11: 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)". Each JEP proposal is open for roughly one week and, if there are no objections, will be targeted officially to JDK 11 next week.

The purpose of JEP 181 is to "introduce nests" and the JEP's "Summary" states that "nests" are significant because they "allow classes that are logically part of the same code entity, but which are compiled to distinct class files, to access each other's private members without the need for compilers to insert accessibility-broadening bridge methods." A nice overview of JEP 181 can be found in the article "Java Nestmates Makes Progress," in which author Ben Evans describes this JEP as "a technical enhancement to the platform that pays off a 20 year old architectural debt introduced in Java 1.1."

The purpose of JEP 315, according to its "Summary," is to "improve the existing string and array intrinsics, and implement new intrinsics for the java.lang.Math sin, cos and log functions, on AArch64 processors."

The experimental JEP 333 introduces the "Z Garbage Collector," which the JEP's "Summary" section states is "also known as ZGC" and "is a scalable low-latency garbage collector." I like the "At a glance" sentence in the "Description" section that explains, "ZGC is a concurrent, single-generation, region-based, NUMA-aware, compacting collector. Stop-the-world phases are limited to root scanning, so GC pause times do not increase with the size of the heap or the live set." The JEP also explicitly states, "It is not a goal to provide working implementations for platforms other than Linux/x64." Important limitations of the initial version of ZGC are spelled out in the aptly named "Limitations" section which states, "The initial experimental version of ZGC will not have support for class unloading." Another limitation listed in that same section is, "ZGC will initially not have support for JVMCI (i.e. Graal)."

With today's announcements, there are now four JEPs waiting approval to be targeted for JDK 11. Besides the three covered in this post, JEP 330 had its review process for targeting JDK 11 extended to this week. Nine JEPs have already been targeted to JDK 11 as of this writing.

Tuesday, May 29, 2018

Deferred Execution with Java's Supplier

In the third chapter of his 2014 book "Java SE 8 for the Really Impatient: Programming with Lambdas," Cay Horstmann writes, "The point of all lambdas is deferred execution." He adds, "After all, if you wanted to execute some code right now, you'd do that, without wrapping it inside a lambda." Horstmann then lists several examples of the "many reasons for executing code later" and his last listed reason is "Running the code only when necessary." In this post, I look at some examples of this from the JDK that use Supplier to do exactly that: to execute a "code block" represented as a lambda expression "only when necessary."

When JDK 8 introduced lambda expressions, it also introduced several standard functional interfaces in its java.util.function package. That package's Javadoc documentation states, "Functional interfaces provide target types for lambda expressions and method references." The package contains standard functional interfaces such as Predicate (accepts single argument and represents boolean), Function (accepts single argument and provides single result), Consumer (accepts single argument and does not provide a result), and Supplier (accepts no arguments and represents/supplies single result). [As a side note, the blog post "Java 8 Friday: The Dark Side of Java 8" provides a highly useful "decision tree to [determine] ... the [standard functional interface] you're looking for" when trying to determine which standard functional interface to use (or to roll your own).]

In this post, I'll be focusing on JDK uses of Supplier, implying that the examples covered here are based on JDK-provided methods whose "target types" accept no arguments and supply a single result. These examples will only invoke the single get() method associated with the provided Supplier "when necessary." Note that all JDK uses of Supplier can be found in Supplier's Javadoc-generated HTML representation by clicking on the "Use" link.

Deferring Potential Expensive Operations Until Known to Be Necessary to Log Them

A nice benefit achieved with Supplier-provided deferred execution (sometimes also called "lazy evaluation") is in deferring of an expensive operation for generating a log message until it is known that the result of that expensive operation will actually be logged. In other words, the expensive operation will only be invoked when it is known that it is necessary to do so because the result will be logged. I have blogged about this before in the posts "Java 8 Deferred Invocation with Java Util Logging" and "Better Performing Non-Logging Logger Calls in Log4j2."

Before the modern Java logging libraries and frameworks featured these Supplier-accepting APIs, the common way to avoid incurring expensive operations whose results would not be logged anyway was to use API-based "guard" statements, but these can clutter the code and reduce readability. There are now numerous resources on how to use Supplier-based logging framework APIs to ensure that an expensive operation that might potentially be logged is not actually executed until it is known to be necessary. These resources include my two just-mentioned posts on java.util.logging and Log4j 2 as well as "Writing clean logging code using Java 8 lambdas," "Lazy logging in Java 8," and "Log4j 2 and Lambda Expressions."

The JDK supports this Supplier-powered deferred execution for logging in both its java.lang.SystemLogger "log" methods and in numerous java.util.logging.Logger methods.

Deferring Alternative Calculation for Optional Until Known to Be Necessary

The JDK 8-introduced Optional class provides several methods that accept a Supplier parameter. In all cases, the intent is that the alternative result that the Supplier can provide will only be calculated when it's known to be necessary to calculate it. In other words, the Supplier.get() is only invoked if the Optional is "empty." If Optional is not empty, all of these methods will return the value held in the Optional and won't invoke the Supplier potentially costly operation in those cases. The following list shows the methods on Optional that accept a Supplier as of JDK 10:

Deferring Handling of Undesired null Values Until Known to Be Necessary

JDK 8 added two Supplier-powered methods to the Objects class that allow for an unwanted null (typically on a method parameter) to be detected and an appropriate response supplied only when determined that a null was indeed encountered. I wrote about one of these methods, Objects.requireNonNullElseGet, in my blog post "JDK 9: NotNullOrElse Methods Added to Objects Class." This method will only execute the provided Supplier by calling its get() method when it is determined that that first parameter passed to the method is indeed null. If the first parameter is not null, the Supplier is never executed.

The second Supplier-accepting method added to Objects with JDK 9 is requireNonNull​(T obj, Supplier<String>). This method allows a Supplier to supply a String to be used in a "customized NullPointerException" thrown when the first parameter is null. If the first parameter is not null, the Supplier's get() never needs to be invoked because an exception does not need to be thrown. A very similar method exists on the Objects class that accepts a String instead of a Supplier. This requireNonNull​(T, String) method may be preferable in some cases where the cost of the String generation is deemed less than the cost of generating the supplier. If, for example, the "custom string" is a string literal, it might be preferable to use the form that accepts that String directly instead of the one expecting a Supplier, especially if the null case is expected to be common.

Other JDK Uses of Supplier for Deferred Execution

The JDK examples of using Supplier to defer execution shown in this post were selected because of their relatively frequent use and because they are straightforward examples of how Supplier enables deferred execution or lazy evaluation in cases where no argument needs to be provided and one result needs to be supplied. Other uses of Supplier for deferred execution can be found in the java.util.concurrent concurrency package and in the JDK 8 streams-supporting java.util.streams package. Perhaps the best way to quickly identify the JDK's use of Supplier and its primitive-oriented counterparts is to look at the Javadoc-generated HTML representation of each classes "uses": Uses of Supplier, Uses of DoubleSupplier, Uses of IntSupplier, and Uses of LongSupplier. Interestingly, but not too surprisingly, there are no uses of BooleanSupplier.

The JDK-provided examples of using Supplier discussed in this post mostly demonstrate Horstmann's last listed possible reason for deferring code execution to a later point: "Running the code only when necessary." Other JDK examples of using Supplier demonstrate some of Horstmann's other listed reasons that one might want to "[execute] code later."

Suppliers Are Not Limited to the JDK

Although this post has focused on JDK use of Supplier to defer execution, its use is not limited to the JDK. As discussed earlier, Log4j 2 and other logging frameworks besides java.util.logging also provide Supplier-based logging APIs to allow deferral of construction of expensive strings for logging until it's known that the string will actually be logged. Similarly, one can use Suppliers in one's own code whenever the need arrives to specify code to be executed only when necessary and that code to be potentially exercised does not require an argument passed to it and will return (supply) a single result.

Monday, May 28, 2018

Shebang Coming to Java?

Although it was never a central goal of JEP 330 ["Launch Single-File Source-Code Programs"] to add support for the Unix-style shebang (#!), issues surrounding the potential ability of JEP 330 "single file source programs" to support a Unix-style shebang have generated significant discussion on the OpenJDK jdk-dev mailing list. This "vigorous discussion" has led to Mark Reinhold adding a week to the review period (now ends on May 31) for JEP 330 to allow for further discussion regarding targeting JEP 330 for JDK 11.

Although there are still some disagreements about whether shebang support should be added at all, it does seem that consensus is shifting to a proposal to explicitly differentiate between regular platform-independent Java source code files (those that end with extension .java) and the new JEP 330 "executable" platform-specific "single-file source-code programs". The explicit distinction is noteworthy because it would allow for shebang to be expressed in the latter (JEP 330 executable platform-specific single-file source-code programs) and not be used in the former (traditional Java platform-independent source code we're all accustomed to).

A Jonathan Giles message in this discussion spells out "various reasons to not want to change JLS or javac", points out that "shebang scripts are an executable format defined on some, but not all, platforms," points out that "creating a shebang script is typically more than just adding an initial first line to a file," and articulates the concept of differentiating explicitly between traditional Java source code and JEP 330 executable Java scripts:

While renaming the file to a command-friendly name is optional, it is also expected to be common practice. For example, a source file named `HelloWorld.java` might be installed as `helloworld`. And, while the JEP describes use cases for executing a small single-file program with `java HelloWorld.java` or executing it as a platform-specific shebang script with just `helloworld`, it does not seem like there is a common use case to execute `HelloWorld.java`. So, if the shebang script is typically renamed to a command-friendly name, it will not be possible to compile it directly, with "javac helloworld", because that is not a valid command line for javac. This reduces any potential convenience of having javac ignore shebang lines.

Since Java source files are different artifacts to platform-specific executable scripts, it makes sense to treat them differently, and since we do not want to change the Java language to support shebang lines, the suggestion is to amend the JEP and implementation so that shebang lines are never stripped from Java source files, i.e. files ending in `.java`. This avoids the problem of having the ecosystem of tools handling Java source files having to deal with arbitrary artifacts like shebang lines. The change would still permit the direct execution of Java source files, such as `java HelloWorld.java`, and the execution of shebang scripts, such as `helloworld`.

The following table summarizes characteristics and advantages associated with each style of "Java" file.

Item Traditional Java Source Files JEP 330 Executable Single-File Source-Code Programs
Descriptions
/Names
"Java source files (which end with a .java extension)" "executable scripts (which do not use [.java] extension.)"
"Java source files" "shebang scripts"
"Java source file" "script that contains Java code" or "platform-specific executable script"
"Java source files, as identified by a filename ending in '.java'"  
Shebang Not Supported Supported
Platform Independent Dependent
Explicit Compilation Yes No

Jonathan Gibbons summarizes the intent of JEP 330: "The general theme here is not to evolve Java into a scripting language, but to make tools like the Java launcher more friendly to supporting the use of Java source code in an executable text file, in order to reduce the ceremony of running simple programs."

The discussion has also covered alternative approaches such as binfmt_misc (see here also), Unix-style "here documents" (here documents defined), "support for '-' STDIN source in java launcher", and Linux being changed to support "la-la-bang: //!.

Another interesting side note from this discussion is Brian Goetz's "retrace" of how JEP 330 got to its current state. He talks about the "countless hours listening to people's concerns about Java" that led to this realization, "A general theme that people have expressed concern over is 'activation energy'; that doing simple things in Java requires too much fixed work." Goetz points out that JShell and JEP 330 are two of many possible ways of addressing this and that these two approaches were selected from among the many after making "subjective choices about which had the best impact" with consideration of "cost (in multiple dimensions) and benefit (or our subjective estimates of the benefits) when making these choices."

So, "regular Java" source code files will not be getting shebang support, but that is not a big deal as they don't really need them. It is looking likely, however, that JEP 330-based platform-dependent executable single-file scripts written in Java will support an optional shebang on the first line. We may know by Thursday of this week whether JEP 330 will be targeted for JDK 11.

Saturday, May 26, 2018

Java's String.format Can Be Statically Imported

JDK-8203630 ["Add instance method equivalents for String::format"] postulates that "the argument for implementing String::format as static appears to be that the format methods could be imported statically and thus conduct themselves comparably to C's sprintf." On a StackOverflow.com thread on the subject, Brandon Yarbrough writes, "by making the method static you can use format in a way that's very familiar and clean-looking to C programmers used to printf()." Yarbrough provides a code example and then concludes, "By using static imports, printfs look almost exactly like they do in C. Awesome!"

When I read in JDK-8203630 about this, I wondered to myself why I had not statically imported String.format when I've used it because it seems obvious to me now to do that. In this post, I look briefly at some personal theories I have considered to explain why I (and many others apparently) have not thought to statically import String.format consistently.

When static imports were introduced with J2SE 5, the new documentation on the feature presented the question, "So when should you use static import?" It answered its own question with an emphasized (I did NOT add the bold), "Very sparingly!" That paragraph then goes on to provide more details about appropriate and inappropriate uses of static imports and the negative consequences of overuse of static imports.

Although the original documentation warned emphatically about the overuse of static imports, their use did seem to increase gradually as developers became more used to them. In 2012, I asked, via blog post, "Are Static Imports Becoming Increasingly Accepted in Java?" I felt at that time that they were becoming increasingly accepted, especially when used in unit testing contexts and in more modern libraries and frameworks focusing on providing "fluent" APIs. Still, somehow, I did not think to consistently apply static imports to my uses of String.format.

I don't use String.format very often, so I thought that perhaps I just didn't get many opportunities to think about this. But, even in my relatively few uses of it, I don't recall ever importing it statically. As I've thought about this more, I've realized that the primary reason I probably don't think about statically importing String.format is the same reason that most developers have not thought about it: most of the popular and readily available online examples of how to use String.format do not use static imports!

When writing a blog or article covering a feature, especially if it's at an introductory level, it can be useful to NOT do things like import statically because the explicitly spelling out of the class name can improve the developer's ability to understand where the methods in the code come from. However, this also means that if a given developer reads numerous articles and posts and none of them show use of static imports, it is easy for that developer to use the API as shown in all those examples without thinking about the possibility of statically importing.

The following are some introductory posts regarding use of String.format. At the time of this writing, they do not demonstrate use of String.format via static import. I want to emphasize that this does not take away from the quality of these resources; in fact, some of them are excellent. This is instead intended as evidence explaining why String.format seems to be seldom statically imported in Java code.

Many of the examples in the above posts use String.format() to generate a String that is assigned to a local variable. In this context, the static import is arguably less valuable than when it is used to format a String within a greater line of code. For example, it is more "fluent" to statically import String.format() so that simply format() can be specified when that formatting takes place in a line of code doing other things beyond simply assigning the formatted string to a local variable.

The main purpose of this blog post is to point out/remind us that we can statically import String.format when doing so makes our code more readable. However, there were some other interesting points made in the short discussion on the OpenJDK core-libs-dev mailing list on this subject that I'll briefly point out here:

  • JDK-8203630 points out how an instance method might make for arguably more readable code in some cases with this example: "This result is %d".format(result);
  • Rémi Forax points out some arguments against adding an instance format method to String:
    • Issues associated with static and instance methods sharing the same name in a class.
      • John Rose adds, "Refactoring static as non-static methods, or vice versa, is a very reasonable design move, but the language makes it hard to do this and retain backward compatibility."
    • Relative slowness of Java's current string interpolation capabilities with provided by String.format
    • Potential of StringConcatFactory for future faster Java string interpolation (see "String concatenation in Java 9 (part 1): Untangling invokeDynamic" for more details on StringConcatFactory).

Whether or not instance format methods come to Java's String, reading about JDK-8203444, JDK-8203630, and the associated mailing list discussion have provided me with some things to think about. If nothing else, I'll definitely be more apt to weigh String.format's performance when considering using it and will be more likely to statically import it when I do use it.

Tuesday, May 22, 2018

JEP 329 and JEP 330 Proposed for JDK 11

This past week, two Mark Reinhold messages (here and here) on the OpenJDK jdk-dev mailing list proposed two new JEPs for inclusion with JDK 11: JEP 329 ["ChaCha20 and Poly1305 Cryptographic Algorithms"] and JEP 330 ["Launch Single-File Source-Code Programs"]. I am excited about JEP 330, but that enthusiasm led me to blog on it when it was but a mere "draft" JEP (not even assigned to the 330 number at that point). The focus of the remainder of this post will therefore be on JEP 329.

The intent of JEP 329 is succinctly described in the JEP's "Summary" section: "Implement the ChaCha20 and ChaCha20-Poly1305 ciphers as specified in RFC 7539." That same "Summary" section also states, "ChaCha20 is a relatively new stream cipher that can replace the older, insecure RC4 stream cipher."

The RC4 (Rivest Cipher 4) stream cipher has already been disabled in major web browsers (early 2016) due to security risks:

The "Motivation" section of JEP 329 currently states:

The only other widely adopted stream cipher, RC4, has long been deemed insecure. The industry consensus is that ChaCha20-Poly1305 is secure at this point in time, and it has seen fairly wide adoption across TLS implementations as well as in other cryptographic protocols. The JDK needs to be on par with other cryptographic toolkits and TLS implementations.

It is worth noting this important caveat mentioned in JEP 329's "Non-Goals" section: "TLS cipher suite support will not be part of this JEP. TLS support for these ciphers will be part of a follow-on enhancement." For additional details, see JDK-8140466 : ChaCha20 and Poly1305 Cipher Suites.

The "Dependencies" section of JEP 329 states that its only dependency is on the "constant-time math APIs" embodied in JEP 324 (see my previous post for additional overview details).

JDK-8198925 : ChaCha20 and ChaCha20-Poly1305 Cipher Implementations provides additional and even lower-level details than JEP 329. For example, it provides the specification of the new class javax.crypto.spec.ChaCha20ParameterSpec and its methods.

As of this writing, there are currently 8 JEPs targeted for JDK 11 and the 2 additional JEPs highlighted in this post's title are now proposed to target JDK 11, bringing the total number of JEPs targeted or likely to be targeted to JDK 11 to ten.

Monday, May 21, 2018

New JDK 11 Files Methods for Reading/Writing Strings From/To Files

My previous post focused on the Files.isSameContent() method that is likely to be added to JDK 11. JDK-8201276 ["(fs) Add methods to Files for reading/writing a string from/to a file"] mentions this new method and also highlights the methods that are the subjects of this post:

  • readString(Path)
  • readString(Path, Charset)
  • writeString(Path, CharSequence, OpenOption...)
  • writeString(Path, CharSequence, Charset, OpenOption...)

Joe Wang recently posted the message "RFR (JDK11/NIO) 8201276: (fs) Add methods to Files for reading/writing a string from/to a file" on the core-libs-dev mailing list. In this message, Wang provided links to the related bug (JDK-8201276), to the proposed specification (API) differences, and to the proposed code changes.

This is another case where a proposed change leads to some interesting discussion. The thread started with this message includes discussion regarding whether or not to include operating-system specific line separators Files.readString in methods implementations, discussion of alternatives of the readString methods such as simple Files.lines().collect(Collectors.joining("\n")), explanation of how raw string literals handle line separators, a described example of a common use case for these methods, and use of File.deleteOnExit() with unit tests.

JDK-8201276 shows that the proposed methods to implement "common operations" for "reading the content of a file into a string and writing a string text to a file" are currently planned for JDK 11.

New JDK 11 Files Method isSameContent()

It has been proposed that a method named isSameContents() be added to the Files class in JDK 11 via JDK-8202285 ["(fs) Add a method to Files for comparing file contents"]. Proposed by Joe Wang, this new method is "intended to be an extension to the existing isSameFile method since it stopped short of comparing the content to answer the query for whether two files are equal." JDK-8201276 also references this method and describes it as "a utility method that compares two files."

Regarding the usage of this new method, JDK-8202285's Description states:

Proposing a new Files method isSameContent. Files currently has a method called isSameFile that answers the query on whether or not two files are the same file. Since two files containing the same contents may also be viewed as the same, it is desirable to add a method that further compares the contents, that would make the "is same file" query complete.

The OpenJDK core-libs-dev mailing list discussion on this thread provides additional details on the background of, motivation for, and implementation of this new method. For example, there are messages on this thread that do the following:

A particularly insightful message in this thread is a Rémi Forax message providing code demonstrating how to use the JDK 9-added InputStream.transfer(OutputStream) method, the JDK 10-added local variable type inference, and classes MessageDigest and DigestOutputStream to hash the contents of a file in six lines of Java code.

It's looking increasingly likely that JDK 11 will provide several new useful "utility" methods in addition to the JEPs and other more significant features that will be coming with JDK 11.

Saturday, May 19, 2018

Predicate::not Coming to Java

Jim Laskey's recent message "RFR: CSR - JDK-8203428 Predicate::not" on the OpenJDK core-libs-dev mailing list calls out JDK Bug JDK-8203428 ["Predicate::not"]. The "Summary" of JDK-8203428 states, "Introduce a new static method Predicate::not which will allow developers to negate predicate lambdas trivially." It is currently assigned to JDK 11.

The "Problem" section of JDK-8203428 provides a succinct description of the issue that Predicate::not addresses:

The requirement for predicate negation occurs frequently since predicates are defined antipodal to a positive selection; isNull, isEmpty, isBlank.

Presently there is no easy way to negate a predicate lambda without first wrapping in a Predicate Object.

There is a highly illustrative example of how this would work in the JDK-8203428 write-up. The "Problem" section of JDK-8203428 provides code that demonstrates how "predicate negation" would be performed today and the "Solution" section provides code demonstrating how the same functionality could be implemented with the proposed static method Predicate::not.

There are some other interesting messages in this mailing list thread. A Brian Goetz message in the thread states that "we did discover that default methods on [functional interfaces] combined with subtyping of [functional interfaces] caused trouble. But static methods are fine." A Rémi Forax message in the thread states that "stackoverflow has already decided that Predicate.not was the right method." A Sundararajan Athijegannathan message in the thread points out that "not(String::isEmpty) reads almost like !str.isEmpty()".

A message on a different thread on the core-libs-dev mailing list adds this additional context regarding the motivation behind the addition of Predicate.not(): "One of the rationals for adding 'Predicate.not' is to avoid adding another stream operation" because "we are trying to avoid adding 'overloaded' forms of the same kind of operation." This Paul Sandoz message provides the example that one would use the general filter(not(String::isEmpty)) rather than a specific Filter.reject or Filter.notFilter operation.

The addition of static function not(Predicate<T>) to Predicate is a small thing, but should improve the fluency of many lines of Java code.

Monday, May 14, 2018

Three New JEPs Targeted for JDK 11

Three new JEPs were targeted for JDK 11 a week ago today (7 May 2014). In three separate messages on the jdk-dev mailing list, Mark Reinhold made the following announcements:

JEP 324: Key Agreement with Curve25519 and Curve448

The "Summary" section of JEP 324 ("Key Agreement with Curve25519 and Curve448") states, "Implement key agreement using Curve25519 and Curve448 as described in RFC 7748." The Curve25519 entry on Wikipedia has an opening paragraph that makes it clear why this particular elliptic curve is well-suited as an addition to the JDK. It states that "Curve25519 is an elliptic curve offering 128 bits of security" that is "designed for use with the elliptic curve Diffie–Hellman (ECDH) key agreement scheme and is one of the fastest ECC curves and is not covered by any known patents." It adds that "the reference implementation is public domain software."

D. J. Bernstein provides a more specific and approachable summary of the value of Curve25519: "Given a user's 32-byte secret key, Curve25519 computes the user's 32-byte public key. Given the user's 32-byte secret key and another user's 32-byte public key, Curve25519 computes a 32-byte secret shared by the two users. This secret can then be used to authenticate and encrypt messages between the two users."

RFC 7748 ("Elliptic Curves for Security") is a memo provided by the Internet Research Task Force (IRTF) that "specifies two elliptic curves [curve25519 and curve448] over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS), and that are "intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties."

The "primary goal" of JEP 324 is to provided "an API and an implementation for [the RFC 7748] standard," the two additional goals are also spelled out. One of the additional goals is to provide "a platform-independent, all-Java implementation with better performance than the existing ECC (native C) code at the same security strength."

Current plans for JEP 324 only involve an RFC implementation in the SunEC elliptic curve cryptography provider. However, with an API provided ("XDH"), it seems possible for other ECC providers to implement RFC 7748 as desired. JEP 324 currently adds this important note: "This new library will be in an internal JDK package, and will only be used by new crypto algorithms."

JEP 327: Unicode 10

JEP 327 ("Unicode 10") provides a straightforward "Summary": "Upgrade existing platform APIs to support version 10.0 of the Unicode Standard." The WikiBooks entry "Unicode/Versions" lists each major version of Unicode from Unicode 1.0 through Unicode 12.0. Unicode 10 was released last summary and Unicode 11 is planned for next month.

An early history/mapping of Java versions to Unicode versions is provided in "Unicode Versions Supported in Java-History," which shows Unicode 1.1.5 associated with JDK 1.0 through Unicode 6.0 associated with JDK 7. Unicode 6.2.0 was supported by JDK 8, Unicode 8.0.0 was supported by JDK 9 and JDK 10, so JDK 11 will add support for both Unicode 9.0 and Unicode 10.0.

JEP 327 explicitly lists "four related Unicode specifications" (Unicode Technical Standards) that "will not be implemented" as part of JEP 327. These are UTS #10 ("Unicode Collation Algorithm"), UTS #39 ("Unicode Security Mechanisms"), UTS #46 ("Unicode IDNA Compatibility Processing"), and UTS #51 ("Unicode Emoji").

JEP 328: Flight Recorder

JEP 328 ("Flight Recorder") aims to "provide a low-overhead data collection framework for troubleshooting Java applications and the HotSpot JVM." In its "Motivation" section, this JEP states, "Flight Recorder records events originating from applications, the JVM and the OS. Events are stored in a single file that can be attached to bug reports and examined by support engineers, allowing after-the-fact analysis of issues in the period leading up to a problem. Tools can use an API to extract information from recording files."

The current Java Mission Control page describes Java Flight Recorder and its relationship to Java Mission Control:

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collection framework built into the Oracle JDK. It allows Java administrators and developers to gather detailed low level information about how the Java Virtual Machine (JVM) and the Java application are behaving. Java Mission Control is an advanced set of tools that enables efficient and detailed analysis of the extensive of data collected by Java Flight Recorder. The tool chain enables developers and administrators to collect and analyze data from Java applications running locally or deployed in production environments.

This JEP is another step in achieving the announcement made last September that "Oracle will also open source commercial features such as Java Flight Recorder previously only available in the Oracle JDK." Marcus Hirt announced just this month that Java Mission Control has been open sourced with repositories available at http://hg.openjdk.java.net/jmc.

Summary

The three JEPs highlighted in this post now bring the number of JEPs currently associated with JDK 11 to a total of eight:

Saturday, May 12, 2018

Java's @Serial Annotation

The JDK may be getting another standard (predefined) annotation with JDK 11: @Serial. JDK-8202385 ["Annotation to mark serial-related fields and methods"] aims to add "some kind of 'SerialRelated' annotation to facilitate automated checking of the declarations of serial fields and methods." The idea is to better indicate to a developer when a serialization-related field or method is misspelled similar to the way that "the java.lang.Override annotation type is used to signal the compiler should verify the method is in fact overridden."

Joe Darcy recently requested review of the "webrev" (proposed code addition). This provides a peek at what the new @Serial might look like. The current proposal is for this annotation definition to reside in the java.io package, to be targeted at specific methods or fields, and to have SOURCE retention.

The Javadoc comments for the proposed definition of @Serial currently provide significant detail on how to use this annotation. This Javadoc also explicitly specifies which methods and fields are anticipated to be annotated with @Serial: writeObject(), readObject(), readObjectNoData(), writeReplace(), readResolve(), ObjectStreamField[], and serialVersionUID.

The proposed @Serial annotation will be checked when the javac "serial" lint check is executed. This is described in Darcy's e-mail request for review:

The proposed java.io.Serial annotation type is intended to be used along with an augmented implementation of javac's "serial" lint check; that work will be done separately as part of JDK-8202056: "Expand serial warning to check for bad overloads of serial-related methods".

It's interesting to note that the name of this annotation is not necessarily finalized, though it seems likely to stick. Darcy's e-mail message points out that alternate names such as @Serialize and @SerialRelated could also be used.

An interesting distinction is that the @Serial annotation cannot or should not be used with certain methods and certain fields of the Externalizable interface (extends Serializable) because those methods and fields are not used in Externalizable. More details on this distinction are available in the core-libs-dev messages 053060, 053061, 053064, and 053067.

The @Serial annotation is not officially scheduled for JDK 11 as of this writing, but it appears likely that it could be available in time for the JDK 11 release given the recent progress of JDK-8202385. Besides the potential usefulness of this annotation to those implementing custom serialization, this annotation's definition will provide another example of how any custom annotation can be documented to allow it to be used correctly.

Tuesday, May 1, 2018

New Methods on Java String with JDK 11

It appears likely that Java's String class will be gaining some new methods with JDK 11, expected to be released in September 2018.

BUG #BUG TITLENEW String METHODDESCRIPTION
JDK-8200425 String::lines lines() "String instance method that uses a specialized Spliterator to lazily provide lines from the source string."
JDK-8200378 String::strip, String::stripLeading, String::stripTrailing strip() "Unicode-aware" evolution of trim()
stripLeading() "removal of Unicode white space from the beginning"
stripTrailing() "removal of Unicode white space from the ... end"
JDK-8200437 String::isBlank isBlank() "instance method that returns true if the string is empty or contains only white space"

Evidence of the progress that has been made related to these methods can be found in messages requesting "compatibility and specification reviews" (CSR) on the core-libs-dev mailing list:

A common characteristic of four of these five new methods is that they use a different (newer) definition of "whitespace" than did old methods such as String.trim(). Bug JDK-8200373 ["String::trim JavaDoc should clarify meaning of space"] even addresses this for the String.trim() method (mailing list review request):

The current JavaDoc for String::trim does not make it clear which definition of "space" is being used in the code. With additional trimming methods coming in the near future that use a different definition of space, clarification is imperative. String::trim uses the definition of space as any codepoint that is less than or equal to the space character codepoint (\u0040.) Newer trimming methods will use the definition of (white) space as any codepoint that returns true when passed to the Character::isWhitespace predicate.

The method isWhitespace(char) was added to Character with JDK 1.1, but the method isWhitespace(int) was not introduced to the Character class until JDK 1.5. The latter method (the one accepting a parameter of type int) was added to support supplementary characters. The Javadoc comments for the Character class define supplementary characters (typically modeled with int-based "code point") versus BMP characters (typically modeled with single character):

The set of characters from U+0000 to U+FFFF is sometimes referred to as the Basic Multilingual Plane (BMP). Characters whose code points are greater than U+FFFF are called supplementary characters. The Java platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes. In this representation, supplementary characters are represented as a pair of char values ... A char value, therefore, represents Basic Multilingual Plane (BMP) code points, including the surrogate code points, or code units of the UTF-16 encoding. An int value represents all Unicode code points, including supplementary code points. ... The methods that only accept a char value cannot support supplementary characters. ... The methods that accept an int value support all Unicode characters, including supplementary characters.

I added the bold emphasis in the above quote to emphasize the significance of a "code point," which is defined for the Java context as "a value that can be used in a coded character set". Four of the five proposed new methods for String in JDK 11 rely heavily on the concept embodied in Character.isWhitespace(int) to determine how to "trim" a given string or when determining if a given string is "blank."

Speaking of Unicode, JEP 327 ["Unicode 10"] has been proposed to be added to JDK 11 as well. As that JEP states, its intent is to "upgrade existing platform APIs to support version 10.0 of the Unicode Standard."

Conclusion

The new methods on String currently proposed for JDK 11 provide a more consistent approach to handling white space in strings that can better handle internationalization, provide methods for trimming whitespace only at the beginning of the string or at the end of the string, and provide a method especially intended for coming raw string literals.

Additional References