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.

Sunday, April 1, 2018

Diverting Blame Effectively in Software Development

I previously blogged on how to effectively sweep problems under the rug in Java, but even with the tactics discussed in that post, it's not always possible to hide every problem encountered when developing software. In this post, I look at tactics software developers can use to avoid direct blame for problems and issues that cannot be hidden or easily fixed.

Dealing with Version Control Tools

Version control (AKA source control) offers several advantages, but can also be one of the easiest ways for others to know when you've introduced a particular bug or issue. One option that seems to not be used much anymore is to avoid version control systems altogether. Without version control, it isn't as easy for someone else to find out who delivered a particular line or lines of code.

Even with some sort of version control in place, there are tactics to reduce the ability of others to see when you've introduced a bad piece of code or made a change with negative repercussions. One tactic is to convince a fellow developer to merge your changeset for you. Depending on the version control system you're using, this is accomplished in different ways, but at a high-level typically involves you supplying a patch of your changes and asking the fellow develop to merge that patch's changes into the main development branch.

Because it's often not easy to get someone else to merge for you or to otherwise prevent the version control system from showing you as the responsible individual for code changes, an easier tactic is to put things in the version control commit or merge comments that deflect blame. These comments might ascribe the change to someone else. The comment could say something about merging someone else's changes for them or that the changes were someone else's idea and imply that you merely made the requested changes for them.

The problem with referencing other developers in version control delivery comments is that, in many version control systems, these developers will see the delivery comments as the deliveries are being made. In such cases, it's often better, if possible with your version control system's configuration, to change the comment AFTER the delivery has been made and AFTER any automatic notices of the delivery have been issued.

In-code Comments

In-code comments can be a great way to divert blame. A well-written comment can be convincing and might even preclude a fellow developer from bothering to use the version control system history to see who made a change if that developer sees an in-code comment explaining the change or addition. These in-code comments might state things like, "This was Frank's idea" or "Change made at Anna's request." If mentioning specific names is too risky, the comments can be more vague as to whose ideas are implemented ("I was directed to do this because ...").

A specialized form of an in-code command that can be particularly useful in deflecting blame is the infamous "TODO" comment. This "TODO" comment can be used to make your problem someone else's future problem. This approach is particularly effective if the current problem is described in this comment in such a way that it seems impossible to address it now and so it must be addressed at some point in the future. One might even go further and pretend it's someone else's "TODO" by placing the other person's initials in the comment or referencing the other individual. There might even be an implication that the other individual will be or should be the one to resolve the issue.

Apply Logical Fallacies

There are numerous logical fallacies that can be applied in response to others' critical code reviews or other mentions of problems with your code. One that can be effective is an "appeal to ridicule" in which you make it obvious that you won't waste time on such an absurd argument; this works best when you are the more experienced developer or are in a higher or more powerful position. Sometimes, to pull this off, you might need to imply that the other person will some day understand.

The "false authority" logical fallacy is also effective; with this one, you just need to find one person who makes an argument for doing something the way you did it and then cite that is THE authority. You want the person writing this to seem as credible as possible for this to work well. Alternatively, one could use "false attribution" to quote someone well-credentialed authority in favor of one's position without actually citing the source (because there isn't any).

One particularly effective approach can be to respond to critiques with comments quoted by authorities out of context. One of the most obvious here is to defend one's poor code choices with the argument that one was simply avoiding premature optimization.

Muddy the Waters

There are several tactics one can use to "muddy the waters" to make it difficult to ascertain who did what when. Some examples include mixing substantial changes with refactorings and cosmetic changes in single change sets, breaking an otherwise cohesive set of changes into multiple merges over time to make it difficult to see when the issue was introduced, making changes in files with lots of changes so that others' merges show up over your own merges, etc.

Write Unit Tests that "Prove" Your Code Works

Unit tests can be very useful for a variety of reasons, but they can also be the first to expose your issues. Fortunately, you can make unit tests work for you when covering up your issues by writing tests that assert your incorrect code is fine. Then, when someone finds an issue with your code, you can blame the unit test for being at fault.

Blame External Forces

When it's not possible or ill advised to blame another developer, blaming inanimate items that won't attempt to defend themselves can be effective. This approach is most effective when the blame is directed at items that are already viewed with disdain by those around you and include things such as tools (IDE, version control, static analysis tools, unit test frameworks, etc.), schedules (including deadlines), libraries and APIs, existing code, the environment ("it worked on my machine"), etc.

Management and/or customers can often be blamed to at least partially deflect attention. Being outraged at the ridiculous requests or unrealistic requests of clients and/or management can lead to empathy and agreement from fellow developers.

