Tuesday, February 27, 2018

JDK 11 Early Access Builds and Renaming "Incubating" as "Preview"

Mark Reinhold posted "JDK 11 early-access builds" on the jdk-dev mailing list in which he wrote, "JDK 11 EA builds, under both the GPL and Oracle EA licenses, are now available at http://jdk.java.net/11." Reinhold adds, "These builds include JEP 320 (Remove the Java EE and CORBA Modules), so they're significantly smaller (nine fewer modules, 22 fewer megabytes on Linux/x64)."

In the post "Rename 'incubating' language/VM features to 'preview'" on the same jdk-dev mailing list, Alex Buckley opens with, "Members of the Expert Group for JSR 384 (Java SE 11) have indicated to the Spec Lead that they support the goal of releasing non-final language/VM features in order to gain developer feedback, but also feel that the "incubating" terminology is too confusing." Buckley differentiates between "incubating APIs" (JEP 11) and "incubating language/VM features" and proposes renaming "incubating language/VM features" as "'preview language/VM features' for a number of reasons." Buckley concludes the message with related proposals to "[drop] the operand to --preview" and to "[allow] preview features only when --release is specified."

Monday, February 26, 2018

Java May Use UTF-8 as Its Default Charset

Because Java-based applications are often used in a wide variety of operating systems and environments, it is not uncommon for Java developers to run into issues related to character-based input and output. Blog posts covering these issues include The Policeman's Horror: Default Locales, Default Charsets, and Default Timezones; Annotating JDK default data; Encoding issues: Solutions for linux and within Java apps; Silly Java Strings; Java: a rough guide to character encoding; and this post with too long of a title to list here.

Several enhancements have been made to Java over the years to reduce these issues, but there are still sometimes issues when the default charset is implicitly used. The book Java Puzzlers features a puzzle (Puzzle #18) describing the quirkiness related to the "vagaries of the default charset" in Java.

With all of these issues related to Java's default charset, the presence of the draft JEP "Use UTF-8 as default Charset" (JDK-8187041) is welcome. In addition to potentially resolving issues related to the default charset, this JEP already provides a nice overview of what these issues are and alternatives to deal with these issues today. The JEP's "Motivation" section currently summarizes why this JEP is significant: "APIs that use the default charset are a hazard for developers that are new to the Java platform" and "are also a bugbear for experienced developers."

The issues with "default" charset are complicated by different uses of charsets and by different approaches currently available in the JDK APIs that lead to more than one "default." Here is a breakdown of the issues to be considered.

The draft JEP "Use UTF-8 as default Charset" will help address the issues related to different types of "default" when it comes to charset used by default for reading and writing file contents. For example, it will remove the potential conflict that could arise from writing a file using a method that uses the platform default and reading that file from a method that always uses UTF-8 regardless of the platform default charset. Of course, this is only a problem in this particular case if the platform default is NOT UTF-8.

The following Java code is a simple class that prints out some of the settings related to charsets.

Displaying Default Charset Details

package dustin.examples.charset;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Locale;

import static java.lang.System.out;

/**
 * Demonstrate default Charset-related details.
 */
public class CharsetDemo
{
   /**
    * Supplies the default encoding without using Charset.defaultCharset()
    * and without accessing System.getProperty("file.encoding").
    *
    * @return Default encoding (default charset).
    */
   public static String getEncoding()
   {
      final byte [] bytes = {'D'};
      final InputStream inputStream = new ByteArrayInputStream(bytes);
      final InputStreamReader reader = new InputStreamReader(inputStream);
      final String encoding = reader.getEncoding();
      return encoding;
   }

   public static void main(final String[] arguments)
   {
      out.println("Default Locale:   " + Locale.getDefault());
      out.println("Default Charset:  " + Charset.defaultCharset());
      out.println("file.encoding;    " + System.getProperty("file.encoding"));
      out.println("sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding"));
      out.println("Default Encoding: " + getEncoding());
   }
}

The next screen snapshot shows the results of running this simple class on a Windows 10-based laptop without explicitly specifying either charset-related system property, with specification only of the file.encoding system property, and with specification of both system properties file.encoding and sun.jnu.encoding.

The image just shown demonstrates the ability to control the default charsets via properties. It also demonstrates that, for this Windows environment with a locale of en_US, the default charset for both file contents and file paths is windows-1252 (Cp1252). If the draft JEP discussed in this post is implemented, the default charset for file contents will be changed to UTF-8 even for Windows.

There is the potential for significant breakage in some applications when the default charset is changed to be UTF-8. The draft JEP talks about ways to mitigate this risk including early testing for an application's susceptibility to the change by explicitly setting the system property file.encoding to UTF-8 beforehand. For cases where it is necessary to keep the current behavior (using a system-determined default charset rather than always using UTF-8), the current version of the draft JEP proposes supporting the ability to specify -Dfile.encoding=SYSTEM.

The JEP is in draft currently and is not associated with any particular JDK version. However, based on recent posts on the JDK mailing lists, I am optimistic that we'll see UTF-8 as the default charset in a future version of the JDK in the not too distant future.

Saturday, February 24, 2018

Prefer System.lineSeparator() for Writing System-Dependent Line Separator Strings in Java

JDK 7 introduced a new method on the java.lang.System class called lineSeparator(). This method does not expect any arguments and returns a String that represents "the system-dependent line separator string." The Javadoc documentation for this method also states that System.lineSeparator() "always returns the same value - the initial value of the system property line.separator." It further explains, "On UNIX systems, it returns "\n"; on Microsoft Windows systems it returns "\r\n"."

