Why do you need to migrate now?

  • JDK 8 support was ending in 2020, unless you purchase commercial license (1)
  • Improved Security : TLS 1.3 implementation, better SSL-validation, deprecated old ciphers,.. (2)
  • Faster, improved garbage collection
  • Default container-support, like with Docker (3)
  • Extra language features : like ‘var’ keyword, Optional-Stream, extra Stream-methods, handy collection-functions like Lists.of(…),…
  • Safer reflection-operations

How to start

  • Select your JDK version:
    • Every 6 months there will be a new major version of Java. It’s best to choose a version with long time support like Java 11, 14, 17,…
    • There are several commercial providers, but also free and good alternatives like OpenJDK (4)
  • Update your tools:
    • Maven 3.5+, Compiler 3.8+, surefire & failsafe plugins 2.22+
  • Change the version of Java in your project, so add in your pom-file
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>11</java.version>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
  </properties>
  
  • In your IDE change the version of your modules to JDK 11 and change the language level to Java 11. (In IntelliJ : short-cut F4)
  • The ultimate test is to use somewhere in your code the ‘var’-keyword: Recompile, run all the tests and start the application. If everythings works : the migration is a succes
  • As final step it is often needed to update your pipeline or CI/CD:
    • The security-configuration file got moved to the config-folder of your JVM
    • The command-line arguments are now easier, like -XX:+UseContainerSupport is now default (5)

Known problems

  • Java EE modules got removed (6)
    • Exceptions like Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException. Just include:
    <dependency>
      <groupId>com.sun.xml.bind</groupId>
      <artifactId>jaxb-impl</artifactId>
      <version>2.3.2</version>
    </dependency>
    
  • Embedded Postgres database gave some issues and this fixes it. Alternatively you can use Test Containers.
  <dependency>
    <groupId>ru.yandex.qatools.embed</groupId>
    <artifactId>postgresql-embedded</artifactId>
    <scope>test</scope>
    <!-- temp fix for JDK 11 annoying postgress shutdown exceptions, awaiting release new version -->
    <!-- https://github.com/yandex-qatools/postgresql-embedded/issues/153  -->
    <exclusions>
      <exclusion>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.process</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.process</artifactId>
    <version>2.0.5</version>
  </dependency>
  
  • SSL-issues: they were due to more validation by Java 11. This is normally all fixed now.
  • Exceptions where they complain about the byte code version mismatch. Just remember that byte code of Java 8 is version 52 and the byte code of Java 11 is version 55. You probably didn’t rebuild all modules or somewhere there is a wrong Java version declared. The exception is normally very verbose and easy to understand (7)