Divert Blame to Code Reviewers and/or Test Organization

When all else fails, blame can be diverted to code reviewers. When problems are found during a code review, you can state that you placed them there intentionally to test the quality of the reviews and see if anyone was actually reviewing. When issues are found after the code reviews, you can blame the reviewers for not finding the issues during their review. If you have a separate test organization, the same tactics can be applied; you can say your problem was intentionally added to verify the testers were doing their job if found by Test or can blame Test for not finding the issues if they arise after testing.

Conclusion

This post has quickly looked at some of the tactics that a software developer may find useful when diverting blame.

By the way, Happy April Fools Day!

Saturday, March 24, 2018

Forward-Looking with Java's @Deprecated

I have occasionally run into a situation in which I have needed to introduce a new API or construct for others to try out, but have known that it might change based on others' feedback after some use of it. In such cases, I've wanted to somehow annotate the construct to warn other developers of the tentativeness of this newly added construct. There are several alternatives that I have considered in these cases.

Third-party Annotation

The Javadoc documentation for Guava's @Beta annotation states:

Signifies that a public API (public class, method or field) is subject to incompatible changes, or even removal, in a future release. An API bearing this annotation is exempt from any compatibility guarantees made by its containing library. Note that the presence of this annotation implies nothing about the quality or performance of the API in question, only the fact that it is not "API-frozen."

This explanation of the use of @Beta seems to imply this is a good fit for a "new" construct that may be removed. I talked more about this annotation in the blog post "Two Generally Useful Guava Annotations".

Other considerations when using a third-party library's annotation is that the third-party library must be included on one's classpath and that there is typically no out-of-the-box support in the most popular Java IDEs to indicate special treatment of the construct annotated with the annotation.

Custom Annotation

If one is not using the library with the annotation for any other reason, it can seem a bit heavy to add a new library dependency simply for an annotation when it's relatively straightforward to write one's own custom annotation. I have written about writing a custom @Unfinished annotation before and that post discussed how to create corresponding custom IDE inspections in NetBeans 8.0.2 and IntelliJ IDEA 14.0.3 for this custom annotation.

The following code listing provides an example of a custom annotation one could use for this purpose.

@Preview Annotation

package dustin.examples.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Preview
{
   /**
    * Anticipated release in which Preview status will no longer apply.
    *
    * @return Anticipated release of feature
    */
   String transition() default "";

   /**
    * Version in which this preview feature was introduced.
    *
    * @return Release in which this preview feature was introduced.
    */
   String since() default "";

   /**
    * Reasons this construct is considered "preview."
    *
    * @return Reasons this construct is considered preview.
    */
   String[] reasons() default {};
}

The custom annotation lacks any out-of-the-box support in the popular Java IDEs.

Comments Only

Annotations don't necessarily need to be used and simple comments (Javadoc or otherwise) could explain that a particular construct is preliminary and might go away. However, comments are weaker in many ways than annotations in terms of communicating intent. It is much more difficult to have an IDE or other tooling parse comments than to process annotations.

@Deprecated Annotation and @deprecated Javadoc Tag

One can use @Deprecated to annotate a deprecated construct with a standard annotation that IDEs, tools, and scripts can easily process. Unfortunately, the @Deprecated annotation never got the full support I had hoped it would get for more specifically specifying why something was deprecated when it was decided to make the JDK 9 enhanced @Deprecated much less ambitious. The Javadoc @deprecated tag can be used to document that the deprecation is actually for a "new" construct that might go away, but also might not go away. The @Deprecated annotation and the @deprecated Javadoc tag can be removed if it's decided to keep the "preview" construct.

Although the @Deprecated annotation and @deprecated Javadoc tag enjoy benefits from being standards that include built-in IDE support and awareness among most Java developers, it can still feel a bit inappropriate to use these to mark a new construct that may go away, but may stick around. The "When to Deprecate" section of the document "How and When To Deprecate APIs" states, "When you design an API, carefully consider whether it supersedes an old API." It further lists three reasons for deprecation which are "insecure, buggy, or highly inefficient", "going away in a future release", and "encourages bad coding practices".

I'm not the only one who thinks of "deprecation" as marking something likely to be removed or that should not be used. Nicolas Fränkel outlines the feature lifecycle in Java and explains that deprecation in Java is "a bold and clear statement to everyone that a feature version has no future, at least in its current form."

In the jdk-dev mailing list message "JEP 12: Treatment of standard APIs supporting preview features," Alex Buckley writes:

We'd like to use deprecation-for-removal-at-birth as the way to flag "this API is intimately connected to a preview feature". If the preview feature becomes permanent, then the deprecation would be removed. This jump from terminal-deprecation to no-deprecation is novel, but not mad -- deprecation has a variety of meanings, and its historical use in the JDK is not a good guide to anything.