Given that a Java developer has long been able to use System.getProperty("line.separator") to get this system-dependent line separator value, why would that same Java developer now favor using System.lineSeparator instead? JDK-8198645 ["Use System.lineSeparator() instead of getProperty("line.separator")"] provides a couple reasons for favoring System.lineSeparator() over the System.getProperty(String) approach in its "Description":

A number of classes in the base module use System.getProperty("line.separator") and could use the more efficient System.lineSeparator() to simplify the code and improve performance.

As the "Description" in JDK-8198645 states, use of System.lineSeparator() is simpler to use and more efficient than System.getProperty("line.separator"). A recent message on the core-libs-dev mailing list provides more details and Roger Riggs writes in that message that System.lineSeparator() "uses the line separator from System instead of looking it up in the properties each time."

The performance benefit of using System.lineSeparator() over using System.getProperty("line.separator") is probably not all that significant in many cases. However, given its simplicity, there's no reason not to gain a performance benefit (even if tiny and difficult to measure in many cases) while writing simpler code. One of the drawbacks to the System.getProperty(String) approach is that one has to ensure that the exactly matching property name is provided to that method. With String-based APIs, there's always a risk of spelling the string wrong (I have seen "separator" misspelled numerous times as "seperator"), using the wrong case, or accidentally introducing other typos that prevent exact matches from being made.

The JDK issue that introduced this feature to JDK 7, JDK-6900043 ("Add method to return line.separator property"), also spells out some benefits in its "Description": "Querying the line.separator value is a common occurrence in large systems. Doing this properly is verbose and involves possible security failures; having a method return this value would be beneficial." Duplicate JDK-6264243 ("File.lineSeparator() to retrieve value of commonly used 'line.separator' system property") spells out advantages of this approach with even more detail and lists "correctness", "performance", and "ease of use and cross-platform development" as high-level advantages. Another duplicate issue, JDK-6529790 ("Please add LINE_SEPARATOR constant into System or some other class"), makes the point that there should be a "constant" added to "some standard Java class, as String or System," in a manner similar to that provided for file separators by File.pathSeparator.

One of the messages associated with the JDK 7 introduction of System.lineSeparator() justifies it additions with this description:

Lots of classes need to use System.getProperty("line.separator"). Many don't do it right because you need to use a doPrivileged block whenever you read a system property. Yet it is no secret - you can divine the line separator even if you have no trust with the security manager.

An interesting side note related to the addition of System.lineSeparator() in JDK 7 is that the Javadoc at that time did not indicate that the method was new to JDK 7. JDK-7082231 ("Put a @since 1.7 on System.lineSeparator") addressed this in JDK 8 and two other JDK issues (JDK-8011796 and JDK-7094275) indicate that this was desired by multiple Java developers.

The introduction of System.lineSeparator() was a very small enhancement, but it does improve the safety and readability of a relatively commonly used API while not reducing (and, in fact, while improving) performance.

Wednesday, February 21, 2018

JDK 10: FutureTask Gets a toString()

I've felt for a long time that, for most Java classes that have distinguishing attributes, developers should take the time to override Object.toString(), even if it's just with an IDE-generated implementation or using a library class such as Apache Commons Lang's ToStringBuilder. The overloaded Objects.toString() methods also make this easier than ever if one wants to implement toString by hand. The JDK class FutureTask, introduced with J2SE 5, finally gets its own toString() implementation in JDK 10.

Richard Nichols's 2012 post "How to get the running tasks for a Java Executor..." highlights the omission of a toString() method on the FutureTask class. He wrote:

It seems odd that the API doesn't include any way to gather info about what's happening inside the Executor, and also, there's not even a toString() implementation for wrapping classes like FutureTask which would bubble your Runnable or Callable classes' toString() methods.

Nichols's post is in the context of his observation that "it's quite difficult to actually expose at run-time what ... Java's Executor is actually doing at any point in time."

Issue JDK-8186326 ["Make toString() methods of "task" objects more useful"] talks about aligning FutureTask toString() with that of CompletableFuture, which the issue states "already has a useful toString method, giving the current status." An e-mail thread in late 2017 documents the discussions around the addition of toString() to FutureTask and other "task classes in j.u.c." (java.util.concurrent).

The Javadoc comments for the new FutureTask.toString() method state, "The default implementation returns a string identifying this FutureTask, as well as its completion state. The state, in brackets, contains one of the strings 'Completed Normally', 'Completed Exceptionally', 'Cancelled', or 'Not completed'." Three of these four potential completion states for FutureTask's toString() are also potentially written as part of CompletableFuture's toString() ["Cancelled" is the exception].

The addition of a specific implementation of toString() to the FutureTask class in JDK 10 is a small one. However, for a developer "staring at output of toString for 'task' objects (Runnables, Callables, Futures) when diagnosing app failures" as described in JDK-8186326's "Problem" statement, this "small" addition is likely to be very welcome.

Tuesday, February 20, 2018

JDK 10: Accessing Java Application's Process ID from Java

A popular question on StackOverflow.com is, "How can a Java program get its own process ID?" There are several answers associated with that question that include parsing the String returned by ManagementFactory.getRuntimeMXBean().getName() [but that can provide an "arbitrary string"], using ProcessHandle.getPid() [JEP 102], using Java Native Access (JNA), using System Information Gatherer And Reporter (SIGAR), using JavaSysMon, using Java Native Runtime - POSIX, parsing the results of jps (or jcmd) via invocation of Runtime.getRuntime().exec(String), and other approaches. JDK 10 introduces perhaps the easiest approach of all for obtaining a JVM process's PID via a new method on the RuntimeMXBean.

JDK-8189091 ("MBean access to the PID") introduces the RuntimeMXBean method getPid() as a default interface method with JDK 10. That issue states the "Problem" as: "The platform MBean does not provide any API to get the process ID of a running JVM. Some JMX tools rely on the hotspot implementation of RuntimeMXBean::getName which returns < pid >@< hostname >." The issue also provides the "Solution": "Introduced new API java.lang.management.RuntimeMXBean.getPid, so that JMX tools can directly get process ID instead of relying on the implementation detail, RuntimeMXBean#getName().split("@")[0]."

The next code listing is a simple one and it demonstrates use of this new getPid() method on RuntimeMXBean.

Using JDK 10's RuntimeMXBean.getPid()

final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
final Console console = System.console();
out.println("Process ID is '" + pid + "' Press <ENTER> to continue.");
console.readLine();

When the code above is contained within an executable main(String[]) function and that function is executed from the command line, the output is as shown in the next screen snapshot (which also includes a separate terminal used to verify the PID is correct via jcmd).

The process ID is provided as a long and no parsing of an "arbitrary string" is necessary. This approach also does not require a third-party library or elaborate code to determine the current Java process's identifier.

This post has provided a brief introduction to what will perhaps be the easiest approach for a Java application (written with JDK 10 or later) to determine its own underlying process ID.

Monday, February 19, 2018

JDK 10's Summary Javadoc Tag

JDK 10 introduces a Javadoc tag {@summary} via issue JDK-8173425 ("Javadoc needs a new tag to specify the summary."). This new tag allows the developer to explicitly specify what portion of the Javadoc comment appears in the "summary" rather than relying on Javadoc's default treatment looking for a period and space to demarcate the end of the summary portion of the comment. JDK-8173425 states, "Currently in javadoc the summary (firstsentence) of an element is deciphered by a dot-space rule, or if required using BreakIterator." It adds that it can be confusing to know what that implicitly selected summary sentence will be.

The easiest way to see {@summary} in action may be through Javadoc examples. The next code listing shows four methods with similar Javadoc comments, two using explicit {@summary} tags and two relying on implicit Javadoc summary construction.

Demonstrating {@summary} in Javadoc Method Comments

package dustin.examples.javadoc;

/**
 * Demonstrate JDK 10 added summary support. Demonstrates
 * this by comparing similar methods' Javadoc comments with
 * and without use of new "@summary" tag.
 */
public class Summary
{
   /**
    * This method's first sentence is normally in the summary.
    * Here are some of its characteristics:
    * <ul>
    * <li>This method does great things.</li>
    * <li>This method does not really do anything.</li>
    * </ul>
    */
   public void implicitSummary1()
   {
   }

   /**
    * This method's first sentence is normally in the summary.Here are some of its characteristics:
    * <ul>
    * <li>This method does great things.</li>
    * <li>This method does not really do anything.</li>
    * </ul>
    */
   public void implicitSummary2()
   {
   }

   /**
    * {@summary This method's first sentence is normally in the summary.
    * Here are some of its characteristics:
    * <ul>
    * <li>This method does great things.</li>
    * <li>This method does not really do anything.</li>
    * </ul>}
    */
   public void explicitSummary1()
   {
   }

   /**
    * {@summary This method's first sentence is normally in the summary.Here are some of its characteristics:
    * <ul>
    * <li>This method does great things.</li>
    * <li>This method does not really do anything.</li>
    * </ul>}
    */
   public void explicitSummary2()
   {
   }
}

When the Javadoc tool delivered with the first JDK 10 (18.3) Release Candidate (Build 43) is executed against this simple class, the "Method Summary" section of the generated HTML appears as follows in a web browser.

Comparing the HTML output to the commented Java code above it demonstrates how the {@summary} allows for explicit control of what appears in the methods' summaries.

Saturday, February 17, 2018

String#repeat Coming to Java?

JDK-8197594 ("String#repeat") includes the following it its "Description": "A String method for repeating sequences of characters has been long requested with no follow through." Evidence of this interest in a method on the String class for repeating sequences of characters can be found in JDK-8197594's "Issue Links" that include JDK-8055862 ["Provide a String repeat method"] and JDK-6984084 ["(str) n times repetition of character constructor for java.lang.String"]. Both of these linked issues describe motivations for having such a method in the String class. Further evidence includes online questions such as Simple way to repeat a String in java, How to repeat string “n” times in java?, What is the simple way to repeat a string in Java?, and How do you repeat a string n number of times in Java programming?

Guava provides this desired behavior via its Strings.repeat(String, int) method and Apache Commons Lang provides this functionality via its StringUtils.repeat(String, int). It's also likely that this functionality has been implemented hundreds of times or more in individual projects. The availability of a standard java.lang.String.repeat(String, int) method could replace all of these.

The discussion on the core-libs-dev JDK mailing list regarding JDK-8197594 offers up some additional intriguing details regarding this likely addition to a future version of Java.

