Upgrading To Java 17

Upgrading To Java 17

Upgrading to Java 17

What is Java 17?

Java 17 is the 17th release of the Java SE platform. It was released on September 14, 2021, and provides a variety of new features performance improvements over Java 11. More information on the release of Java 17 can be found here at the OpenJDK Java 17 release page.

Java is general purpose, class based, object-oriented programming language and computing platform first developed by Sun Microsystems in 1995 by James Gosling. It is free to download, and free to use under certain conditions. Java can run on Windows, NIX, and MacOS with ease, and is considered a write-once run anywhere programming language where it compiles the source code to Java byte code which can be run on all platforms that support the Java runtime environment.

What is the difference between Active Support and Security Support?

Active support includes performance updates, bug fixes, new features, and support resources to maintain the release of Java. Security support includes JDK and JRE security vulnerabilities that are discovered during the lifecycle.

What is the support model for Java 11 vs Java 17?

Java 17 is the next LTS release of Java. More information can be found on the version support lifecycles at one the endoflife.date page for Java. In a nutshell, active support for Java 11 ends in September 2023 whereas Java 17 ends in September 2026.

What about Java 12 through 16?

Java 12 through 16 are not considered long term support. At the time of writing this article, security support for Java 16 ended 4 months ago whereas security support for Java 17 ends in 9 years, so it’s highly unlikely anyone is running Java 16 in production. Generally it is not recommended to use these release versions for production applications due to their short short support cycles, so wise choices for production services should include using software packages that are supported for long periods of time. Every organization is different, so certain use cases may require these releases, but the 99% use case is generally supported using long term support release of Java.

What am I doing?

We are just now starting to upgrade our greenfield projects to Java 17. We will hold off on upgrading existing production projects until we can evaluate the imapct to our greenfield projects. After these have been migrated, we will likely consider upgrading our other projects to use Java 17.

Should I upgrade to Java 17?

Ultimately this depends on your organization. Active support ends in September 2023, and Security support ends in September 2026. If you rely on Java performance optimizations and feature updates, then you should probably schedule tech debt to update your Java releases in early 2023. Greenfield projects or projects that are not yet in production should consider the update before going production to minimize tech debt later. This would also minimize risk of issues when deploying the newer release of Java, and establish organization upgrade documentation to identify actions required to upgrade your projects.

Should I use OpenJDK or Oracle JDK?

OpenJDK. There are very few use cases where Oracle JDK would be recommended over OpenJDK as Oracle has tried to commercialize the product. One of the biggest issues with Oracle is their licensing agreement where Oracle JDK has been licensed under the Oracle Binary Code License Agreement where its use would require an Oracle Commercial license to use. When buying the commercial license, a user would get enterprise level support which would provide expedited bug fixes to any bugs encounted when using the JDK. OpenJDK is free and open source and falls under the GNU GPL V2 license, and can be used freely.

Oracle’s JDK is based on OpenJDK with additional features that come with the purchase of a license.

What about other JDKs?

There are other JDKs that are excellent candidates for development and production which include Amazon’s Corretto. Corretto is Amazon AWS’ JDK which promises more expedited bug fixes and patches for its supported releases, and has a much longer release cycle for minor releases that attempts to offer LTS releases for the non-LTS releases of Java. Corretto also includes patch fixes prioritized at communication with Amazon services.

See here for more information on Amazon’s Corretto Support Roadmap which details a 2 year release cadence for LTS releases, and highlights version 17 release support until 2028 whereas OpenJDK support ends in 2026.

What do I get from upgrading to Java 17 from Java 11?

Record objects

Record objects are really cool, and you’ll find a lot of overlap between Record objects and what Lombok has to offer. First off, Lombok is a tool that can be used to generate boilerplate Java byte code by adding annotations to classes. You’ll find things like @Builder, @Data, @Getter, @Setter, @AllArgsConstructor, and @Value to be the most common annotations. Java records are actual syntax that carry semantic features and alter the logic behind the object whereas Lombok is a processor that generates common patterns of code. To create a Java record, you’ll just define the input parameters, and I recommend that you define it as serializable as well so you can convert it to a JSON object like so:

import java.io.Serializable;

public class Hello {
    public static void main(String ...args) {
        new Hello().hello();
    }

    public void hello() {
        var h2 = new Hello2("GoodLifeRead");
        System.out.println(h2.toString());
        System.out.println(h2 instanceof Serializable);
    }
    
    public record Hello2(String name) implements Serializable {}
}

This returns the following output:

Hello2[name=GoodLifeRead]
true

One of the other options is to use JsonProperty from Jackson annotations to serialize the object. This way you can combine records with spring boot controllers to reduce boilerplate code to create your rest controllers.

public record Hello2(@JsonProperty("name")String name) { }

Text Blocks

For those of us who work interchangeably with both Python and Java, one of the common features of Python is the ability to use triple quotes to create long strings without using new line breaks or string concatenation, and this has finally made its way into Java 17. As an example:

String str = """
This is a
multiline string.
""";

Strings are very common objects used when I program in Java, and this just increases its flexibility. This block annotation can also maintain indentation. For example if you were generating HTML, and wanted to indent your tags, this would hold up:

String str = """
<div>
    <p>Hello</p>
<div>
""";

And the result would be:

<div>
    <p>Hello</p>
<div>

Sealed classes

Another syntax is sealed classes which allows you to permit certain sublcasses for inheritance. As an example:

public sealed interface Animal permits Cat {
    String getNoise();
}

public record Cat(String noise) implements Animal {
    @Override
    public String getNoise() {
        return noise;
    }
}

When attempting to add a Dog record, you get the following exception:

error: class is not allowed to extend sealed class: Animal (as it is not listed in its permits clause)
    public record Dog(String noise) implements Animal {

More Verbose Null Pointer Exception Logging

Null Pointer Exceptions can be a drag, but usually it’s quite quick to spot where you went wrong. With Java 17, they’ve improved the logging of the Null Pointer Exception. Here’s an example of some Java code that returns a Null Pointer Exception:

Map<String, Cat> map = new HashMap<>();
map.get("asdf").getNoise();

And the result:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Demo$Cat.getNoise()" because the return value of "java.util.Map.get(Object)" is null

Conclusion

Different strokes for different folks. If it fits for your organization, go for it, but don’t be so eager to jump on the band wagon if you have higher priority things to worry about. Personally, I’m excited to use the new record feature, and can’t wait to demo the code structure to my team.