Buckley also cites a paragraph from JEP 277 ("Enhanced Deprecation") regarding use of the deprecation mechanisms (I have highlighted the same portion Buckley emphasized):

Deprecation is a technique to communicate information about the life cycle of an API: to encourage applications to migrate away from the API, to discourage applications from forming new dependencies on the API, and to inform developers of the risks of continuing dependence upon the API.

The JDK 9-introduced "enhanced" @Deprecated annotation can help a bit in this situation (that Buckley termed "deprecation-for-removal-at-birth") via its newly added "since" and "forRemoval" elements. Specifying the @Deprecated annotation's forRemoval() as false and specifying its since as the same version as the Javadoc @since tag might help developers to see that the construct was deprecated from the beginning with no current plans to remove it. For such an approach to be most effective, it'd probably be write to explicitly state forRemoval as false rather than relying on its implicit default.

It may be that we Java developers will need to start thinking of @Deprecated and @deprecated a bit differently than in the past. Although the @Deprecated annotation and @deprecated Javadoc tag still "inform" us of "the risks of continuing dependency" upon the annotated/described construct, it may be incorrect to assume that such a construct is necessarily going away at some point in the future. If we get used to this alternate meaning in deprecated JDK constructs, we'll be more likely to consider using the same approach with our own newly added and still tentative features.

Saturday, March 17, 2018

Raw String Literals Coming to Java

It appears likely that "raw string literals" are coming to Java. JEP 326 ("Raw String Literals") started as Issue JDK-8196004 and was announced as a "new JEP candidate" on March 2. The JEP and associated issue point out that "Java remains one of a small group of contemporary programming languages that do not provide language-level support for raw strings." The JEP and associated issue specifically reference programming languages C, C++, C# ("verbatim"), Dart, Go, Groovy, Haskell, JavaScript, Kotlin, Perl, PHP, Python, R, Ruby, Scala and Swift and the "Unix tools" bash, grep, and sed that were "surveyed for their delimiters and use of raw and multi-line strings."

JEP 326's "Summary" provides an overview of the proposed Java raw string literals: "A raw string literal can span multiple lines of source code and does not interpret escape sequences, such as \n, or Unicode escapes, of the form \uXXXX." The "Motivations" section of this JEP adds, "This JEP proposes a new kind of literal, a raw string literal, which sets aside both Java escapes and Java line terminator specifications, to provide character sequences that under many circumstances are more readable and maintainable than the existing traditional string literal." JEP 326 does not introduce interpolation and, in fact, rules it out in its "Non-Goals" section: "Raw string literals do not directly support string interpolation. Interpolation may be considered in a future JEP."

Multi-line String literals have long been desired in Java. JEP 326 ("Raw String Literals") currently lists several examples of how raw string literals would make it easier to implement common things in Java and these example uses include multi-line strings, operating system file paths, regular expressions, relational database SQL statements, and polygot (Java+JavaScript).

The current version of JEP 326 states that Java's raw string literals will be denoted via the use of the "backtick" character (`), which is also described in the JEP as \u0060 (Unicode "Grave Accent"), "backquote", and "accent grave". I don't show any examples of the proposed syntax because the JEP already does a nice job of listing these proposed raw string literal examples alongside examples of traditional Java code needed to implement the same thing. This makes it easy to compare the required current syntax to what would be needed in the future to accomplish the same thing if raw string literals are supported.

Support for raw string literals in Java will provide nice convenience for Java developers wishing to write more readable code to support use cases like those described in the JEP. It will provide similar advantages to libraries and even to the JDK code. The core-lib-devs mailing list post "Raw String Literal Library Support" [JDK-8196005] starts a "discussion with regards to RSL library support." (The context of "library support" in this case is the JDK and RSL stands for Raw String Literal.).

In the referenced post Raw String Literal Library Support, Jim Laskey provides a list of methods to potentially add to String to take advantage of raw string literals. These ideas for kicking off discussion include "line support", enhancements to "trim" methods, "margin management", and "escape management". Some of these are facilitated by RSL while others are necessitated by RSL. The cited post provides multiple examples of each of these.

Issue JDK-8198986 points out that "a new JLS section is needed for raw string literals." This issue links to a currently proposed section to be added to the cited Java Language Specification.

Although JEP 326 is still just a "Candidate" and is not associated with a particular release of Java, recent work on it and recent discussion in mailing list posts seeking input related to it lead me to be cautiously optimistic that we'll see multi-line Java strings and other raw string literals coming to Java in a future release.

Tuesday, March 13, 2018

