Saturday, April 21, 2018

Recent Java Developments - Late April 2018

There have been several recent developments in the Java-sphere this week and I summarize some of them in this post.

The End of JavaOne as We Know It

In the post "JavaOne Event Expands with More Tracks, Languages and Communities – and New Name," Stephen Chin writes, "The JavaOne conference is expanding to create a new, bigger event that’s inclusive to more languages, technologies and developer communities." He adds that it has been renamed to "Oracle Code One" and that this year's edition (the "inaugural year of Oracle Code One") will be held in San Francisco's Moscone West in late October (October 22-25, 2018).

GraalVM: "Run Programs Faster Anywhere"

In the 17 April 2018 post "Announcing GraalVM: Run Programs Faster Anywhere," Thomas Wuerthinger and the GraalVM Team "present the first production-ready release" of "a universal virtual machine designed for a polyglot world" called GraalVM 1.0. GraalVM Community Edition (CE) is open source and is hosted on GitHub. The main GraalVM page describes it as "a universal virtual machine for running applications written in JavaScript, Python 3, Ruby, R, JVM-based languages like Java, Scala, Kotlin, and LLVM-based languages such as C and C++."

JavaScript and the JVM-based languages are recommended for production use of GraalVM 1.0 with improved support advertised for other languages in the near future. The GraalVM Downloads page provides for downloads of either the Community Edition (from GitHub) or the Enterprise Edition (EE, from Oracle Technology Network).

Mission Control Project in OpenJDK

Marcus Hirt has proposed "the creation of the Mission Control Project" on the OpenJDK announce mailing list. This seems like a logical step in the effort discussed in Mark Reinhold's message "Accelerating the JDK release cadence" to "open-source the commercial features in order to make the OpenJDK builds more attractive to developers and to reduce the differences between those builds and the Oracle JDK" with the "ultimate goal" of making "OpenJDK and Oracle JDK builds completely interchangeable."

Flight Recorder in OpenJDK

Speaking of commercial features of the Oracle JDK being brought into the OpenJDK, JEP 328 ("Flight Recorder") had some interesting news this month with Markus Gronlund's hotspot-dev mailing list announcement of the availability of "a preview of a large part of the source code for JEP 328 : Flight Recorder."

JEP 321: HTTP Client (Standard) Targeted for JDK 11

As announced late last month, JEP 321 ["HTTP Client (Standard)"] has been targeted for JDK 11.

Significant Progress on Switch Expressions (and Improving Switch Statements)

There has been significant progress in the OpenJDK mailing lists' high-level design of switch expressions that includes enhancements to the existing switch statements since my original post on switch expressions. I have summarized some of the latest discussion (particularly that in a Brian Goetz post) in a recent blog post called "Enhancing Java switch Statement with Introduction of switch Expression."

Should I Return A Collection or Stream?

There's an interesting thread "Should I return a Collection or a Stream?" on the Java sub-reddit that is based on an interesting July 2017 discussion on StackOverflow related to whether it's most appropriate to return a Collection or a Stream in a particular case.

Friday, April 20, 2018

Enhancing Java switch Statement with Introduction of switch Expression

In late December of last year, I posted "Switch Expressions Coming to Java?" Since then, there has been significant discussion, expressed differences of opinion, and now a coalescence of general agreement regarding the future of switch expressions in Java. I have tried to capture some of the major developments related to switch expressions as comments on my December blog post. However, I felt like this week's Brian Goetz message title "[switch] Further unification on switch" on the amber-spec-observers mailing list warranted a new blog post on Java switch expressions.

Goetz opens his message with a reminder that the end game is not Java switch expressions. Instead, Goetz points out that "switch expressions are supposed to just be an uncontroversial waypoint on the way to the real goal, which is a more expressive and flexible switch construct that works in a wider variety of situations, including supporting patterns, being less hostile to null, use as either an expression or a statement, etc."

Goetz also points out that "switch does come with a lot of baggage" and he points out that "this baggage has produced the predictable distractions in the discussion." Goetz states that "the worst possible outcome ... would be to invent a new construct that is similar to, but not quite the same as switch ... without being a 100% replacement for today's quirky switch." Given that concern, the original proposed switch expression syntax is being discarded because it was leading the discussion toward this "worst possible outcome."

