Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Migrating Java 8 project to Java 11

We have a repository built using Java 8. There are multiple rest services within the repository. We want to migrate to Java 11 and trying to figure out the best way of doing this. We are considering doing module by module. For example changing one service over to Java 11 while the remaining are still Java 8. We are unsure if Maven supports this?

like image 407
Mfswiggs Avatar asked Feb 11 '20 10:02

Mfswiggs


2 Answers

Disclaimer: This is not an answer but just a partial report of my recent experience. Feel free to flag this answer if you feel that it doesn't meet the SO standards.

Does Maven supports this?

Yes, use the compiler plugin 3.8.0/3.8.1

However this migration requires addition care.

Recently we did something like this by migrating from ORACLE JDK 8 to OPENJDK 11. As we have houndreds of repositories with different missions, we faced all kind of problems. Just to cite some that I got here in my e-mail box tagged as [jdk11_migration]:

  • It is quite obvious but I'd like to highlight that in order to migrate from java 8 to 11 we have to meet the requirements from java 9 and 10 as well

  • Some maven plugins like cobertura do not support Java 11 and I guess they will never support it. In some cases, these plugins have reached the abandoned life cycle stage. The solution was looking for alternatives in a case to case manner. For example, we replaced cobertura by Jacoco.

  • rt.jar and tools.jar have been removed! Everything you have explicity refered from them will probably break.

  • some classes which we shouldn't use in java 9 or less now in java 11 no longer exist. I'm talking about to access classes in packages like sun.*, sun.misc etc. The solution is to look for a one-to-one replacement or refactor the code to avoid the usage.

  • Reflection usually is the last bullet to use and, for these cases, in java 9 and above we geta warning messages like:

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by ...
    WARNING: Please consider reporting this to the maintainers of ...
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    

Although it is not exactly a solution, there is a flag to get rid of this warning --illegal-access=permit . This is particulary important when using surefire maven plugin.

  • Java 9 introduced the module system then "now" we have the phenomena of clash of packages. For example, messages like "The package org.w3c.dom is accessible from more than one module: , java.xml" . The solution is to find the source of reduntant inclusion (notably duplicated maven dependences or dependences of dependences) and remove it.

Althought it wasn't a problem for us, I just noted that your repository consists in REST components in majority. Probable you will face ClassNotFound issues regarding some packages like javax.xml.bind which were basically dropped out of java standard edition. You can fix it by including they explictly in your pom.xml.

Luckly you may find good questions & anwswers for each issue you will find in your migration here in SO or over internet. There are some migration guides in the wild which are good start points. Specific issues, like obfuscation and IDE integration, can take a little bit of time, but, at least in my experience, this migration was painless than I have supposed.

like image 52
Duloren Avatar answered Sep 29 '22 00:09

Duloren


My suggestion is to upgrade the entire project. Try to have some Java8 and some Java11 modules can be very difficult. As you already know, starting from Java9 module appears. The answer is very generic, so it's difficult to give a detailed response. I suppose:

  • Your project is managed with maven
  • You have many artefacts (jar)
  • You are using some library or framework (who said Spring?)
  • You are using a Source Version Control (Git or Subversion for example)
  • You have a multi-module project
  • The code you wrote works on Java8 and on Java11 platform

My suggested plan:

  1. Create a branch on your SVC for Java11 project's version and start to work on it.
  2. Create a parent module for common definitions
  3. Upgrade maven plugin and all your library to the latest version. For Maven compiler set the Java11 target (the Java11 is supported only by the latest version of Maven Compiler Plugin).
  4. For each module define the exported packages (and specify which packages are required)
  5. If there are many modules, start with only a few of them and then include the remains.

If it can help you, let have a look at this simple project on github (It target Java11 and it's a multi-module Maven project).

Hope it helps.

like image 30
xcesco Avatar answered Sep 29 '22 00:09

xcesco