One interesting point is made in Jim Laskey's message in which he describes potential performance improvements that this method would provide. Specifically, Laskey writes that "performance runs with jmh ... show that these methods are significantly faster than StringBuilder equivalents" and Laskey attributes this to "fewer memory allocations," "fewer char to byte array conversions," and "faster pyramid replication vs O(N) copying." Because this is open source, the currently proposed implementation that brings these performance benefits is provided. For those who are interested, the two aforementioned open source projects have obviously made their source code available [Guava's Strings.repeat(String, int) and Apache Commons Lang's String repeat(String, int)].

Brian Goetz has posted a second reason for adding a method such as String.repeat in the standard API: to turn common functionality implemented via statements into composible expressions. Goetz explains, "My primary motivation for these sorts of methods is to take things that require execution as _statements_ (loops, if-then, etc) and turn them into _expressions_, not primarily because they are more compact, but because they are then _composible_." Goetz has described the advantages of expressions before and this is one of the primary motivations of the draft JEP related to switch expressions in Java.

A new method on java.lang.String to repeat a character sequence a specified number of times won't be as big of a deal as many other new API additions and new language features, but it can provide advantages such as not needing third-party or custom implementations, improved performance, and a standardized expression form of a commonly implemented behavior. As of this writing, JDK-8197594 is not associated with a particular Java version and is instead labeled "tbd_feature".

Friday, February 16, 2018

First JDK 10 (18.3) Release Candidate (Build 43) Demonstrates New Versioning Scheme

Mark Reinhold's post "JDK 10: First Release Candidate" announced "no unresolved P1 bugs in build 43" and named that Build 43 the initial JDK 10 Release Candidate. The Reinhold post also points to the "JDK 10 Early-Access Builds" page which contains links to the release notes; to the Javadoc-based API documentation; to the "early-access, open-source builds" (OpenJDK) for Windows, Linux, macOS, and Alpine Linux; and to the Oracle JDK builds.

The following screen snapshot shows the version information provided by the OpenJDK 10 Build 43 (the text in the screen snapshot is reproduced below the image):

openjdk version "10" 2018-03-20
OpenJDK Runtime Environment 18.3 (build 10+43)
OpenJDK 64-Bit Server VM 18.3 (build 10+43, mixed mode)

The next screen snapshot shown the version information provided by the Oracle JDK 10 Build 43 (the text in the screen snapshot is reproduced below the image):

java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+43)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+43, mixed mode)

As the above screen snapshots show, the -version information for the OpenJDK and OracleJDK currently show both forms. They show the "10" in quotes for JDK 10, but they also show 18.3. This is consistent with the JSR 383 title ["Java SE 10 (18.3) Platform JSR (383)"] and its description.

There has been some confusion regarding the versioning scheme for versions of Java after JDK 9 because of rapid changing developments in plans for Java version names. Some key posts on the developing version naming after JDK 9 are shown below.

  1. Moving Java Forward Faster (6 September 2017)
    • Proposed that "after Java 9 we adopt a strict, time-based model with a new feature release every six months, update releases every quarter, and a long-term support release every three years."
    • "To make it clear that these are time-based releases, and to make it easy to figure out the release date of any particular release, the version strings of feature releases will be of the form $YEAR.$MONTH." This is where the "18.3" comes from in the above examples (representing March 2018).
    • Related post "Accelerating the JDK release cadence" discusses approaches to be taken with "the ultimate goal" of making "OpenJDK and Oracle JDK builds completely interchangeable."
  2. Version-string schemes for the Java SE Platform and the JDK (19 October 2017)
    • Addresses community concern and responses (such as this one) to original proposal.
    • Outlines criteria to be considered when selecting a versioning scheme.
    • Presents potential alternatives that satisfy the outlined criteria.
    • References Wadler's Law.
  3. Proposal: Newer version-string scheme for the Java SE Platform and the JDK (2 November 2017)
    • Introduces scheme $FEATURE.$INTERIM.$UPDATE.$EMERG
    • $FEATURE is "the feature-release counter, incremented every six months regardless of release content."
    • "This is primarily a time-based scheme, since $FEATURE is incremented every six months regardless of release content and, for each feature release, $UPDATE is incremented every three months."
    • JEP 223-compliant system property java.version.date is added and is the "intended GA date" in "ISO-8601 YYYY-MM-DD format." It is "some date in the future" for early access releases. In the examples above, the expected release General Availability release date is 2018-03-20.
  4. Updating the version number (1 December 2017)
    • States that JSR-383 documents will be updated to reference "10 (18.3)" instead of "18.3".
  5. Why do "Oracle JDK 10 builds" not support AppCDS? (16 February 2018)
    • I include this post because it provides a specific concrete example of how the version name differs for early access builds ("10-ea+42") versus release candidate builds intended for eventual general availability ("10+43").

The screen snapshots shown in this post depict the versions associated with the available initial build of JDK 10 Release Candidate. This initial build provides an early look at the new JDK version naming scheme in action.

Monday, February 12, 2018

APIs To Be Removed from Java 10

In the blog post "JDK 10 Release Candidate Phase", I looked at the twelve new features that are likely to be part of JDK 10. In this post, I look at some of the APIs that appear likely to be removed in JDK 10 and I look at some APIs proposed to be deprecated in JDK 10. The information in this post is based on the current version (2018/1/31 19:49 -0800 [a337d4f5aa79]) of "Java SE 10 (18.3) (JSR 383) Proposed Final Draft Specification - DRAFT" and, because this source document is a draft, this information is subject to change.