Updates on JavaFX, Valhalla, Data Classes, and Java's Floating-Point

There have been some interesting posts this week and in recent weeks that provide more insight into the future of Java and the JDK.

JavaFX Removed from JDK with JDK 11

In the blog post "The Future of JavaFX and Other Java Client Roadmap Updates," Oracle's Donald Smith announced that "starting with JDK 11, Oracle is making JavaFX easier to adopt by making the technology available as a separate download, decoupled from the JDK." Smith provides a brief history of JavaFX and discusses other motivations for the decision to decouple JavaFX from the JDK.

The "The Future of JavaFX and Other Java Client Roadmap Updates blog post concludes with a reference to the March 2018 Oracle whitepaper "Java Client Roadmap Update." That referenced whitepaper describes "the Java Client" as "consist[ing] of Java Deployment (Applets and Web Start) and Java UI (Swing, AWT and JavaFX) technologies" and then "provides an overview of the current roadmap and recommendations for each technology." About Swing/AWT, this whitepaper states, "Swing and AWT will continue to be supported on Java SE 8 through at least March 2025, and on Java SE 11 (18.9 LTS) through at least September 2026."

Valhalla

Project Valhalla hosts some of the concepts and ideas I most excitedly anticipate for future versions of Java. I have long wanted reified generics (still only listed on the Valhalla Wiki page as "possibly other related topics" to be considered in the future), but also look forward to "value objects." I have written before, in the post "The Value in Project Valhalla," about what makes value objects so exciting.

In a recent post on the core-libs-dev mailing list, Brian Goetz wrote about how Valhalla might one day address "an obvious gap between primitive and reference types in Java." Goetz describes how Java makes it easy to add libraries, but that "the primitive types we have are fixed and we effectively cannot make more." Goetz states that Valhalla's solution to this gap is the introduction of "value types" that "are like classes" in some characteristics, but "are like primitives" in terms of other characteristics. He sums this up as, "Codes like a class, works like an int." Most of this was not new to me thanks to Goetz's and others' earlier posts and articles on value types. However, Goetz points out in this mailing list post a "now obvious" to me consequence of these value types: "Value types let us write new numeric (and other) types as library classes, and get the performance characteristics of primitives." This concept makes me wish we had value types yesterday!

Goetz provides a very rough idea of the timeframe for value types in a future version of the JDK. He writes, "Project Valhalla has been rolling for a few years, and will likely go for a few more until we reach the point where this is practical -- and more after that before value types can fit cleanly into the generic type system." This statement dampens my hopes a bit, but does seem realistic given the magnitude and broad scope of the changes involved.

The "Valhalla EG notes" dated 28 February 2018 provide insight to the current state of Valhalla.

Floating-Point in Java

The Goetz post on how Valhalla might someday allow Java developers to write "their favorite numeric type" as "ordinary user-written libraries" when not already "built into the platform" exists in the context of a mailing list thread about a request user request and statement that "the java language needs to be changed" in relation to "arithmetic underflow and overflow" and "arithmetic approximation" associated with Java's floating-point types. What caught my particular attention (besides Goetz's reference to Valhalla) in this thread is an excellent overview of Java's handling of float-point types provided by Joe Darcy.

In this mailing list message (which would make an outstanding blog post or article), Darcy concisely and thoroughly (hard to do at the same time) lays out the challenges associated with representation of and calculation using floating-point approximations "with pragmatic compromises to facilitate calculation on computers." This post is much more accessible to most of us developers than the 70+ pages of the classic article "What Every Computer Scientist Should Know About Floating-Point Arithmetic."

Darcy also provides guidance on what to expect in future versions of Java's handling of floating-points. He writes (I added the emphasis):

There are no prospects for a fundamental redefinition of the floating-point semantics of the Java language and VM. It is possible a faster and looser mode will be defined at some point, but altering the default is extremely unlikely. Long-term, decimal-based arithmetic (and other kinds of arithmetic) may get better support as a consequence of the features in Valhalla.

The Darcy post is worth reading for its overview of floating-point computations in binary-based computer systems in general and in Java in particular. Darcy concludes the post with a paragraph on expected etiquette on the OpenJDK mailing lists.

Data Classes

In a February 2018 post titled "Data Classes for Java", Goetz "explores possible directions for data classes in the Java Language." Goetz contrasts data classes versus value types (such as pointing out that data classes have identity while value types sacrifice identity to reduce overhead). He also explains why data classes are preferable to tuples and to the "only syntax-deep" "compact syntactic forms for modeling data-oriented classes" such as those provided by Scala (case) and Kotlin (data). Much of this post is on considerations that must be made when designing and implementing data classes in Java.

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.