Project

General

Profile

Switching Between Java 8 and Java 17

Introduction

In FWD v3.x, only Java 8 is supported.

Starting in FWD v4, all Java 8, Java 11 and Java 17 are supported. Java 11 support was implemented in #5567, Java 17 support was added in #6692. Except Java 17 support #6692 brought several changes and enhancements that need to be taken into account when moving to FWD 4.

Java 17 upgrade task #6692 there were two main goals:

  • bring Java 17 support to FWD
  • upgrade all possible components FWD depends on to remove security vulnerabilities
  • upgrade gradle

Java 8 stays as main FWD runtime platform, but any project can be upgraded to Java 17 if up to 15% performance degradation is accepted.

Older project configurations were designed to run on Java 8, so nothing needs to be done to keep those configurations on Java 8. If a project wants to support Java 17, then changes to scripts/runtime are needed. The changes may be implemented such that, one can switch only the current Java runtime from Java 8 and Java 17 and back are needed for migration.

Additionally some tweaks to the FWD code have been implemented to make its code compatible with newer Java VM APIs and to remove build warnings (most of).

Note that the JAVA UDF (PL/Java) feature was not tested and is not supported with Java 17.

Performance in Java 17

All other things being equal (same hardware, OS, converted code and configuration), Java 17 is up to 15-20% slower than Java 8 in general. This has been measured in simulations as well as with real converted application code.

Supported Configurations

The following configurations are tested and supported:

  • Build Java 8, Conversion Java 8, Runtime Java 8 - build processes tools and code, conversion and compiled generated/custom code are executed with Java 8 runtime,
  • Build Java 17, Conversion Java 17, Runtime Java 17 - build processes tools and code, conversion and compiled generated/custom code are executed with Java 17 runtime,

Java 9/10, Java 12-16 and Java 18+ have not been tested and are not supported in any way.

Unsupported Configurations

Following configurations are not tested and are not supported.

  • Build Java 8, Conversion Java 8, Runtime Java 17
  • Build Java 8, Conversion Java 17, Runtime Java 17

Updated Dependencies

The following changes were brought by #6692
  • gradle was upgraded to version 7.6.4
  • batik was upgraded to version 1.17
  • bonucycastle libs were upgraded to version jdk15to18-1.69
  • gremlin libs were upgraded to version -3.7.0
  • jetty-all is not using uber-jar anymore and was upgraded to version 9.4.54.v20240208
  • janusgraph was upgraded to 1.0
  • acme4j was removed
  • slf API was upgraded to version 2.0 so fwd-slf4j.jar is not needed anymore

Java 8 to Java 17 Migration Process

Once the java runtime is switched and application fully rebuilt everything should work as before. By "rebuilt" we mean that FWD needs to be recompiled and any converted code needs to be recompiled.

Before this shift is done, some changes may be needed to a given project configuration.

FWD Build Scripts

FWD build scripts (build.xml and build.gradle) detect the Java version runtime and configure environment according to the detected java version, so no changes are needed.

Conversion

Conversion is independent of the Java runtime version. No changes to the conversion process are required. Source files converted/generated with FWD running Java 8 are identical to files generated by FWD running Java 17.

Project Build Scripts

Project-specific (custom) build scripts (mainly build_db.xml) must be updated accordingly to reflect a new way Java 9 and newer supports SPI feature:

  • fwdspi.jar needs to be added to classpath
  • -Djava.ext.dirs= directive must be removed from server java command line
  • -Djava.locale.providers should be now SPI,CLDR,COMPAT instead of SPI,CLDR

Scripts supporting noth Java 8 or Java 17 (and newer) need to detect Java version and act accordingly.

For projects created from the standard project templates like hotel_gui, please check the way Java 17 is detected and supported in build_db.xml.

FWD Server Runtime

