DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Java
  4. Better NPE Messages in JDK 14

Better NPE Messages in JDK 14

Learn more about Early Access Builds for JDK 14, specifically better NullPointerException messages.

Dustin Marx user avatar by
Dustin Marx
·
Oct. 29, 19 · News
Like (7)
Save
Tweet
Share
13.52K Views

Join the DZone community and get the full member experience.

Join For Free

JDK 14 NPE Messages

Learn more about creating better NPE messages with JDK 14!

My March 2019 blog post "Better Default NullPointerException Messages Coming to Java?" was written when the draft JEP for better NullPointerException messages had not yet been targeted to a particular JDK release. Since then, that draft JEP became JEP 358 ("Helpful NullPointerExceptions"), which has been targeted for JDK 14. Even better, the initial implementation (JDK-8218628) is already in the JDK 14 branch and is available to play around with in JDK 14 Early Access Builds, Build 20 (2019/10/23).

In this post, I will run the example code introduced in my previous post against the JDK 14 Early Access Build 20 to demonstrate the additional details now provided. To see the example code that was written to intentionally introduce a variety of situations resulting in NullPointerExceptions, check out that post or view the source code on GitHub.

You may also like: 10 Tips to Handle Null Effectively

With the JDK 14 Early Access Build 20 downloaded and pointed to by my path, I see the following when I run java -version:

openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+20-879)
OpenJDK 64-Bit Server VM (build 14-ea+20-879, mixed mode, sharing)


With the JDK 14 Early Access Build 20 configured appropriately, I rebuilt the source code mentioned previously and then re-ran the code with the Java launcher without any new options. The output from this (shown below) is not materially different from the output with previous JDK versions.

=========================================
| #1: Element [0] on null boolean array |
=========================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateFirstExampleIndexAccessOnNullBooleanArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=================================
| #2: .length on null boolean[] |
=================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateSecondExampleLengthOnNullBooleanArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=======================================
| #3: Assigning float to null float[] |
=======================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateThirdExampleAssigningValueToElementOfNullFloatArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

