Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Are you seriously not using Java 15 yet?
Alessandro Aiezza
Alessandro Aiezza

Posted on • Edited on

     

Are you seriously not using Java 15 yet?

Introduction

  • What I want to accomplish: I want to move toAmazon Corretto 15 so I can use the new features in my work projects. These features feel long awaited; So much so,Kotlin andLombok continue to gain popularity.
  • How: I plan to convert an existing Java project from amazon‑corretto‑11 to amazon‑corretto‑15,and add code to the project which will leverage the new features just to see how our infrastructure handles them.
  • Caveats: This particular service is dockerized. So we would also need to update our docker image to use Java 15. I plan to run the project outside of docker just usingmvn from a local shell.

Conversion process

Change the Maven compiler plugin version.

In the build section of thepom.xml file:

<build><plugins>            . . .<plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><release>15</release><compilerArgs><arg>--enable-preview</arg></compilerArgs></configuration></plugin>            . . .<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><forkCount>0</forkCount><argLine>--enable-preview</argLine></configuration></plugin>            . . .<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-failsafe-plugin</artifactId><configuration><argLine>--enable-preview</argLine></configuration></plugin></plugins><build>
Enter fullscreen modeExit fullscreen mode

I neededforkCount in thesurefire plugin configuration because the parent pom declares something higher than0,SUREFIRE-1528.

This is a great reminder that some of the features in 15 are technically experimental still and require preview.
While I would be hesitant to use preview features in a production system, Amazon hasfaithfully iterated on corretto-11 through patches. Thus, as issues arise, there is iteration to fix those problems, and I believe that would also extend to preview features.
And I think it's safe to assume thatcorretto-15 will also have patches issued.

Installing Amazon Corretto 15

Downloadamazon-corretto-15

Or for the Linux users, you couldn't ask for a sweeter time:Linux package managed installation instructions

Updating my IDE

IntelliJ

Download the latest IntelliJ and you will have been all set to useJava 15 since version 2020.2!

Eclipse

Download the latest Eclipse

Using the JDK

Just make sure when you're setting up your IDE, that you point to the correctto JDK installation!

Let's try out these Java 15 features

No more need for lombok here | Records

Here is a simple class in the existing project. Users in this domain are given a "baby step" between0 and7.

With Lombok:

@lombok.DatapublicclassUserBabyStep{publicstaticfinalUserBabyStepNO_BABY_STEP=newUserBabyStep();publicstaticfinalintDEFAULT_BABY_STEP=0;publicstaticfinalintMAX_BABY_STEP=7;privatefinalintvalue;publicUserBabyStep(){this.value=DEFAULT_BABY_STEP;}publicUserBabyStep(finalintvalue){if(value<0||value>MAX_BABY_STEP)thrownewIllegalArgumentException("The Baby Step of a user must be between 0 and 7 inclusively.");this.value=value;}}
Enter fullscreen modeExit fullscreen mode

Hellorecords!

publicrecordUserBabyStep(intvalue){publicstaticfinalUserBabyStepNO_BABY_STEP=newUserBabyStep();publicstaticfinalintDEFAULT_BABY_STEP=0;publicstaticfinalintMAX_BABY_STEP=7;publicUserBabyStep(){this(DEFAULT_BABY_STEP);}publicUserBabyStep(finalintvalue){if(value<0||value>MAX_BABY_STEP)thrownewIllegalArgumentException("The Baby Step of a user must be between 0 and 7 inclusively.");this.value=value;}}
Enter fullscreen modeExit fullscreen mode

Notes forrecord

Lombok will generate a more Java‑canonical getter method for fields:getValue(). The getter method produced by therecord feature is:value().
This is more similar to how theImmutables library operates, andis a fancy way to get around when you may, or may not wantisFlag forboolean getters. Especially if you are like me, and prefer leveraging the type system for wrapping primitives in a more domain‑driven class.

Another note is thatrecord‑declared classescannot extend another class! Only implement interfaces.

Necessary usage of the canonical constructor

Finally, when using records, all constructorsmust call the canonical constructor. That is, the constructor with the same types, order, and number of arguments that are declared on the record itself.

Who's up for Checkers?

Instead of just looking for more things to change around in this existing project, I'm going to add irrelevant code simply for the sake of flexing the new features. And then, I want to see how it compiles and how the project plugins handle it.

Also, I isolated thecheckers code if you'd like to take a closer look.

Sealed Interfaces

I'm going to mess around with this here, however, see the note at the end of the article concerning sealed interfaces.

A checker board tends to have two alternating colors tiling a 8 x 8 board.

checkerboard

Eachspace/tile can havecontents; a red or black token.

To demonstrate the difference between individual tiles, there is a sealed interface calledSpace whichpermits aBlackSpace and aRedSpace. Each subclass then also implements thewither method that allows a space to take new contents.

publicenumContents{EMPTY,BLACK,RED;}publicstaticsealedinterfaceSpacepermitsBlackSpace,RedSpace{publicContentscontents();publicintx();publicinty();publicSpacewithContents(finalContentsstate);publicdefaultbooleanisEmpty(){returncontents()==Contents.EMPTY;}publicdefaultbooleancontains(finalContentsstate){returncontents()==state;}publicrecordBlackSpace(Contentscontents,intx,inty)implementsSpace{publicBlackSpace(finalintx,finalinty){this(Contents.EMPTY,x,y);}@OverridepublicSpacewithContents(finalContentscontents){returnnewBlackSpace(contents,x,y);}}publicrecordRedSpace(Contentscontents,intx,inty)implementsSpace{publicRedSpace(finalintx,finalinty){this(Contents.EMPTY,x,y);}@OverridepublicSpacewithContents(finalContentscontents){returnnewRedSpace(contents,x,y);}}}
Enter fullscreen modeExit fullscreen mode

Now ourCheckerBoard can look a little something like this:

@SuppressWarnings("preview")publicclassCheckerBoard{privatestaticintMAX=8;privatefinalSpace[][]spaces;privateCheckerBoard(){spaces=newSpace[MAX][MAX];forEachSpace((i,j)->spaces[i][j]=((i+j)%2==0)?newBlackSpace(i,j):newRedSpace(i,j));}...}
Enter fullscreen modeExit fullscreen mode

Note: that, if you are anything like me, you aren't a fan of warnings. So here's a way tosuppress them for the preview features we'll be using.

Multi-line Strings

Java eliminates all leading whitespace between newlines!
Luckily, I already had a scenario where I would not need leading spaces in my string anyways:

classCheckerBoardTest{@TestvoidshouldPrintBoardAsExpected(){finalCheckerBoardsubject=CheckerBoard.freshBoardWithTokens();assertThat(subject.toString()).isEqualTo("""            Ω · Ω · Ω · Ω ·            · Ω · Ω · Ω · Ω            Ω · Ω · Ω · Ω ·            · • · • · • · •            • · • · • · • ·            · ☺ · ☺ · ☺ · ☺            ☺ · ☺ · ☺ · ☺ ·            · ☺ · ☺ · ☺ · ☺            """);}}
Enter fullscreen modeExit fullscreen mode

The google format spec basically has no idea what to do with this…

Pattern Matching ininstanceof (instanceof casting)

This is a really handy trick that I wish was introduced much earlier.

It is also reminiscent ofa feature of the AssertJ testing library.

The key use of this feature is to prevent a manual class cast of a variable after you areonly in a block of code based on the type of a variable.

So instead of:

publicvoidmethod(finalAnimalanimal){if(animalinstanceofCat){((Cat)animal).meow();}}
Enter fullscreen modeExit fullscreen mode

We can do:

publicvoidmethod(finalAnimalanimal){if(animalinstanceofCatcat){cat.meow();}}
Enter fullscreen modeExit fullscreen mode

This method will set up a new checkboard and place the players' tokens in their starting positions. Since pieces should only be allowed to be played to the black spaces on the board, I can place pieces using the awither to keep eachspace instance of my board immutable.

publicstaticCheckerBoardfreshBoardWithTokens(){finalCheckerBoardboard=newCheckerBoard();board.forTopThreeRowsOfSpaces(space->{if(spaceinstanceofBlackSpaces){board.spaces[s.x()][s.y()]=s.withContents(BLACK);}});board.forBottomThreeRowsOfSpaces(space->{if(spaceinstanceofBlackSpaces){board.spaces[s.x()][s.y()]=s.withContents(RED);}});returnboard;}
Enter fullscreen modeExit fullscreen mode

To be fair, the cast here is not necessary. So if you can come up with a better use case, I'd be happy to hear about it in the comments!

Switch Expression

OurCheckerBoard class has a convenienttoString method for a user friendly visual:

@OverridepublicStringtoString(){returnstreamSpaces().map(space->{finalStringstrSpace=(switch(space.contents()){caseEMPTY:yieldspaceinstanceofRedSpace?"·":"•";caseBLACK:yield"Ω";caseRED:yield"☺";});returnString.format("%s%s",strSpace,space.isRightEdge()?"\n":" ");}).reduce(newStringBuilder(),StringBuilder::append,(l,r)->l).toString();}
Enter fullscreen modeExit fullscreen mode

That newyield keyword at work! I can essentially iterate over eachspace to yield a character.

More examples can be found here at thisBaeldung article.

Issues

  • google code formatter breaks. It looks like it breaks on records, multi-line strings, and theyield keyword that occurs in the switch expressions
  • the maven compiler (actually, the JVM) requires the--enable-preview flag to unlock the features. This is an obvious red flag for usage in production code. It is hard to assess the risk of using these features as well. In the past, many features of the JDK that shipped as previews in earlier versions of Java have actually functioned perfectly. Will that continue to be the case?

Wrap-up

One cannot simply assume thatpreview Java feature will become integrated into the JDK long‑term.
TheJavaDoc for theRecord class even contains a disclaimer:

This class is associated withrecords, a preview feature of the Java language. Programs can only use this class when preview features are enabled. Preview features may be removed in a future release, or upgraded to permanent features of the Java language.

In the case ofrecords, however, you can breathe easy, as it isofficially integrated into Java 16.