FWD server scripts (usually located in deploy/server/server.sh need to be updated to reflect a new way Java 11 (and newer) supports SPI feature:

  • fwdspi.jar needs to be added to classpath
  • -Djava.ext.dirs= directive must be removed from server java command line
  • -Djava.locale.providers should be now SPI,CLDR,COMPAT instead of SPI,CLDR

Scripts supporting both Java 8 and Java 17 (and newer) need to detect Java version and act accordingly.

FWD Client Runtime

For standard installation no update is required for FWD client scripts to run with Java 17.

FWD Spawner Runtime

spawner needs to be rebuilt with Java 17 and reinstalled/redeployed, as spawner binary has hardcoded reference to Java libraries runtime present at compile time.
For the standard installation spawner build script is a part of FWD build script, thus only rebuild and reinstall is necessary.
For other types of installations build scripts need to be updated accordingly.

Opening API

JVM command line parameter --add-opens java.base/java.lang=ALL-UNNAMED needs to be added for any use case there is an java.lang.IllegalAccessError thrown by an application - it seems it most cases it is needed due to way FWD api is used.

In addition in current FWD version Java 17 requires opening java.base APIs when building FWD administration console by adding following lines to JVM arguments in server startup script (e.g. server.sh):

           <jvmarg line="--add-opens"/>
           <jvmarg value="java.base/java.lang=ALL-UNNAMED"/>

Explicit importing of com.goldencode.p2j.persist.Record

As Java 17 defines its own Record type its necessary to explicitly specify that application code needs FWD Record and not java.lang.Record by putting following header into all relevant files:

import com.goldencode.p2j.persist.Record;

Changes to JavaScript dependencies.

Note that due to changed way JS dependencies are managed version string needs to be removed from JS dependencies name. So following changes needs to be implemented:
  • jquery-3.4.1.js reference needs to be renamed to jquery.js

Spawner installation

Note that privileged mode inside ant or gradle is not supported anymore, so installation that requires privileged access needs to be moved to scripts e.g. postinstall.sh like in following install_spawner.sh:

#!/bin/bash

[[ "$fspawn"* != "$HOME"* ]] && [[ $(whoami) != "root" ]] && mysudo="sudo" 

fspawn=/opt/spawner
pwd=$PWD
postbuild=${pwd}/p2j/src/native/postbuild.sh
spawn_prog=${pwd}/p2j/build/native/spawn
p2j_lib=${pwd}/p2j/build/lib

# Use sudo if elevation is required (destination for spawn is outside $HOME and we are *not* root)
sudo install -d /opt/spawner/
sudo chmod gou+rx /opt/ /opt/spawner/

cd p2j
ANT_OPTS="$ANT_OPTS -Xmx4g" 
ant $@ jar native -Dspawn.install.folder=$fspawn -Dsrv.certs=$pwd/deploy/server/srv-certs.store
(cd build/native && $mysudo $postbuild $fspawn $spawn_prog $pwd/deploy/server/srv-certs.store )
$mysudo chmod gou+rx $fspawn
cd ../
ant deploy.prepare

For details please check install_spawner.sh in hotel_gui project.

Simplified Migration Plan

Simplified plan to migrate a project from Java 8 to Java 17:

  1. Development: migrate any custom (software out of FWD project) platform extensions to Java 17.
  2. Install java 17 or Java 17 on build server
  3. Switch build server environment to java 17
  4. Build FWD for Java 17
  5. Build the project for Java 17 with FWD for java 17
  6. Test the project for java 17 with FWD for java 17
  7. Install Java 17 on runtime servers
  8. Install the project built for Java 17 on runtime servers, I'd suggest to install spawner in different directory if quick rollback is needed
  9. Stop app for java 8, run app for Java 17 on runtime servers (with updated spawner directory configuration if needed)

Java 17 Migration Process Q&A and Tips

  • Make sure no old dependecies are in use after the switch, clean deploy/lib directory before building project for Java 17
  • Make sure spawner is also migrated.
  • On Ubuntu Linux 20.04 its possible to switch Java version system wide with sudo update-java-alternatives --set <java_version_string>
  • On Ubuntu Linux 20.04 its possible to check Java version by executing 'ls -l /proc/<pid>/exe' - to make sure correct version of JVM is in use

© 2024 Golden Code Development Corporation. ALL RIGHTS RESERVED.