The new switch unification proposal (dubbed "Unification Attempt #2" [UA2]) proposes that "that _all_ switches can support either old-style (colon) or new-style (arrow) case labels -- but must stick to one kind of case label in a given switch." This means that a given switch's case labels all must use either the "colon" syntax we're used to today with switch statements or used the new proposed "arrow" syntax, but cannot use both within the same switch.

There are reasons a developer might choose one form over the other ("colon" versus "arrow"). Goetz highlights some advantages of the "arrow" syntax associated with switch's current proposal: "in the all-arrow form, all of the things people hate about switch -- the need to say break, the risk of fallthrough, and the questionable scoping -- all go away."

Goetz, in text, presents how the "structural properties" of the various "switch forms" drive "control flow and scoping rules." This is shown in the following table.

  STATEMENT
("Nonlocal control flow _out_ of a switch [continue to an enclosing loop, break with label, return]")
EXPRESSION
(Totality: return a value)
COLON
(Enables Fall-through)
switch we know and "love", but enhanced break returns a value like return
ARROW
(Prevents Fall-through)
"Syntactic shorthand" for Statement/Colon (above) plus
  • "obviates the annoyance of 'break'"
  • "implicitly prevents fallthrough of all forms"
  • "avoids the confusion of current switch scoping"
Arrow (->) points to returned value

Goetz summarizes what the above table shows with the statement "the colon form gives you the old control flow and the arrow form gives you the new. And either can be used as a statement, or an expression. And no one will be confused by mixing." He also specifically describes the structure in the lower left corner of the table above (switch statement with "arrow" syntax): "Switch statements now come in a simpler (arrow) flavor, where there is no fallthrough, no weird scoping, and no need to say break most of the time. Many switches can be rewritten this way, and this form can even be taught first."

Goetz concludes his post with this promising summary:

The result is one switch construct, with modern and legacy flavors, which supports either expressions or statements. You can immediately look at the middle of a switch and tell (by arrow vs colon) whether it has the legacy control flow or not.

The overall response so far to the proposed "Unification Attempt #2" so far has been overwhelming positive, but not without the expected lingering concerns. Gavin Bierman summarizes this proposal by saying "it's really all about enhancement as opposed to a new construct" and states, "Writing revised spec as we speak - be ready!"

Monday, April 16, 2018

Java-Related April Fools Day Pranks

Although you'd never catch me stooping to this level, it has been interesting over the years to see some of the effort and thought put into Java-related April Fools' Day pranks. This post references and summarizes some of them.

Google Annotations Gallery (gag)

The Google Annotations Gallery (cleverly abbreviated as 'gag') is hosted on Google Code, so you may want to download that as soon as possible so that you do not miss out on it. Both gag-1.0.zip (original release) and gag-1.0.1.zip (supplements original release to "add many great user-suggested annotations"). These ZIP files include actual Java source code with the libraries that gag depends on.

Some of my favorite annotations provided by gag are @AhaMoment, @Blame, @BossMadeMeDoIt, @Facepalm, @Hack, @HandsOff, @IAmAwesome, @LegacySucks, @Magic, @Noop, and @OhNoYouDidnt.

I also enjoy the WHERE enumeration provided by 'gag' to allow one to specify "where" a particular annotation's meaning may have occurred. Values for WHERE cover the most likely locations to think up the best ideas (most "free time"): BATH, BED, BORING_MEETING, DMV, GYM_WORKOUT, SHOWER, TOILET, and TRAFFIC_JAM.

I was negligent in not mentioning the 'gag' library in my recent post on how to effectively divert blame.

New OpenJDK Project: Even Faster JDK Releases

This year (2018), the discuss OpenJDK mailing list includes a couple threads with April Fools' Day hoaxes. One of these, "New project proposal: even faster JDK releases," is particularly timely given the relatively recent change to a new Java release every six months. The new cadence has caused some concerns such as those described in "The Java release train is moving faster, but will developers be derailed?"

The April 1 proposal proposes "the creation of project Doomed, which aims to solve an extremely important issue caused by the currently specified fast release schedule, that of an equally fast adoption." Before making several other arguments for Project Doomed, the proposal states, "With project Doomed we aim at continuous release and deployment of the JDK, thus removing the need to have any version number and increase the adoption rate considerably and better position the JDK in the fast pacing world of cloud development."

New OpenJDK Project: The Block GC