The JDK 9 enhanced deprecation feature (JEP 277) allowed several JDK APIs to be annotated with @Deprecated's new optional forRemoval() element to be set to true, which indicates that the annotated API "is earmarked for removal in a future release." The following APIs had this enhanced deprecation applied, were marked for "removal in a future release" in JDK 9, and now JDK 10 appears to be the version in which they'll be removed.

As currently proposed, JDK 10 will add the optional annotation element forRemoval=true to some previously deprecated [@Deprecated] API elements that did not formerly have forRemoval set. These include security-related interfaces, classes, and exceptions that have been replaced by other security-related constructs (many were replaced as far back as JDK 1.2). Several "finalize"-ending methods also have their @Deprecated annotation enhanced to indicate that as of JDK 10 they are "earmarked for removal in a future release." For example, FileInputStream.finalize() was deprecated in JDK 9, but will be marked with forRemoval=true as of JDK 10.

Most of the JDK API constructs to be removed in JDK 10 have been deprecated for a long time (since JDK 1.2 or earlier) and so there has been plenty of time to replace use of these. Most of the JDK API constructs newly denoted in JDK 10 to be removed in a future release have already been deprecated and this change is only to indicate that they now will likely be removed in a future release. The JDK 9-introduced enhanced deprecation mechanism allows the JDK API to have constructs more aggressively removed after having their likely removal advertised in advance via the forRemoval=true element of the @Deprecated annotation. JDK 9 removed several things and it appears likely that JDK 10 will continue the removal of certain previously deprecated API elements.

Saturday, February 10, 2018

Executing Single Java Source Files with One Command

A draft JDK Enhancement Proposal (JEP) was created in late 2017 called "Launch Single-File Source-Code Programs" (its associated JDK issue is JDK-8192920). As its name suggests, this draft JEP aims to "enhance the java launcher to support running a program supplied as a single file of Java source code." In other words, as the JEP describes, if one had a typical self-contained HelloWorld.java source code code file, one could simply run java HelloWorld.java from the command line rather than needing to use javac to compile HelloWorld.java into HelloWorld.class before running it with the java launcher.

JEP owner Jonathan Gibbons summarized this when he introduced the JEP on the compiler-dev mailing list:

This draft JEP contains a proposal to enhance the |java| launcher to support running a program supplied as a single file of Java source code. The program will be compiled and run, without the need to explicit invoke javac, or to package up a jar file.

The primary use cases for such a feature are expected to be for people to run very simple Java applications (the JEP calls them "small utility programs") and people wanting to learn about basic Java features. I have described similar use cases in my blog posts "Learning Java via Simple Tests" and "Compiling and Running Java Without an IDE". The JEP states that in the context of these use cases, "it is pure ceremony to have to compile the program before running it. In addition, a single source file may compile to multiple class files, which adds packaging overhead to the simple goal of 'run this program'. It is desirable to be able to run the program directly from source with the java launcher."

There have been two interesting discussion points on the JDK mailing lists related to this draft JEP. One of the topics discussed is the ability to put a "shebang" on the first line of a Java source code file that is intended to be run in the way this JEP describes (such as used in Groovy and numerous other languages running in Linux/Unix shells). As of this writing, the draft JEP currently addresses this topic under the section heading "Shebang" files and states:

A "shebang" file to invoke the Java launcher using source-file mode will typically begin with something like:

#!/path/to/java --source

To allow for such files in source-file mode, if the file begins with #! the contents of the first line up to but not including the first newline are removed before compiling the rest of the file. ... When the file begins with #!, the newline at the end of the first line is preserved so that the line numbers in any error messages remain unchanged.

The second interesting discussion point associated with this draft JEP is the question if its relationship with the jshell introduced with JDK 9. As Brian Goetz states in his message on the compiler-dev mailing list, it is "a natural (and common) thought" to expect that jshell would be used instead of the enhanced java launcher to run these shell-like single source Java source files. Goetz explains in that message why this isn't as good of an idea as it would first seem because jshell was explicitly designed for a "a good interactive experience" rather than as a "batch runner." The current version of the draft JEP addresses this in the Alternatives section, which states:

We could delegate the task of "one-off runs" to the jshell tool. While this may at first seem obvious, this was an explicit non-goal in the design of jshell. The jshell tool was designed to be an interactive shell, and many design decisions were made in favor of providing a better interactive experience. Burdening it with the additional constraints of being the batch runner would detract from the interactive experience.

Although this is only a draft JEP at this point, I like the idea and think it would be a nice minor feature to have added to a future version of the JDK. This feature would allow basic Java examples to be more easily tested by those new to Java and would not burden the novice Java developer with extra steps that he or she is not accustomed to using with some other (often dynamically typed) programming languages. It would also be convenient for more experienced Java developers. I still find myself writing small Java snippets to learn how something works (and to demonstrate to others how it works) and this draft proposed JDK enhancement would make that a bit easier, especially when the Java source file compiles into multiple .class files. This is one of the features I've enjoyed with Groovy development and it'd be nice to have it for simple Java development.

Monday, February 5, 2018

Java 8: Bastion of Long-term Support

