We're finally getting close to official word that JDK 11 is fully supported. These are steps you can take in advance.
Introduction
As of yet, there has been no official word that JDK 11 is supported by the Liferay developer tools. Just like the old delays going from JDK 7 to JDK 8, various third party tools and libraries held up the switch to JDK 11.
Up until now, some developers had luck using JDK 11, but there were lingering issues with some tools such as Service Builder which could get in the way.
In fact, my general recommendation has been to just stay with JDK 8 until the dev tools were all declared compatible with JDK 11. And that day is just around the corner, so let's see what will be necessary for using JDK 11 on an existing workspace.
I have a current Liferay 7.2 workspace that contains some themes and some modules, everything currently works fine under a JDK 8 build and it is about to be moved to a JDK 11 build.
There's two basic steps that need to be taken.
- Update the Gradle version to at least 6.6.1
- Update the Liferay Workspace plugin to at least 3.4.2
- Update Service Builder -service module build.gradle files
Before making any changes, I made sure that I had some kind of backup. My workspace is in Git, so I'm good; I even made a custom branch so I could isolate my changes for JDK 11. If you're not using revision control (yet), a tarball of the workspace is a decent alternative.
I also cleaned out all legacy build artifacts. A gradlew clean command will do it, I used git clean -fdx as an alternative.
The goal here is to clean any remnants of a JDK 8 build. We want to ensure that we will be using JDK 11 fully after we apply these updates.
Updating Gradle
This is pretty easy. In the root of our workspace, we need to edit the gradle/wrapper/gradle-wrapper.properties file.
Change the value for the distributionUrl so it refers to 6.6.1 instead of what it currently says (unless you're at a later version already). My file now reads:
#Thu Jun 11 16:44:41 EDT 2020 distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME
With this change done, on the next gradlew command you enter, the 6.6.1 version will be downloaded and used for the build going forward.
I tried issuing a simple command, gradlew tasks, and it downloaded 6.6.1, but then I got a subsequent error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':modules:channels-servlet'.
> Failed to apply plugin class 'com.liferay.gradle.plugins.node.NodePlugin'.
> Could not create plugin of type 'NodePlugin'.
> Could not generate a decorated class for type NodePlugin.
> org/gradle/api/internal/plugins/osgi/OsgiHelper
Since I'm only part way through the necessary changes, I wasn't surprised by the error and new I needed to go on to the next step.
Updating the Liferay Workspace Plugin
This is pretty easy too. In the root of our workspace, we need to edit the settings.gradle file to change the plugin version.
Change the version for the com.liferay.gradle.plugins.workspace to 3.4.2 unless you already have a later version. My file now reads:
buildscript {
dependencies {
classpath group: "com.liferay", name: "com.liferay.gradle.plugins.workspace", version: "3.4.2"
classpath group: "net.saliman", name: "gradle-properties-plugin", version: "1.4.6"
}
repositories {
maven {
url "https://repository-cdn.liferay.com/nexus/content/groups/public"
}
}
}
apply plugin: "net.saliman.properties"
apply plugin: "com.liferay.workspace"
Now I've implemented all of the changes, but I still need to test it out.
ServiceBuilder -service Module build.gradle Updates
If you have an older workspace, the build.gradle file in the -service module for SB need an addition. Add the following stanza to the file:
tasks.withType(JavaCompile) {
// Generated classes using Jodd library are unable to be read when compiled against JDK 11
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
This is only necessary in the -service module, you don't need to add this to the -api module or any other.
Update: IllegalArgumentException from Jodd...
So today I needed to recompile a workspace under JDK-11. I changed my JDK and did a gw clean build to ensure everything was ready for 11. No compile errors, so I was good to go.
Deployed this to my Liferay 7.2 bundle and started it up under JDK-11 and started my testing.
My remote SB services were failing. No idea why until I ramped up debug logging on com.liferay.portal.jsonwebservice package, then I started to see that I was, for some unknown reason, getting IllegalArgumentExceptions stemming from Jodd, a package Liferay uses for reflection help.
Since I saw Jodd in the stack trace (sorry, I didn't keep it to add here), I figured it was going to be a java version issue, but it was actually a bit trickier...
Some of my remote SB services were working fine, but not all of them. Any service method which included a ServiceContext parameter was failing.
I checked my build.gradle file for the -service module and, sure enough, it didn't have the snippet above to force JDK-8 for compile. I added it and tried to compile, but it complained because the -api module was compiled under 11 and it didn't like the mismatch. I added the JDK-8 snippet to the build.gradle for the -api module and both were happy again.
So still using JDK-11, my -service and -api modules are targeting JDK-8 via the snippet above, when these modules are deployed to Liferay running under JDK-11, the services started working again.
So if you're testing something and you get a stack trace and you notice Jodd is seemingly at the source of the exception, you're going to need to add the above snippet so the code will be JDK-8 compatible; that should fix up your runtime.
Test, Test, Test
Yes, we want to test the builds, Service Builder if we're using it, Theme building, the whole nine yards.
Missing liferay.workspace.product
The first thing I noticed is a message notifying me that I don't have the property liferay.workspace.product set in gradle.properties. I didn't need that property before, so I had no reason to have it.
Since my workspace is for Liferay 7.2 DXP, I added the following line to my gradle.properties file:
liferay.workspace.product=dxp-7.2-sp3
I got this value using the blade init -l command to list valid versions. If the one you are using is missing, try blade init -L to get the full list of supported values.
With this set, the specific warning went away, but as I had other properties set in gradle.properties, I received a number of notes that I was overriding values from the workspace product value. I solved this by commenting out those other properties.
ReflectionUtil Illegal Reflective Access
Next, for (re-)building the services, I received the following error:
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.liferay.petra.reflect.ReflectionUtil (file:.gradle/caches/modules-2/files-2.1/com.liferay/ com.liferay.portal.tools.service.builder/1.0.375/ 3b92444a4554540ab05e8ce15925331b32ece9dc/ com.liferay.portal.tools.service.builder-1.0.375.jar) to method java.lang.Object.clone() WARNING: Please consider reporting this to the maintainers of com.liferay.petra.reflect.ReflectionUtil 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
I checked with Liferay and found that this error started after the release of JDK 9 and at this point it is only a warning. Support for this may be deprecated in a future JDK release, but it is not an immediate concern. This warning is a warning only, and will not affect the build.
You'll also see this message when you start the bundle under JDK 11, you can safely ignore that one too.
Removal of JAX-WS
Next I ran into a JDK 11 issue. One of my modules includes javax.xml.soap classes and those were removed finally from JDK 11. Well, it was removed from the JDK, but not removed as a dependency in my module. I solved this by adding compile 'com.sun.xml.ws:jaxws-ri:2.3.2' as a dependency in the build.gradle file.
The rest of my build, including themes and other modules, worked without issue.
Deployment
To prepare my bundle for JDK 11, I deleted the osgi/state directory. No one told me this was necessary, I just did it to ensure I didn't have any serialized classes there that a different JDK might have problems with.
During startup and shutdown using the shell scripts, I did see a new message:
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
This is an artifact of using JDKs 10 or later with Tomcat. Tomcat sets these values in the catalina.sh script, and the JVM will log that they are used. Tomcat sets these to maintain functionality under the newer JVMs. According to the Tomcat mailing lists, this is what it is and they offer no way to remove this note.
Otherwise deployment and testing went very well. I exercised each portlet, checked for each modification, verified that all was working well.
Conclusion
Following these steps I was able to get my environment to build under JDK 11.
Give these instructions a try in your environment and, if you have any problems, let us know.
And remember, if you're totally stopped from building, you should still have that backup we took earlier so you can revert back to JDK 8 until the problems can be resolved.
Update 1
Daniel Yee from the community and reached out with a problem he faced when trying to update to JDK 11:
I tried updating my workspace and got a handshake error. The gradle wrapper downloaded correctly, but after changing the workspace version, I get the error.Reverting back to the previous Gradle and workspace versions allows it to work again.Have you run into this issue before?
Could not resolve all artifacts for configuration 'classpath'.
Could not resolve com.liferay:com.liferay.gradle.plugins.workspace:3.4.2.
Required by:
unspecified:unspecified:unspecified
> Could not resolve com.liferay:com.liferay.gradle.plugins.workspace:3.4.2.
> Could not get resource '<a target="_blank" data-stringify-link="https://repository-cdn.liferay.com/nexus/content/groups/public/com/liferay/com.liferay.gradle.plugins.workspace/3.4.2/com.liferay.gradle.plugins.workspace-3.4.2.pom"
delay="150" data-sk="tooltip_parent" rel="noopener noreferrer"
href="https://repository-cdn.liferay.com/nexus/content/groups/public/com/liferay/com.liferay.gradle.plugins.workspace/3.4.2/com.liferay.gradle.plugins.workspace-3.4.2.pom">
https://repository-cdn.liferay.com/nexus/content/groups/public/com/liferay/com.liferay.gradle.plugins.workspace/3.4.2/com.liferay.gradle.plugins.workspace-3.4.2.pom</a>'.
This ended up being a CDN issue. By adding the following repository reference to the settings.gradle file, the artifacts were able to resolve:
maven {
url "http://repository.liferay.com/nexus/content/groups/public"
}
Update 2
I added a section above talking about an IllegalArgumentException I was getting with Jodd. Basically if you see Jodd in your stack trace, you're likely going to need to add the JDK-8 compatibility snippet to your build.gradle to make the exceptions go away.