Another April 1 thread on the discuss OpenJDK mailing list starts with the post "New Project Proposal: The Block GC." The proposal here is for "Block Chain GC", "an innovative new system for Garbage Collection." Among other advertised virtues of the Block Chain garbage collector is the ability for it to be "used to calculate hash values for popular cryptocurrencies, a.k.a. 'bitcoin mining'". The proposal also outlines where the default recipients of the revenues generated from the Block Chain garbage collector: "by default, the revenue extracted by the Block GC miner will be stored in the Block GC Project account. This revenue will be divided as follows: 90% will go to the initial committers of the Block GC Project, and 10% will go to the OpenJDK community."

Apache Software Foundation Sold to Oracle

The 2010 April Fools post "The Apache Software Foundation Receives Approval for Sale to Oracle Corporation" announced "Today, the Apache Software Foundation announced it has agreed to sell all IP and assets of the foundation to Oracle."

Frostbyte

ZeroTurnaround announced Frostbyte on April Fools Day in 2012 and advertised it as "a new stack-based language for the JVM" that was "born out of frustration of working with the standard Java software stack and tools." Among Frostbyte's advertised features were "use of inverse reverse Polish notation with parentheses" and "the built-in default language is Estonian." Perhaps the most promising feature of Frostbyte was "built-in AI that is able to make aesthetic judgments about your code and will outright disallow ugly code, over-abstractions and excessive copy-and-pasting."

Goto in Java

Another 2010 April Fools Day announcement was Joe Darcy's "Goto for the Java Programming Language." "Endorsed" by "Edsger Dijkstra" (author of "go to statement considered harmful"), this proposal advertises that it will "Provide the benefits of the time-testing goto control structure to Java programs." Fortunately, Java still doesn't have that form of a "goto," but it does have its own narrowly-scoped similar capability.

Neo 4 Java

On April Fools' Day 2016, the Neo4j blog announced Neo 4 Java, "a proprietary 100% pure Arabica available in the caffeine aisle soon, or possibly right at your desk if you happen to have a 3D printer or a really good intern."

Micecraft Java Edition Textures Finally Perfected

In "Java Edition Textures Finally Perfected," it was announced of April Fools Day this year that "a new default texture pack for the Java Edition of Minecraft" was being released. Not everyone thought this was funny because it apparently cost some Minecraft users quite a bit of time before they realized it was a one-day prank. A Minecraft bug, MC-127786, was reported with this moderator response, "April fools! This is an April Fools' joke by Mojang. Textures will return back to normal once April Fools' Day is over." Minecraft users should probably be especially wary of April Fools Day pranks because it's not the first time that Mojang has pulled one.

Conclusion

Several of the April Fools' Day posts described above required a surprising amount of ingenuity, effort, and time.

Saturday, April 14, 2018

JDK 11 Early Access Build 8

In the message "JDK 11 Early Access build 8 available," Muneer Kolarkunnu announces that "JDK 11 EA build 8, under both the GPL and Oracle EA licenses, is now available at http://jdk.java.net/11." Kolarkunnu specifically highlights Build 8's changes to the Selector API that have been discussed on the nio-dev mailing list in threads such as Callback Based Selectors and More Selector Cleanup.

The JDK 11 EA Build 8 announcement also mentions that "VM option '-XX:+AggressiveOpts' is deprecated in JDK 11 and will be removed in a future release" as of Build 7. The announcement highlights JDK-8193033 ("Release Note: remove terminally deprecated sun.misc.Unsafe.defineClass") in Build 6 and reminds that "users should use the public replacement 'java.lang.invoke.MethodHandles.Lookup.defineClass' which was added in Java SE 9."

The "JDK 11 Early-Access Builds" page referenced in the announcement provides links to Release Notes, OpenJDK 11 Early Access Build Test Results, JDK 11 Javadoc API, and links for downloads of the OpenJDK 11 "early-access, open-source" OpenJDK 11 builds and the Oracle JDK Builds. An interesting note on that page states, "Oracle will no longer offer a stand-alone JRE for desktops. Starting with JDK 11 Oracle will only produce a JDK and a Server JRE."

Optional.isEmpty() Coming to Java?

JDK-8184693 requests that the method isEmpty() be added to the Optional class introduced with JDK 8. Invoking Optional.isEmpty() would be the equivalent of invoking !Optional.isPresent(). There is no JDK release currently associated with JDK-8184693, but it is being actively worked as demonstrated in a recent core-libs-dev mailing list post titled "RFR: 8184693: (opt) add Optional.isEmpty".

Written by Stuart Marks in July 2017, JDK-8184693 provides some interesting justification for the addition of Optional.isEmpty(). Marks points out that "generally we avoid adding methods that are simple inverses of each other" and cites as examples presence of String.isEmpty() and Collection.isEmpty() without any accompanying String.notEmpty() or Collection.nonEmpty() counterparts. Marks writes this approach works well in these cases because "emptiness/non-emptiness isn't fundamental" for them: "For these objects, it's perfectly reasonable to operate on an empty String (e.g., searching or appending it) or collection (e.g., iterating over it)."

In JDK-8184693, Marks writes of examples that do have methods to explicitly express both emptiness and non-emptiness. He writes, "However, with references, null/non-null is pretty fundamental, we have Objects.isNull and Objects.nonNull." Because these examples' usages are more like Optional's usages, Marks argues that Optional should have an isEmpty() method alongside its current isPresent() method: "Similarly with Optional, the empty/present dichotomy is quite fundamental, so there should be isEmpty alongside of isPresent."

Most of the justification text in JDK-8184693 was added this month (April 2018) and includes a link to the April 2017 core-lib-devs mailing list post "Optional.isEmpty()" by Peter Levart. The bug write-up summarizes some of the discussion started by this post. Messages in that thread include those that provide humor, reference bikeshedding, list "plenty of one-liners that don't use boolean negation," recommend name isNotPresent() or isAbsent(), provide enthusiastic support of the idea of Optional.isEmpty(), and remind that "the bar for adding methods to Optional is set very high."

The previously mentioned mailing list message "RFR: 8184693: (opt) add Optional.isEmpty" references code available for review. The "Sdiff" of Optional.java for this proposed change shows that this method has been implemented. However, a similar change still needs to be made for OptionalDouble, OptionalLong, and OptionalInt.

As I've used Optional in my Java code, I've come to appreciate times when I don't need to use Optional.isPresent(). However, there are times when there's no good way around it and I look forward to the addition of Optional.isEmpty() to replace the use of !Optional.isPresent(). The addition of Optional.isEmpty() is a minor thing, but I believe it will make my code more readable and more fluent. I look forward to it coming soon to a JDK near me.

Thursday, April 12, 2018

Updates on Records (Data Classes for Java)

There have been several updates related to "Java Data Classes" (AKA "Records") in recent months. As I briefly mentioned in the post "Updates on JavaFX, Valhalla, Data Classes, and Java's Floating-Point," Brian Goetz's "Data Classes for Java" "explores possible directions for data classes in the Java Language." Sadly, despite significant discussion on this potential new Java feature on the OpenJDK mailing lists, this document also points out, "This is an exploratory document only and does not constitute a plan for any specific feature in any specific version of the Java Language."

In mid-March, Goetz posted a message to the amber-spec-experts mailing list titled "Records -- current status." He states the intent of records in Java in that message: "Our goal all along has been to define records as being 'just macros' for a finer-grained set of features. Some of these are motivated by boilerplate; some are motivated by semantics (coupling semantics of API elements to state.) In general, records will get there first, and then ordinary classes will get the more general feature."

There are several interesting points made in the "Records -- current status" post, but I'll focus on a few here that I found particularly interesting. In general, one can see in the stated early design decisions that general principles that are now more popular than perhaps they were when Java was created dominate the thinking related to records.

Under the section "Mutability and accessibility," Goetz proposes that Java records provide final fields that are "package (protected for abstract records) by default," but which would allow the developer to "explicitly opt out of (non-final)" as well as allow accessibility to be "be explicitly widened (public)." I love the idea of a Java construct having final fields by default and having to explicitly choose to make them non-final rather than the other way around that we've become used to in Java.

In the "Accessors" section, Goetz writes that the current thought is to have these accessor methods NOT use the JavaBeans convention of "get" and instead use the field's name without "get" prefix. He writes, "The obvious choice is to expose read accessors automatically. (These will not be named getXxx; we are not burning the ill-advised Javabean naming conventions into the language, no matter how much people think it already is.) The obvious naming choice for these accessors is fieldName()." I like the idea of automatically generated read accessors following this simple naming convention (which I tend to use when I write builders). I also appreciated the emphasized reassurance that there is no conspiracy or effort to "burn the ill-advised JavaBean naming convention into the language."