======================================
| #4: Accessing field on null object |
======================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateFourthExampleAccessInstanceFieldOfNullObject(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

===================
| #5: throw null; |
===================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateFifthExampleThrowingConstantNull(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

================================================
| #6: Method invocation on null instance field |
================================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateSixthExampleMethodInvocationOnNullInstanceField(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=============================================
| #7: synchronized() on null instance field |
=============================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateSeventhExampleSynchronizedNullInstanceField(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

==========================================================================
| >>> Null Lost in Long Series of Method Invocations in Single Statement |
==========================================================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInSeriesOfMethodInvocationsInSingleStatement(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=======================================================
| >>> Null Lost in Dereferenced Constructor Arguments |
=======================================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInConstructorAcceptingMultiplePotentiallyNullArgumentsDereferenced(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

==================================================
| >>> Null Lost in Dereferenced Method Arguments |
==================================================

java.lang.NullPointerException
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInMethodAcceptingMultiplePotentiallyNullArgumentsDereferenced(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)


As the above output demonstrates, even with the new JDK 14 Early Access Build 20, I don't see any new detailed information regarding NullPointerExceptions when I run my application as normal. I included this output to show that a special flag is needed to enable the more detailed NullPointerExceptions and to make it more convenient to compare the output without and with the extra details. The next output listing shows the additional details provided when the Java launcher is passed the flag -XX:+ShowCodeDetailsInExceptionMessages:

=========================================
| #1: Element [0] on null boolean array |
=========================================

java.lang.NullPointerException: Cannot load from byte/boolean array because "<local1>" is null
 at dustin.examples.npe.NpeDemo.demonstrateFirstExampleIndexAccessOnNullBooleanArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=================================
| #2: .length on null boolean[] |
=================================

java.lang.NullPointerException: Cannot read the array length because "<local1>" is null
 at dustin.examples.npe.NpeDemo.demonstrateSecondExampleLengthOnNullBooleanArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=======================================
| #3: Assigning float to null float[] |
=======================================

java.lang.NullPointerException: Cannot store to float array because "<local1>" is null
 at dustin.examples.npe.NpeDemo.demonstrateThirdExampleAssigningValueToElementOfNullFloatArray(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

======================================
| #4: Accessing field on null object |
======================================

java.lang.NullPointerException: Cannot read field "nullInstanceField" because "<local1>" is null
 at dustin.examples.npe.NpeDemo.demonstrateFourthExampleAccessInstanceFieldOfNullObject(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

===================
| #5: throw null; |
===================

java.lang.NullPointerException: Cannot throw exception because "null" is null
 at dustin.examples.npe.NpeDemo.demonstrateFifthExampleThrowingConstantNull(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

================================================
| #6: Method invocation on null instance field |
================================================

java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "this.nullInstanceField" is null
 at dustin.examples.npe.NpeDemo.demonstrateSixthExampleMethodInvocationOnNullInstanceField(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=============================================
| #7: synchronized() on null instance field |
=============================================

java.lang.NullPointerException: Cannot enter synchronized block because "this.nullInstanceField" is null
 at dustin.examples.npe.NpeDemo.demonstrateSeventhExampleSynchronizedNullInstanceField(Unknown Source)
 at dustin.examples.npe.NpeDemo.demonstrateJdk8218628Examples(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

==========================================================================
| >>> Null Lost in Long Series of Method Invocations in Single Statement |
==========================================================================

java.lang.NullPointerException: Cannot invoke "dustin.examples.npe.DysfunctionalLocation$Province.getCity()" because the return value of "dustin.examples.npe.DysfunctionalLocation$Nation.getProvince()" is null
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInSeriesOfMethodInvocationsInSingleStatement(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

=======================================================
| >>> Null Lost in Dereferenced Constructor Arguments |
=======================================================

java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because "<local6>" is null
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInConstructorAcceptingMultiplePotentiallyNullArgumentsDereferenced(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)

==================================================
| >>> Null Lost in Dereferenced Method Arguments |
==================================================

java.lang.NullPointerException: Cannot invoke "java.lang.Long.longValue()" because "<local6>" is null
 at dustin.examples.npe.NpeDemo.demonstrateNullLostInMethodAcceptingMultiplePotentiallyNullArgumentsDereferenced(Unknown Source)
 at dustin.examples.npe.NpeDemo.main(Unknown Source)


JEP 358 explains the use of this flag for seeing additional NullPointerException details: "The feature can be toggled with the new boolean command-line option -XX:{+|-}ShowCodeDetailsInExceptionMessages. The option will first have default 'false' so that the message is not printed. It is intended to enable code details in exception messages by default in a later release." As we see, this feature is initially turned off by default, but there is a plan to enable more detailed NullPointerException messages in the future.

A recent Tweet asked the question: "How it will work if bytecode doesn’t contain variable names?"

The question continued by providing a specific example: "Suppose we have code like Object a = ....; a.getName(); //NPE What kinds of message NPE would have?" Although an example of this is included in my battery of tests shown earlier, I thought I'd provide a more focused example here in response to that question. The next code listing (which is also available on GitHub) shows code adapted from the example used in the Tweet.

package dustin.examples.npe;

/**
* Simple demonstration to answer Tweet-ed question
* "How it will work if bytecode doesn't contain variable names?"
* (https://twitter.com/2doublewhiskey/status/1180365953240055809).
*/
public class TwoDoubleWhiskeyTweetExample
{
public static void main(final String[] arguments)
{
final Person person = null;
person.getName(); //NPE
}

public static class Person
{
private String name;

public Person(final String newName)
{
name = newName;
}

public String getName()
{
return name;
}
}
}


The next screen snapshot shows the result of running this simple application with the JDK 14 Early Access Build 20 without, and then with, the java launcher flag -XX:+ShowCodeDetailsInExceptionMessages.

JDK 14 EAB 20 result

As the screen snapshot indicates, using the -XX:+ShowCodeDetailsInExceptionMessages flag with the JDK 14 Early Access Build 20 provides this additional detail related to this simple NullPointerException example: "Cannot invoke "dustin.examples.npe.TwoDoubleWhiskeyTweetExample$Person.getName()" because "<local1>" is null"

An example that is simpler and even closer to the original example provided in the Tweet-ed question is available on GitHub.

JEP 358 ("Helpful NullPointerExceptions") may not be as flashy as some other JEPs that come to new JDK releases, but it may be one that in the end provides more value to Java developers on a daily basis than some of its flashier peers. There are numerous examples where this will be helpful, and many of those example situations are spelled out in the JEP itself, and in my code examples referenced in this post.

Further Reading

10 Tips to Handle Null Effectively

NPE — Free Code Without Null Checks

Java (programming language) Java Development Kit

Published at DZone with permission of Dustin Marx, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 3 Main Pillars in ReactJS
  • How To Build an Effective CI/CD Pipeline
  • A Beginner's Guide to Infrastructure as Code
  • DeveloperWeek 2023: The Enterprise Community Sharing Security Best Practices

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: