Sunday, April 26, 2020

SudokuFX: Migration to Java11 LTS

Better late than never: now I want to migrate SudokuFX to Java11.

Up to version 2020.1.1,  SudokuFX needs a Java Runtime with JavaFX integrated - version 8. Choosing the correct Java version is the first hurdle for the casual internet visitor, very easy to 'do wrong'. Cryptic errors will drive away newcomers, will cost even pro's some time until they realize that the wrong platform is used.

Java != Java

Choosing the wrong Java version is a common problem for beginners, I must admit that it becomes more and more complicated.

Every half year a new Java version is released, with new features, and several organisations provide builds. This is a good thing, the industry has to evolve the platform, and it is good if there exist different sources for Java binaries. Many years of development went into a build process which is now simple enough for the average Bob D. Eveloper to build OpenJDK themselves, which is - considering the details - a huge accomplishment. 

For the rest of us, the question is which version of Java to choose? Oracle is still the place to go if you have much money to buy their licenses and subscriptions. Alternatives can be used from AdoptOpenJDK, Azul and others. To ease the migration costs, LTS versions are maintained for a longer period of time - Java version 11 is the one the industry migrates to at this very moment. 

And even me with my SudokuFX project.

Still one has to keep in mind that everybody is advertising their latest release, as such often the newest runtimes and jdks are downloaded, and projects written for older incarnations of those technologies maybe just don't work. 

If your project has dependencies on libraries which are also only written for a specific version of the JDK the game becomes even more complex. Then, as a Scala User, you have even more troubles since libraries for a specific version of Scala doesn't really work together with a different Scala version ... 

I didn't even mention the modularization effort of the JDK itself, which - only very slowly but in a foundational manner - reinvents the whole ecosystem yet again. 

Don't get me wrong, everything happens because of a perfectly sound reason, but it is not trivial to get everything working, considering all those moving targets. There are also not many engineers around who can really cope with those topics to be honest.

Well. Enough motivation to do the move to Java11, without any JavaFX backed in the java runtime. 

SDK! Man!

To easily switch between Java versions (and jvm based applications like sbt, lein, scala and others) a tool called sdkman exists, which is very handy and lets you download and change used version of Java with a simple command. It's like a package manager, just for specific (java) applications. Highly recommended!

Here is an example of how it looks if you want to change a java version from current one to to the version AdoptOpenJDK provided, Java version 11:

homemac:sudokufx lad$ sdk list java
================================================================================
Available Java Versions
================================================================================
 Vendor        | Use | Version      | Dist    | Status     | Identifier
--------------------------------------------------------------------------------
 AdoptOpenJDK  |     | 14.0.1.j9    | adpt    |            | 14.0.1.j9-adpt      
               |     | 14.0.1.hs    | adpt    |            | 14.0.1.hs-adpt      
               |     | 14.0.0.j9    | adpt    | local only | 14.0.0.j9-adpt      
               |     | 13.0.2.j9    | adpt    |            | 13.0.2.j9-adpt      
               |     | 13.0.2.hs    | adpt    |            | 13.0.2.hs-adpt      
               |     | 13.0.1.hs    | adpt    | local only | 13.0.1.hs-adpt      
               |     | 12.0.2.j9    | adpt    |            | 12.0.2.j9-adpt      
               |     | 12.0.2.hs    | adpt    |            | 12.0.2.hs-adpt      
               |     | 11.0.7.j9    | adpt    |            | 11.0.7.j9-adpt      
               |     | 11.0.7.hs    | adpt    | installed  | 11.0.7.hs-adpt      
               |     | 8.0.252.j9   | adpt    |            | 8.0.252.j9-adpt     
               |     | 8.0.252.hs   | adpt    |            | 8.0.252.hs-adpt     
 Amazon        |     | 11.0.7       | amzn    |            | 11.0.7-amzn         
               |     | 8.0.252      | amzn    |            | 8.0.252-amzn        
               |     | 8.0.202      | amzn    |            | 8.0.202-amzn        
 Azul Zulu     |     | 14.0.1       | zulu    |            | 14.0.1-zulu         
               |     | 13.0.3       | zulu    |            | 13.0.3-zulu         
               |     | 13.0.3.fx    | zulu    |            | 13.0.3.fx-zulu      
               |     | 12.0.2       | zulu    |            | 12.0.2-zulu         
               |     | 11.0.7       | zulu    |            | 11.0.7-zulu         
               |     | 11.0.7.fx    | zulu    |            | 11.0.7.fx-zulu      
               |     | 11.0.5       | zulu    | local only | 11.0.5-zulu         
               |     | 10.0.2       | zulu    |            | 10.0.2-zulu         
               |     | 9.0.7        | zulu    |            | 9.0.7-zulu          
               |     | 8.0.252      | zulu    |            | 8.0.252-zulu        
               |     | 8.0.252.fx   | zulu    |            | 8.0.252.fx-zulu     
               |     | 8.0.232.fx   | zulu    |            | 8.0.232.fx-zulu     
               |     | 8.0.202      | zulu    |            | 8.0.202-zulu        
               |     | 7.0.262      | zulu    |            | 7.0.262-zulu        
               |     | 7.0.181      | zulu    |            | 7.0.181-zulu        
 BellSoft      |     | 14.0.1.fx    | librca  |            | 14.0.1.fx-librca    
               |     | 14.0.1       | librca  |            | 14.0.1-librca       
               |     | 13.0.2.fx    | librca  |            | 13.0.2.fx-librca    
               |     | 13.0.2       | librca  |            | 13.0.2-librca       
               |     | 12.0.2       | librca  |            | 12.0.2-librca       
               |     | 11.0.7.fx    | librca  |            | 11.0.7.fx-librca    
               |     | 11.0.7       | librca  |            | 11.0.7-librca       
               |     | 8.0.252.fx   | librca  |            | 8.0.252.fx-librca   
               |     | 8.0.252      | librca  |            | 8.0.252-librca      
 GraalVM       |     | 20.0.0.r11   | grl     | installed  | 20.0.0.r11-grl      
               |     | 20.0.0.r8    | grl     |            | 20.0.0.r8-grl       
               |     | 19.3.1.r11   | grl     |            | 19.3.1.r11-grl      
               |     | 19.3.1.r8    | grl     |            | 19.3.1.r8-grl       
               |     | 19.3.0.r11   | grl     |            | 19.3.0.r11-grl      
               |     | 19.3.0.r8    | grl     |            | 19.3.0.r8-grl       
               |     | 19.3.0.2.r11 | grl     |            | 19.3.0.2.r11-grl    
               |     | 19.3.0.2.r8  | grl     |            | 19.3.0.2.r8-grl     
               |     | 19.2.1       | grl     | installed  | 19.2.1-grl          
               |     | 19.1.1       | grl     |            | 19.1.1-grl          
               |     | 19.0.2       | grl     |            | 19.0.2-grl          
               |     | 1.0.0        | grl     |            | 1.0.0-rc-16-grl     
 Java.net      |     | 15.ea.20     | open    |            | 15.ea.20-open       
               |     | 14.0.1       | open    |            | 14.0.1-open         
               |     | 13.0.2       | open    |            | 13.0.2-open         
               |     | 12.0.2       | open    |            | 12.0.2-open         
               |     | 11.0.2       | open    |            | 11.0.2-open         
               |     | 10.0.2       | open    |            | 10.0.2-open         
               |     | 9.0.4        | open    |            | 9.0.4-open          
 SAP           |     | 14.0.1       | sapmchn |            | 14.0.1-sapmchn      
               |     | 13.0.2       | sapmchn |            | 13.0.2-sapmchn      
               |     | 12.0.2       | sapmchn |            | 12.0.2-sapmchn      
               |     | 11.0.7       | sapmchn |            | 11.0.7-sapmchn      
 Unclassified  | >>> | 8.0.201      | none    | local only | 8.0.201-oracle      
================================================================================
Use the Identifier for installation:

    $ sdk install java 11.0.3.hs-adpt
================================================================================
homemac:sudokufx lad$  sdk use java 11.0.7.hs-adpt

Now this shell is configured to use Java11. Neat, isn't it? (You also get a taste of how many different variations of Java distributions exist, and the list is surely not complete ... )

I choose AdoptOpenJDK without JavaFX packaging, since I installed and experimented with it already some time ago. 

homemac:sudokufx lad$ java -version
openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.7+10)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.7+10, mixed mode)

In IntelliJ I have to change the used JDK as well of course.

Nice. But what does it need to change for Java11 LTS support?

Here is an enforcer plugin rule to make sure we run at least at Java11 and with a certain maven version:


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
                <version>3.0.0-M3</version>
                <executions>
                    <execution>
                        <id>enforce-jdk</id>
                        <goals>
                            <goal>enforce</goal>
                        </goals>
                        <configuration>
                            <rules>
                                <requireMavenVersion>
                                    <version>3.6.2</version>
                                </requireMavenVersion>
                                <requireJavaVersion>
                                    <version>11</version>
                                </requireJavaVersion>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>



This rules out already some problems and support tickets which is nice. 

Like mentioned above, I most certainly have to change some dependencies in my poms (my hobby).

A valuable resource for JavaFX is of course openjfx.io. Here you will find simple tutorials to get you up to speed with simple JavaFX projects which you can then use for your apps. They've developed a maven plugin which does almost everything you ever want concerning JavaFX, I hope I have time to look at this in more detail soon.

The company behind this is Gluon, the most active contributor to JavaFX. They work very hard to provide a Java based platform for user interfaces on Desktop, embedded and mobile, which is very valuable for the Java community.

Thanks to them - and others - JavaFX can be used as a 'normal' maven dependency in your project. Which is awesome, from a library developer point of view as well as a user who wants to use it in their next project. 

As such, JavaFX got ripped out from the core JRE, like other elements of the JDK it got modularized in Project Jigsaw. If you want to know more about this go buy this book, thank me later.

We are getting closer to what I actually had to change in SudokuFX - namely introducing new dependencies and throwing out old unsupported ones.



            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-base</artifactId>
                <version>11.0.2</version>
            </dependency>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-swing</artifactId>
                <version>11.0.2</version>
            </dependency>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-fxml</artifactId>
                <version>11.0.2</version>
            </dependency>
            <dependency>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
                <version>11.0.2</version>
            </dependency>


In my case, I struggled a little bit with the javafx-swing dependency, since it was not obvious (at the time) it had to be included as well. As you can see I use four javafx maven dependencies.

Along the way I had to get rid of jfxtras and jfxtras-labs, which don't provide builds for Java11, at least I found none. I also got problems with the scala compiler plugins and IntelliJ (I introduced them in my last post), but I need them only occasionally and as such I commented them out again.

So to sum it up, the migration was quite painless, you can have a look at the result on github - version 2020.2 of SudokuFX ....

Thanks again for reading

No comments:

Post a Comment