Chapter 2
Preparing for Your Migration
What are the most important things to do before starting your migration? In this chapter, we walk you through the recommended sequence of steps and the potential issues you should know about before you roll up your sleeves, fire up some scripts, and take your Java inventory.
Introducing the Three-Phase Migration Process
After you’ve identified your goals, the methodology we suggest for migrating from the Oracle Java Development Kit (JDK) can be broken down into three stages:
1. Discovery. Identify which versions of Java are being used by which applications and on which machines within your organization, including cloud instances. You’ll use this inventory to create a migration plan.
2. Execution. For each machine that requires a Java runtime, install the same version (or versions) of the OpenJDK distribution you choose.
3. Validation. Test your applications to verify that everything works as expected.
The rest of this chapter covers the discovery stage, where a little bit of additional attention can have the biggest impact on shortening your migration time frame and eliminating issues. Chapter 3 walks you through the execution and validation stages.
Making an Inventory of JDKs Currently in Use
The first stage is often the most time-consuming in a JDK migration because of the variety of JDK versions in use. Typically, when a new application is deployed, it uses the latest version of the JDK
at that time and continues to use it even as newer versions of Java are released. This is quite logical, because it has been tested with the deployed version. Assuming the application works without issue, there is no requirement to update its JDK version. An update is required only when security patches and bug fixes are no longer available for the version in use.
Building your inventory
To create a complete JDK usage inventory, you must examine each machine in your estate that runs any Java Virtual Machine (JVM)–based applications. This can be straightforward if you use IT asset management (ITAM) tools to monitor software usage. Many enterprises deploy these tools to ensure that they’re complying with licensing terms and conditions. These tools can quickly produce a report showing which machines have which versions of Java installed.
Even with a report like this, however, producing a definitive inventory of JDKs in use may not be straightforward. For example, many enterprises use standard builds for server and desktop deployments. These may include a Java runtime even where no Java applications will be used.
Many users won’t be using ITAM software, so they’ll need to perform a manual inventory of machines. Tools are available to assist with this. These tools can scan the filesystem of a machine, looking for a Java executable and recording the version string when it’s run. They can also scan the process table to determine whether Java applications are running and which JDK they use. Take care in analyzing these results — applications may be used only when required. If an application isn’t running at the time the process table is being scanned, it won’t be included.
Deciding which JDKs to include
The process of choosing which JDKs to include is similar to one you might follow when dealing with a collection of cords and power adapters for mobile devices. Over time, you build up a collection of different adapters, each applicable to one or more devices. When clearing out your collection, you must determine if each is still required. The same goes for JDKs; you must figure out which ones still have a purpose and which ones don’t match up with anything you still run.
Typically, when a JDK is installed using an automated installer like a Microsoft Software Installer (MSI) file on Windows or a Red Hat Package Manager (RPM) file on Linux, it becomes the default Java runtime. However, some applications may be installed using a bundled JDK that is used only for that application. In such situations, the JDK may be included in the application’s support contract. In many (perhaps most) cases, maintaining that support is desirable and you won’t want to migrate that application. When compiling the inventory, you’ll want to be aware of such applications and, when in doubt, confirm the terms of ongoing JDK support with the application provider.
With the continued trend of moving server applications to the cloud, it’s also necessary to include JDKs used in these environments. Most cloud providers supply and support Java runtimes as part of their platform as a service (PaaS) offering. However, there may be situations where a different JDK is used (for example, to deliver better performance).
It’s becoming increasingly common to use microservice architectures to deploy applications into the cloud. Doing so separates monolithic applications into multiple, loosely coupled services packaged in containers. A container is a fully functional, portable, virtualized computing environment surrounding a service and isolating it from other services. This is a very flexible deployment method, because it eliminates the need to ensure that the correct versions of libraries, frameworks, and runtimes are available where the service is deployed. All dependencies, including the JDK, are bundled into the container. Once again, when creating a JDK inventory, all containers that include a Java runtime should
be added.
Deciding what information to collect about each JDK
For each entry in the inventory, there should be the following fields at a minimum.
» Type: A physical desktop, physical server, cloud instance, and/or container.
» Access details: The credentials needed to access a physical machine or cloud instance via a network connection with sufficient privileges to permit the JDK’s installation. For containers, these details will relate to how the container image is generated. This will probably be via continuous integration/continuous delivery (CI/CD) tooling and should include information enabling you to configure a different JDK for inclusion in the image.
» Operating system (OS): Which OS is in use, plus additional details about it, such as the edition, version, build number, and whether it’s 32 bit or 64 bit. The OS will typically be Windows, macOS, or Linux. For Linux, you should also note the distribution (distro) because it may make a difference in the installation format.
» Automated or manual install: Whether the installation will take place using an installer. If the JDK doesn’t use an installer, this field should also note the location in which the JDK should be manually unpacked.
» JDK version: This field should also include the installed update level, such as JDK 8u202.
At the end of this process, you should have a complete list of all places where the Oracle JDK is located.
For classification purposes, you may want additional fields. Visit www.openjdk-migration.com/inventory-worksheet for a complete worksheet.
If you have a large Java deployment, you’ll be looking for additional resources to assist with the inventory. You can find sample worksheets and a survey to use with application owners at www.openjdk-migration.com/application-owner-survey.
Recognizing the Risks of Older Technologies
Next, you should start thinking about the potential problems that may crop up based on what you found when making your inventory. This section describes some potential issues that you may encounter when migrating applications from the Oracle JDK to OpenJDK distributions. Altogether there are about a dozen possible edge cases to be aware of. It’s unlikely any of these will affect your applications. Almost all relate only to desktop applications that use specific deployment technologies. If your organization is among those still using desktop apps, you’ll want to be aware of these.
Very old versions of Java
Java started life in the mid-’90s and has continued to be developed ever since. Its popularity took off quickly, resulting in people using early versions of the platform to deploy enterprise-wide and mission-critical applications. Most JVM-based applications are replaced or upgraded to a newer version of Java before support for the JDK version expires. However, some applications continue to use very old versions of the Java platform, and that can be a problem.
Through Azul’s Platform Core support, you can continue to receive all scheduled and out-of-bounds updates to JDK 6 and 7, even though Oracle and other distributions have discontinued support.(OpenJDK started with Java SE 7, but a project for Java SE 6 was subsequently created. You can read more about the early days of Java and OpenJDK in Appendix A.)
Versions of Java prior to JDK 6 were never released as open source, so there is no way to provide distributions with backported security patches or bug fixes. The last public update to JDK 5 was in
November 2009 (which was when Sun Microsystems was still developing Java).
Because of Java’s excellent backward compatibility, it’s quite probable that something that runs on JDK 5 (or even earlier versions) will run without issue on JDK 6. However, if you’re still running applications from JDK 1.0 or 1.1, these may not work on JDK 6.
Oracle JDK-specific features
Prior to JDK 11, the Oracle (and Sun Microsystems) JDK included features that were not included in the core OpenJDK project. The following sections cover these features.
JavaFX
JavaFX is a cross-platform graphical user interface (GUI) tool kit for Java. Although it was never included in the Java SE specification or the main OpenJDK project, it was released as a separate open-source project in 2011, called OpenJFX.
If you’re using JavaFX in your applications, you’ll want to use a distribution like Azul that provides OpenJDK builds, including JavaFX libraries. These use the OpenJFX source code and build scripts to provide identical functionality to the JavaFX provided in older (JDK 8, 9, and 10) builds from Oracle.
Migrating JavaFX-based applications from the Oracle JDK to an alternative distribution is very straightforward, provided you use a build with JavaFX libraries. There is no requirement to change
any application code or recompile the application.
Applets
Applets are small applications designed to add interactive content to a web page. Introduced in the mid-’90s, applets ran in web browsers and reached their heyday in the late ’90s — until browsers withdrew support for them due to security concerns. Vulnerabilities became apparent both in applets (backdoor, crosssite scripting, and cross-site request forgery) and in the Java Runtime Environment (JRE) and browser (with attackers being able to track users, perform malicious exploits, and escape from
sandboxes).
Applets should be considered a dead technology for several reasons:
- The Java plug-in, which is necessary to run applets in a browser, was deprecated in Oracle JDK 9 and removed from Oracle JDK 11.
- Even if you’re using Oracle JDK 8 through a Java SE subscription, Oracle ended support for the Java plug-in in March 2019.
- Oracle has left the components required to run applets in Oracle JDK 8, but only for the Windows platform. These components were removed from Linux and macOS in July 2020 (JDK 8u261).
- Due to security and stability implications, no current mainstream browser supports the Netscape Plugin Application Programming Interface (NPAPI), which is necessary to use the browser plug-in. Therefore, it simply isn’t possible to run an applet within most modern browsers, including Google Chrome and Mozilla Firefox. Support for the last legacy browser that still supported the NPAPI (and,thus, the Java plug-in), Microsoft Internet Explorer 11, ended in June 2022. Since the Java plug-in remains closed source, only two options remain for continuing to run applets on a supported JDK:
- Convert the applet from being browser-based to running with a Java Web Start environment.
- Continue using your existing Java plug-in but modify registry entries to direct it to a different Java runtime.
For a migration worksheet on applets, see www.openjdkmigration.com/applets.
Java Web Start
In the early days of Java, internet speeds were very slow. Many people used dial-up connections that would run at a maximum speed of 57 kilobits per second (Kbps). Adding applets to web pages increased the amount of data that needed to be downloaded quite substantially, resulting in a much slower browsing experience.
Part of this problem was that every time a user visited a web page that included an applet, the code for the applet needed to be downloaded, regardless of whether it had changed since the last visit.
The alternative to applets was a full-blown application. Although this meant that the code for the application didn’t need to be downloaded each time it was used, there was no simple way to determine if there was an update. If a user were told an update was available, they would need to manually download and install the application.
Java Web Start aimed to correct such problems by providing the best of both applets and applications through a web-centric application model.
Java Web Start provides a Java Network Launch Protocol (JNLP) client. JSR-56 specifies the JNLP and, at its core, is a JNLP file, which is an Extensible Markup Language (XML) document. The JNLP file describes an application in terms of the resources it requires, such as Java Archive (JAR) files, icons, Java runtime, and so on. All resources are specified as a Uniform Resource Locator (URL), enabling the application to be accessed remotely like an applet (but without using a web browser). Java Web Start caches the resource files on the user’s machine. Each time the application is started, it checks the locally held resources against the remote ones to see if there has been any update. If not, it uses the local files, so no network activity is required. This also enables the application to be used when there is no network connection.
IcedTea-Web
a Web Start included in the Oracle JDK remains closed source, so it isn’t included in standard OpenJDK distributions. For users who need to continue using the Java Web Start functionality, there is an alternative, open-source project called IcedTea-Web.
IcedTea-Web processes JNLP files, as specified by JSR-56, and offers the most commonly used features of Java Web Start. However, it isn’t a drop-in replacement, so an application’s configuration may sometimes require changes to make it work in the same way as the Oracle Java Web Start.
When switching to IcedTea-Web, enable logging so that more detail about any issues will be provided. You can do this through the itw-settings utility included in IcedTea-Web. Alternatively, you can manually edit the deployment.properties file.
These are the most common issues with switching from Java Web Start to IcedTea-Web:
- Custom security certificates: By default, IcedTea-Web assumes that a trusted certificate has signed all JAR files. If the JAR files are self-signed, you must add the certificates to the certificate store. You can configure that using the itw-settings utility.
- Network proxy settings: This can be set manually or use the same settings as browsers using itw-settings.
- Suppressing security checks on manifests: You may need to do this if a signed JAR file’s manifest is missing attributes such as permissions.
- Unsigned JAR files: For applications that use unsigned JAR files, you must modify the deployment.properties file for each user. You should change the deployment.security. level value to ALLOW_UNSIGNED and add the setting deployment.itw.ignorecertissues with a value of True. In addition, you must include the -nosecurity commandline flag when calling javaw.exe.
For a migration worksheet on Java Web Start, go to www.openjdk-migration.com/web-start.
Some Less-Common Considerations
This section lists the furthest corners of edge cases for OpenJDK migration and offers some possible solutions.
Font rendering
Prior to JDK 8, the Oracle JDK used a closed-source font rendering engine called Ductus. OpenJDK provided an open-source equivalent called Pisces. From JDK 11, both the Oracle JDK and OpenJDK use the same engine called Marlin. In most situations, this makes no difference. However, for a font that doesn’t include a bold version, the rendering engine will extrapolate the plain font to bold. On JDK 8, this may appear different when using the Oracle JDK and an OpenJDK distribution.
The only solution to this is to use a font that includes a bold version.
Lucida fonts
Oracle JDK 8 and earlier included a set of default Lucida fonts. These fonts are used if no suitable alternative can be found on the target deployment system. Lucida fonts are commercial fonts and
are not included with a default OpenJDK distribution.
Azul can provide a Commercial Compatibility Kit (CCK), which includes these fonts, if an application requires them.
NTLM authentication
In Oracle JDK 8 update 201, Oracle introduced a new security authentication parameter for Windows NT LAN Manager, jdk.http.ntlm.transparentAuth. By default, this parameter is set to disable, which differs from earlier updates where the value was effectively allHosts. This change may affect applications,
including those deployed with Java Web Start/IcedTea-Web.
You can resolve the issue by modifying the jre/lib/net.properties file in the JDK installation. The value can be set to allHosts, but the recommended setting is trustedHosts.
Stack Overflow provides more detail on configuring trusted hosts for NTLM: https://stackoverflow.com/questions/56840215/ntlm-no-longer-working-with-java-webstart-followinga-java-upgrade.
Custom security configurations
The JDK uses a security sandbox model to limit an application’s access to resources such as files, network connections, and so on. Some applications may require you to modify these settings in order to use custom security certificates and to change resource restrictions.
When migrating from the Oracle JDK, you’ll need to replicate any of these changes for the new JDK installation.
Java Access Bridge
This is a technology that exposes the Java Accessibility API through a Windows-native library, enabling assistive technologies on Windows systems to work with Swing and Abstract Window Toolkit (AWT)–based applications.
When migrating to a build of OpenJDK, you should use the jabswitch command to configure the Java Access Bridge.
Java Control Panel
You can use the Java Control Panel to configure parts of the Java environment, such as security certificates and Java Web Start. OpenJDK doesn’t include it, so it won’t be part of a standard distribution. You can manage certificates manually using the JDK keytool utility, and IcedTea-Web has its own configuration utility, described earlier.
SNMP JMX Gateway is not included in OpenJDK, so it won’t be part of a standard distribution. In the unlikely event that an app requires it, you can use the open-source library SNMP4J as a replacement. Consult the documentation for this library to learn how to install and configure it as an alternative.
Version string incompatibility
Some applications use the version string that the Java runtime provides to determine whether a supported JDK is in use. In the event that an application does rely on a particular version string,
you should contact the application vendor.
Windows registry keys
The Oracle JDK installation for Windows adds registry keys that an application can use to locate the Java runtime. There are three settings, all located in HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Development Kit:
- JavaHome: The full path of the installed JDK.
- MicroVersion: Since JDK 5, this is always zero.
- RuntimeLib: The full path of the Java runtime dynamic link library (DLL).
Azul Zulu Builds of OpenJDK add similar registry settings to ensure compatibility. Other distributions may not.
Handling Third-Party Applications
It’s very common for users to buy applications instead of developing them. This can be very cost effective to not have to develop and maintain bespoke software in-house.
Many such applications that use Java will specify a required version of the JDK and even possibly a minimum version update level. (This is no different from the way other applications specify a minimum version of Windows or Linux.)
The user must source the JDK and make it available to the application. Application providers often state in their documentation that they’ll support the application only if you’re using the correct
JDK. This is sensible for the application developer, because it can help eliminate issues caused by using out-of-date or inappropriate Java runtimes. Because the Oracle JDK has been so ubiquitous in the past, many application providers have stated that only the Oracle JDK will qualify for support. With the recent changes to the Oracle JDK licensing and pricing, however, users are increasingly demanding that they provide support when running on alternative JDKs.
Many application vendors will now provide support so long as the app is running on a Technology Compatibility Kit (TCK)–certified build of OpenJDK. Because they can trust such distributions to be functionally identical to the Oracle JDK, they don’t need to be worried about testing multiple distributions with their applications.
Sometimes an application will state that certain OpenJDK distributions are valid for support but not the one you want to use. In this case, you should contact the application vendor to have them add the distribution you want to use to their list. As long as it’s TCK tested, the vender should have no objection.
In any large organization, where multiple Java applications are in use, applications will have different owners. When planning a successful migration, it’s essential to include all concerned parties — that is, all owners of the applications that must use the new Java runtime.