Stephen Colebourne's post "Java 9 has six weeks to live" starts, "Java 9 is obsolete in just six weeks." Colebourne references the Mark Reinhold blog post "Moving Java Forward Faster" and writes, "The new Java release train means that there will be a new release of Java every six months. And when the next release comes out, the previous release is obsolete." Colebourne points out that those still on Java 8 can enjoy this "current LTS (long term support) release until the next LTS release occurs (Java 11)." However, for those who have already moved to Java 9, different choices must be made and Colebourne outlines these choices at a high level. Colebourne outlines several types of dependencies that must also move forward every six months and concludes, "I think it's fair to say that it's a bold choice to use Java 9 or 10."

As a reminder, the aforementioned Reinhold blog post "Moving Java Forward Faster" outlines how the new proposed release train addresses "the tension between developers, who prefer rapid innovation, and enterprises, which prefer stability, and the fact that everyone prefers regular and predictable releases." The following are key points of this new release train approach:

  • "Adopt a strict, time-based model with a new feature release every six months, update releases every quarter, and a long-term support release every three years." (I added the emphasis)
  • Feature Releases (which "contain any type of feature") ship in March and September of each year with the first one being March 2018 (JDK 10 that Colebourne references when he writes, "Java 9 has six weeks to live").
  • Update Releases (which are "strictly limited to fixes of security issues, regressions, and bugs in newer features") occur between the Feature Releases with two Update Releases between each Feature Release and scheduled with quarter periodicity in the months of January, April, July, and October.
  • Long-Term Support Releases are the same as the Feature Release every third year starting in September 2018. Updates for these long-term support releases will be available at least until the next long-term support release and often may be available longer than those three years.
  • Additional details regarding the Java release train can be found at the #javatrain Twitter handle, in the General OpenJDK Discussion distribution list, in the page "Oracle Java SE Support Roadmap," and in the page "Faster and Easier Use and Redistribution of Java SE."
  • It was recently announced that "the public availability of Java SE 8 updates from Oracle has been extended to at least January 2019" and that "Oracle will continue to provide consumers with updates for personal (non-corporate) use of Java SE 8 through at least the end of 2020."

Colebourne is not the only one to warn Java developers to consider the ramifications of moving from Java 8 to Java 9. In the post "Java 9: No Long-Term Support and Twice-Yearly JDK Releases," Carly Yuk writes that "Java 9 will not be entitled to long-term maintenance." Yuk adds that "enterprises that are running applications in products may want to consider waiting for the future long-term release." Paul Krill writes that "Java 9 will not receive long-term support" and Ben Evans has been paraphrased, "Since Oracle has announced that Java 8 will be a long-term support release, supported through 2022, Evans thinks that a lot of applications might stay on Java 8 and not upgrade to Java 9 at all."

There is much to think about when deciding whether to upgrade to Java 9 or not. There is no single "correct" answer as situations, environments, priorities, and uses of Java differ greatly. In general, developers of larger "enterprise" type applications will likely want to only adopt the long-term support releases and developers of smaller applications will likely be willing to adopt feature releases and associated update releases to get access to new features sooner. This ability to choose between "rapid innovation" and supported stable versions is one of the driving motivations for the new release train.

JDK 9: NotNullOrElse Methods Added to Objects Class

JDK 9 added some new methods to the Objects class including two static methods highlighted in this post: requireNonNullElse(T,T) and requireNonNullElseGet​(T obj,Supplier<? extends T> supplier). Both methods make it easier to verify that a given object is not null and to provide an alternative if the provided variable turns out to be null. As such, these methods and the similar methods introduced to Objects in earlier JDK versions [requireNonNull​(T), requireNonNull​(T,String), and requireNonNull​(T,Supplier<String>)] are most likely to be used to implement guard clauses in methods.

The three methods mentioned in the last paragraph that were added to Objects prior to JDK 9 did not allow a "default" value to be used when the object being tested was determined to be null. Instead, each of these three methods throws a NullPointerException when the variable passed to them is null. The two methods added to Objects in JDK 9 do allow a default to be specified that can be returned by the method rather than the method throwing a NullPointerException.

Objects.requireNonNullElse​(T,T) is the most straightforward approach of the two new added methods for specifying a default object to be returned when the provided variable under test is null. An example of applying this method is shown in the next code listing.

Example of Objects.requireNonNullElse​(T,T)

/**
 * Provide instance of {@code Instant} that corresponds to
 * the provided instance of {@code Date}.
 *
 * @param inputDate Instance of {@code Date} for which
 *    corresponding instance of {@code Instant} is desired;
 *    if this is {@code null}, an {@code Instant} representing
 *    "now" will be returned.
 * @return Instance of {@code Instant} extracted from provided
 *    {@Date} that will instead represent "now" if provided
 *    {@code Date} is {@code null}.
 */
public Instant convertDateToInstantWithNowDefault(final Date inputDate)
{
   final Date dateToConvert
      = Objects.requireNonNullElse(inputDate, new Date());
   return dateToConvert.toInstant();
}

In the above example, if the provided variable of type Date is null, a provided default of "now" (based on calling the Date constructor that doesn't accept arguments) is returned instead.

JDK 9 also added the method Objects.requireNonNullElseGet​(T,Supplier<? extends T>) for a similar purpose. This method differs from the previously discussed method in that it accepts a Supplier for providing the default value rather than accepting another object of the same type to serve as the default.

In the highly recommended book Modern Java Recipes, Ken Kousen writes, "One of the primary use cases for Suppliers is to support the concept of deferred execution." After discussing how Supplier is used in the JDK, he adds, "This process of deferred execution can be used in your own code, to ensure that a value is retrieved from the Supplier only when appropriate." My next example demonstrates this.

A highly contrived code listing is shown next and demonstrates use of this method accepting a Supplier.

Example of Objects.requireNonNullElseGet​(T,Supplier<? extends T>)

/**
 * Provide instance of {@code Instant} that corresponds to
 * the provided instance of {@code Date}.
 *
 * @param inputDate Instance of {@code Date} for which
 *    corresponding instance of {@code Instant} is desired;
 *    if this is {@code null}, an {@code Instant} based on
 *    a complicated date calculation will be returned.
 * @return Instance of {@code Instant} extracted from provided
 *    {@Date} that will instead represent a calculated date if
 *    provided {@code Date} is {@code null}.
 */
public Instant convertDateToInstantWithCalculatedDefault(final Date inputDate)
{
   final Date dateToConvert
      = Objects.requireNonNullElseGet(inputDate, () -> calculateDate());
   return dateToConvert.toInstant();
}

The version of the method accepting a Supplier may be advantageous when the code for determining the default is expected to be long-running. In such cases, that long-running method is only executed if the first passed-in argument is null. When the first passed-in argument is not null, the long-running method is not invoked. [By the way, I don't show the implementation of calculateDate() here because it's ridiculously contrived, but suffice it to say that it intentionally takes a very long time to execute.]

The two methods covered in this post make it easy to detect if a particular variable is null and to provide a suitable replacement in its stead when it is null. These are likely to be most often used to implement "guard clauses," but their ability to return a default value could lead to additional use cases as well.

Saturday, February 3, 2018

An Early Look at Features Targeted for Java 11

With JDK 10 about to enter its release candidate phase, it's interesting to start looking at what will come after that via JDK 11. As of this writing, four JEPs (JDK Enhancement Proposals) have been officially targeted for JDK 11 (with more likely to come). This post summarizes some details about each of the four JEPs currently targeted for JDK 11.

JEP 309: Dynamic Class-File Constants

JEP 309 ("Dynamic Class-File Constants") "seek[s] to reduce the cost and disruption of creating new forms of materializable class-file constants, which in turn offers language designers and compiler implementors broader options for expressivity and performance." JDK bug JDK-8189199 ("Minimal ConstantDynamic support") "implement[s] JEP 309 by properly parsing and resolving new CONSTANT_Dynamic constants in JVM class files used by Hotspot" and was resolved four days ago. JEP 309 was officially targeted for JDK 11 on 14 December 2017.

JEP 318: Epsilon: An Arbitrarily Low-Overhead Garbage Collector

The currently stated goal ofJEP 318 ("Epsilon: An Arbitrarily Low-Overhead Garbage Collector") is to "provide a completely passive GC implementation with a bounded allocation limit and the lowest latency overhead possible, at the expense of memory footprint and memory throughput." The JEP's summary currently states, "Develop a GC that handles memory allocation but does not implement any actual memory reclamation mechanism. Once the available Java heap is exhausted, the JVM will shut down." JEP 318 is associated with issue JDK-8174901 ("JEP 318: Epsilon: An Arbitrarily Low-Overhead Garbage Collector") and was officially targeted for JDK 11 on 18 January 2018. Additional details regarding JEP 318 can be found in online resources such as The Last Frontier in Java Performance: Remove the Garbage Collector and Java garbage collector proposal aimed at performance testing.

JEP 320: Remove the Java EE and CORBA Modules

JEP 320 ("Remove the Java EE and CORBA Modules") has a current "Summary" stating, "Remove the Java EE and CORBA modules from the Java SE Platform and the JDK. These modules were deprecated in Java SE 9 with the declared intent to remove them in a future release." This JEP is not terribly surprising given that CORBA and Java EE modules did not have default visibility in Java SE when JDK 9 introduced modularity. The "Motivation" section of this JEP provides insightful historical background on why Java EE and CORBA modules were included in Java SE in the first place. Among many other interesting tidbits in this "Motivation" section, these two conclusions stand out to me:

  • "Since standalone versions of the Java EE technologies are readily available from third-party sites, such as Maven Central, there is no need for the Java SE Platform or the JDK to include them."
  • "Since the costs of maintaining CORBA support outweigh the benefits, there is no case for the Java SE Platform or the JDK to include it."

JEP 320 lists several modules and tools that it will remove. The to-be-removed modules include java.xml.ws, java.xml.ws.annotation, jdk.xml.ws, java.xml.bind, jdk.xml.bind. The to-be-removed tools include wsgen, wsimport, schemagen, xjc, and servertool.

The JEP 320 "Risks and Assumptions" section illustrates the impact of these removals. It states that developers using --add-modules java.xml.bind currently to include JAXB classes in their Java 9 applications will need to change this for JDK 11. Specifically, the JEP text states, "This proposal assumes that developers who wish to compile or run applications on the latest JDK can find and deploy alternate versions of the Java EE technologies." Fortunately, the text in JEP 320 does a nice job of providing details on current alternate implementations of many of the libraries and tools that will be removed with JDK 11 and JEP 320.

JEP 320 also mentions that most modules it will be removing are "upgradeable," meaning that "developers on JDK 9 who use --add-modules java.xml.bind, etc. have the choice of either relying on the Java EE modules in the JDK runtime image, or overriding them by deploying API JAR files on the upgrade module path." The JEP further explains why this is significant in terms of making it easier to move to JDK 11 when the modules are removed from the JDK runtime image.

JEP 320 is associated with issue JDK-8189188 ("JEP 320: Remove the Java EE and CORBA Modules") and was officially targeted for JDK 11 on 26 January 2018.

JEP 323: Local-Variable Syntax for Lambda Parameters

JEP 323 ("Local-Variable Syntax for Lambda Parameters") is intended to "allow var to be used when declaring the formal parameters of implicitly typed lambda expressions."

JEP 323 is associated with issue JDK-8193259 ("JEP 323: Local-Variable Syntax for Lambda Parameters") and was officially targeted for JDK 11 yesterday (2 February 2018).

Conclusion

I mostly like to look forward to what's coming soon to a JDK near me because I find it interesting to think about. However, there are also practical advantages in some cases to knowing what's coming. For example, JEP 320 provides details regarding alternatives to the modules and tools that will be removed in JDK 11. Developers can start moving to those alternatives now or before migrating to JDK 11 to make that future transition easier.

Dreamix's Java Daily: Aggregation of Fresh Java Online Content

Roughly 18 months ago, I listed three blogs that regularly (daily or weekly) posted links to (and sometimes summaries of) new Java-related blog posts and articles. These blogs were listed under the "Other Resources" section at the bottom of my post "Recent Java News - Early June 2016". Two of those three featured blogs would stop posting those daily/weekly posts with links and summaries by the end of that same year (2016). In this post, I introduce a blog that has come to my attention since then and that I frequently reference when I wish to quickly determine what are the most interesting things going on in the Java online community.

One of the blogs that I featured in my post "Recent Java News - Early June 2016" was Robert Diana's "Geek Reading" series. That series ended approximately one month after my post, but had posted 1150 messages with the "Geek Reading" tag by that time. The reasons for the discontinuation of that series are articulated in the post "Geek Reading July 17, 2016 #1150".

Thorben Janssen's Java Weekly was on my original list, but Janssen concluded (at least temporarily) that series in late 2016 for reasons explained in the post "The end of Java Weekly ... for now." However, Janssen continues to help identify relevant and interesting online resources related to Java via tweets (his Twitter handle is @thjanssen123). It is also important to note that Janssen continues to post original content on his blog.

Of the three blogs that I specifically cited in June 2016 for their links and summaries of fresh Java online content, only the Baeldung Java Web Weekly posts have continued and I still find many good sources of Java-related news from these posts.

The Dreamix blog posts a series called "Java Daily" that provides links to a small number of interesting Java-related blog posts and articles each "working day." These links tend to be to online resources published since the last "Java Daily" blog post. These posts are simple and are typically composed of fewer than ten references with titles and links to the online content. There is typically little or no description beyond what the referenced work's title conveys. I find that the simplicity of these posts and small number of referenced resources allow me to very quickly identify new Java-related posts of interest.

Stoyan Mitov recently posted "Lessons Learned from Publishing the Java Daily during the Entire 2017," in which he writes about "lessons learned from publishing the Java Daily (almost) every working day throughout 2017." He calls this effort "an eye opening experience in the Java world" and outlines eleven "lessons learned from publishing more than 250 Java Dailies in 2017."

Mitov's Java Daily lessons learned post includes a lengthy list of "people one should follow on twitter to stay up to date" with links to the Twitter handle for each of these people. Mitov also references some of my favorite social media sites including DZone, Java Code Geeks, and Baeldung's Best Java Blogs. The post offers approaches to finding new Java sources and this reminds one of the effort that is involved in creating a daily post such as "Java Daily."

In "Lessons Learned from Publishing the Java Daily during the Entire 2017," Mitov makes an observation that I think developers may not fully appreciate until they write a blog of their own: "It's hard to keep up and support a good Java blog." I have seen many of promising blogs that I enjoy come to an end, some of them after a relatively small number of posts. An example of this is the aforementioned Geek Reading. Mitov also observes, "There aren’t so many news on Java on a daily basis. There are many blogs in the form of tutorials – mainly on the basics."

One of the advantages of working with a popular programming language such as Java is access to the thinking of the large community using that language. There is a wealth of online information on Java, but the downside is that it can be difficult to identify the freshest and most interesting new Java-related online resources. Software development social media sites such as DZone and Java Code Geeks help tremendously in this regard, but I have found that these simple recurring blog posts such as those provided by Baeldung's Java Web Weekly, and now by Dreamix's Java Daily, sometimes provide a different perspective on what's interesting that complements those social media sites well.

Thursday, February 1, 2018

JDK 10 Release Candidate Phase

Mark Reinhold's mailing list message "JDK 10 Release Candidate Phase: Process proposal" was posted today and opens with the sentence, "Per the JDK 10 schedule, we'll enter the Release Candidate Phase next week, on Thursday, 8 February." Reinhold proposes that the JDK 10 Release Candidate Phase be enacted in the same manner as the JDK 9 Release Candidate Phase and he provides a link to the (proposed) "JDK 10 Release-Candidate Phase" page. That page outlines the proposed processes associated with the JDK 10 Release Candidate Phase with specific focus on the level of bug fixes targeted for JDK 10. The bugs are categorized as P1 through P5 and once the JDK 10 Release Candidate Phase is entered, "all P2-P5 bugs must be left to future releases" and the focus will be on fixing "all P1 bugs that are new in JDK 10 and critical to the success of the release."

At the time of this writing, the following twelve features are targeted for JDK 10 as we're about to enter the Release Candidate Phase:

Additional References