Document toolboxDocument toolbox

Java 11 Migration

In the following we provide the steps taken in order to migrate the Synapse backend from JDK 8 to JDK 11.

Compile Time Issues

  1. The root pom.xml of the Synapse backend services was updated, in particular the maven-compiler-plugin with now take the new parameter <release>11</release>. The old <source/> and <target/> were removed.

  2. The lib-doi module complained of a duplicated module importing org.w3c.dom.* classes:
    "The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml"
    This was caused by the Xerces library that imported the xml-apis. To solve this the xml-apis artifact was excluded from the xerces-impl dependency:

    <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.12.2</version> <exclusions> <exclusion> <groupId>xml-apis</groupId> <artifactId>xml-apis</artifactId> </exclusion> </exclusions> </dependency>
  3. javax imports were missing (those were removed from the JDK). In particular we needed the javax annotation api that were imported where needed:

    <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
  4. The lib-javadoc module complained of a duplicated module importing com.sun.javadoc.* classes:
    "The package com.sun.javadoc is accessible from more than one module: <unnamed>, jdk.javadoc"
    This was caused by the com.sun tools dependency that was removed. Note that the lib-javadoc uses the old doclet api, that was superseded by jdk.javadoc.doclet. It was not necessary to port the code using the jdk.javadoc.* to the new doclet, but it is deprecated in the JDK 11 and will need to be refactored when we move to a more recent version of the JDK since they will be removed.

Runtime Issues

  1. Several java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter exceptions were noted, in order to solve this the jaxb-api needed to be imported (was removed from the JDK):

    <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency>
  2. The same java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter was also caused by an old version of jjwt. The dependency was updated to the latest version and the code adapted to the changes introduced by the new version.

  3. Noted several Illegal access warnings:

    Guice was updated to the latest version.

Build Changes

  1. The only change needed to run the build against java 11 was to update the docker base image we use to run the build from maven:3-jdk8 to maven:3-amazoncorretto-11. Note that we now use the amazon corretto distribution of the JDK that is the same we use in production.

Test Failures

  1. EvaluationRoundDBOTest and DataAccessNotificationDaoImplTest assertions failed:
    This was caused by a change in the JDK in the Instant.now() implementation that now produces microsecond resolution in JDK11 while it was milliseconds in the past. The SQL timestamp is milliseconds so the test were failing when comparing the data back from the database that was truncated.
    To resolve this the code was adapted to make sure to truncate the Instant to milliseconds:

  2. Failures of ClaimsWithAuthTime class due to changes in the jjwt library, the code was adapted to the new implementation.

  3. Several failures such as: Caused by: javax.net.ssl.SSLProtocolException: Cannot decode named group: x25519:
    This was by far the trickiest issue. The tests were failing only during the jenkins build. Locally the single test class was working properly. Made sure to use the same exact JDK version, connecting to the exact same remote DB instance and tried updated the mysql connector and connections pool library but locally the tests were passing but still failing during the build.
    Realized that there is a subtle difference, when running a single test class locally from the IDE other classes are not taken into account, while the build on jenkins uses the maven surfire plugin that runs the tests in a different context, in particular in the context of the “managers” module. Some classes in the managers must have had some different setup that was messing with the SSL handshake.
    Since the error pointed to an algorithm mismatch somewhere in the code the security providers must have been altered. The culprit was a static initialization in the DockerTokenUtil class:

    This piece of code would remove the default providers globally and replace it with the bouncy castle implementation, since x255519 is an EC then the mismatch was thrown because the Bouncy Castle implementation didn’t match it.
    To solve this the static initializer was removed and instead the KeyPairUtil (that contained various methods to sign and generate tokens) was updated to use the bouncy castle provider (note that the test were passing also with the standard JDK security providers but for historical reasons we left the bouncy castle implementation instead).

  4. The BaseControllerExceptionHandlerAdviceTest was failing due to and old version of the Reflections library. The library was updated to the latest version.

  5. The BeanTest started failing due to the update of the Reflections library, in particular one of the tests was verifying that any supposedly read-only method (e.g. prefixed with get) didn’t have the @*WriteTransaction annotations. The new version of the library picked up more classes than the previous one so we had to add more exclusions to the test (e.g. we have some methods that are prefixed with a get verbiage that do actually need a write transaction).

Deployment changes

  1. The only change was to update the Java version used in the stack builder for the beanstalk cloudformation template from 8 to 11.

Notes

The changes above apply to the Synapse backend only, the deployment was tested successfully in the dev account. Other dependencies didn’t need to be updated. Other projects might need to be updated as needed if they depend on the latest version of Synapse backend code.