Goetz's "Core methods" section talks about common methods such as equals(Object), hashCode(), toString(), and so forth. Goetz writes that "Records will get equals, hashCode, and toString" and that "there's a good argument for making equals/hashCode final." He adds that while there's no need to make toString() a final method, the automatically generated read accessor methods could be made final.

Stephen Colebourne has contributed multiple posts to the mailing list discussion regarding records/data classes in Java. These include his insights from presenting on Amber (the project housing this effort along with other efforts such as LVTI and raw string literals) and a response to the previously mentioned original "Records -- current status" message.

Other relatively recent mailing list messages regarding records in Java include Goetz's "Records: construction and validation," a discussion started by Remi Forax on "Record and annotation values," and a thread started by Gunnar Morling called "Records -- Using them as JPA entities and validating them with Bean Validation."

Although Records/Data Classes are not yet associated with any particular Java release, it's exciting to think about the possibilities they might bring to enable better, safer, and more readable Java code.

Monday, April 9, 2018

Clearer Code with JDK 10 Local Variable Type Inference

One of the first fruits of Project Amber, Local-Variable Type Inference (JEP 286), has been delivered with JDK 10. JEP 286's "Summary" describes its purpose, "Enhance the Java Language to extend type inference to declarations of local variables with initializers." In conjunction with this release, Stuart Marks has published the March 2018 article "Style Guidelines for Local Variable Type Inference in Java."

In "Style Guidelines for Local Variable Type Inference in Java," Marks postulates four "Principles" that lead to seven "Guidelines" that help developers to apply var properly to "help improve good code, making it shorter and clearer without compromising understandability." The articulated guidelines attempt to strike a balance that brings benefits of less redundant code with the benefits of explicitly readable code. The article outlines cases where var should be used and where it shouldn't be used. In general var is best used when other naming conventions or other constructs in use provide significant detail about the local variable type that is only repeated with the explicit typing. On the other hand, there are cases where much information is lost if the explicit type is removed and in such cases, use of var is discouraged. Another typical case where use of local variable type inference might be preferred is when the explicit typing is difficult to read and is only used in an intermediate step. It may not be important to see the complex explicit type for that intermediate step.

I couldn't help but think about my earliest days working with Groovy while reading the document "Style Guidelines for Local Variable Type Inference in Java." Most of the literature I read sang the virtues of using Groovy's def keyword wherever possible to conserve keystrokes and make the Groovy code more concise. In an effort to appear to "speak Groovy" fluently, I embraced what I deemed to be "idiomatic Groovy." However, after several months of this, I realized that some uses of the def keyword significantly reduced the readability of my Groovy code when I returned to it months after writing it. I began to use personal guidelines similar to those espoused by Marks with Java's LVTI with my Groovy code.

I wasn't the only one who learned that mindless application of Groovy's handy def keyword could actually lead to less maintainable Groovy code. Benefits that can be gained from explicit typing in Groovy are discussed in the StackOverflow thread "Groovy: 'def' keyword vs concrete type." The book Programming Grails has a section called "'def' Considered Harmful" in its first chapter and Rob Hinds's post "Groovy: A Retrospective" states, "... typing is better - I still don't buy that typing def rather than the actual type is actually that much of a saving." The "official" Groovy Style Guide features a section "Optional typing advice" that talks about whether or not to use def. However, for the similar case to which Java LVTI applies (local variables), the advice is, "you're more free to decide when to type or not."

Like so many other Java APIs and language constructs, the best Java code will not be written to always use LVTI or to never use LVTI. Instead, as is so often the case in software development, the decision on whether to use LVTI or not to use LVTI depends on the context in which it would potentially be used. Reviewing the "Style Guidelines for Local Variable Type Inference in Java" document and trying out LVTI and reviewing others' code using LVTI are the best ways to build an intuitive sense for when to apply LVTI and when not to. The amber-dev mailing list thread starting with the message "LVTI Style Guide" provides significant more discussion surrounding this document on when to use and not use Java's Local Variable Type Inference. The blog post "Representing the Impractical and Impossible with JDK 10 'var'" demonstrates how to "declare variables with types that were erstwhile impractical or impossible to represent" using Local Variable Type Inference.