As for the other features described in this article:

FeatureJava version introducedJava version finalized
Pattern Matching ininstanceof1416
Records1416
Multi-line Strings1314
Switch Expressions1214
Sealed interfaces15?

Sealed interfaces are still not officially being integrated. Even if they stick around, their syntax is subject to change. So that isn't a feature we were able to use here yet.

The other features that I listed as being integrated for version 16, have not changed syntactically since 15, (as far as I could tell). So with those, you're in the clear

Verdict

If you don't care about using the Google code formatter plugin for a while, and don't care about using sealed interfaces yet, you and your team can make the upgrade!

If for some reason you are still tempted to use the sealed interfaces anyways, I would strongly suggest not using them! It is not an officially integrated feature and could change or even go away.
A good example of this was the "Switch Expressions" feature. It was introduced in version 12 and overloaded thebreak keyword. This was changed toyield in version 13 to make more clear the intended behavior. Since it changed, it naturally needed to stay in preview in version 13, then finally was accepted in version 14. There's no telling what kind of iteration the sealed interfaces could still undergo.


Complete side-note | Speaking of features coming and going or staying

Sometimes, it is nice to declare aFunction in a Java Lambda, but you plan to return a specific object regardless of the input. In the past, I have used an underscore_ to define the variable of non-interest.Java 9 had discontinued this from being allowed.
Which I found interesting, considering that the introduction of_ as a variable name, had the apparent intention of being used inlambdas for unused arguments.

While in our code bases, we have now switched to using double underscores__ for this, we also use Vavr. So a nice alternative might be to useFunction1.constant.

Top comments(7)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
viniciusvasti profile image
Vinícius A. dos Santos
I'm Vinicius. I'm a Software Engineer and Solutions Architect who loves everything about Software craftsmanship, designing solutions and, of course, coding.
  • Location
    São Paulo, Brazil
  • Education
    BS Systems Analysis
  • Work
    Software Engineer/Technical Leader at Lojas Riachuelo
  • Joined

Do you know sdk man?
It's a really helpful tool for managing several sdk's versions.
sdkman.io/

CollapseExpand
 
aaiezza profile image
Alessandro Aiezza
From Rochester, NY • Husband • Father to Three Sons • Jesus • Fall in love with the problem, not the solution
  • Email
  • Location
    Rochester, NY
  • Education
    Master of Science in Bioinformatics | Rochester Institute of Technology
  • Work
    Senior Software Engineer at USAA
  • Joined

Thanks@viniciusvasti!
I had not heard of this until now.
Seems interesting. I'll check it out.

CollapseExpand
 
viniciusvasti profile image
Vinícius A. dos Santos
I'm Vinicius. I'm a Software Engineer and Solutions Architect who loves everything about Software craftsmanship, designing solutions and, of course, coding.
  • Location
    São Paulo, Brazil
  • Education
    BS Systems Analysis
  • Work
    Software Engineer/Technical Leader at Lojas Riachuelo
  • Joined

It's really usefull.
I have to change between Java 8, Java 11 and Java 15 constantly and all I need is runsdk use java 8.0.275.open-adpt

CollapseExpand
 
pmgysel profile image
Philipp Gysel
I love Java☕. 6 years of professional experience. I am interested in architecture, SpringBoot, and new Java features.
  • Email
  • Location
    Switzerland
  • Education
    Master's degree in ECE
  • Work
    Software Engineer at Intersys AG
  • Joined

Great article Alessandro! I like the part where you describe the simple Maven changes required to switch to Java 15 in preview mode 😀

CollapseExpand
 
aaiezza profile image
Alessandro Aiezza
From Rochester, NY • Husband • Father to Three Sons • Jesus • Fall in love with the problem, not the solution
  • Email
  • Location
    Rochester, NY
  • Education
    Master of Science in Bioinformatics | Rochester Institute of Technology
  • Work
    Senior Software Engineer at USAA
  • Joined

@pmgysel I'm glad you could find it useful!

CollapseExpand
 
pazvanti profile image
pazvanti
  • Location
    Timisoara, Romania
  • Work
    Senior Back-end Java Developer at ACI Worldwide
  • Joined

Good article on a few key changes in Java 15. However, from my experience, big projects have a tendency to fall behind in versions. They prefer stability rather than using the latest and greatest.

CollapseExpand
 
aaiezza profile image
Alessandro Aiezza
From Rochester, NY • Husband • Father to Three Sons • Jesus • Fall in love with the problem, not the solution
  • Email
  • Location
    Rochester, NY
  • Education
    Master of Science in Bioinformatics | Rochester Institute of Technology
  • Work
    Senior Software Engineer at USAA
  • Joined

@pazvanti I concur! Youdo gain a little more freedom when iterating on very small projects/microservices, but unless there's a great advantage for switching, or great disadvantage for not switching, using what you have is a great idea.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

From Rochester, NY • Husband • Father to Three Sons • Jesus • Fall in love with the problem, not the solution
  • Location
    Rochester, NY
  • Education
    Master of Science in Bioinformatics | Rochester Institute of Technology
  • Work
    Senior Software Engineer at USAA
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp