Skip to content

Java 9 and higher

Mikle edited this page Feb 13, 2020 · 2 revisions

Java 9+ issues

Once you run your application with WebLaF under Java 9 or later you will most probably see next warning:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.alee.utils.ReflectUtils (file:weblaf-core-x.x.x.jar) to method {method.name}
WARNING: Please consider reporting this to the maintainers of com.alee.utils.ReflectUtils
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

Or a similar one pointing at a different JAR or method.

This warning appears because WebLaF uses Reflection API a lot to access various private/proprietary Java features as it is nearly impossible to have a robust Look and Feel otherwise due to Swing limitations and some bad Sun/Oracle design decisions. Starting from Java 9 - such "unauthorized" access displays a warning like the one shown above.

Java 12+ issues

On top of changes introduced in Java 9 - in Java 12 and later versions some of Reflection APIs were made unavailable and instead of a warning you will most probably get an exception instead.

I've already added workaround for that. It is available within WebLaF v1.2.11 (or any later) release artifacts on both GitHub and Maven. This workaround uses new backward-compatible multi-release JAR feature to provide a separate code implementation for Java 12+ runtime.

Problem is - it is still impossible to fully "fix" these warnings from the library side.

Solution

To avoid getting warnings or errors your application must specify (at JVM launch) which modules specifically should be accessible to other modules through Reflection API. If such permissions are not given or given incorrectly - you will keep encountering warnings or errors pointing at "illegal" reflective access points.

Here is a list of JVM options that can be used with Java 9 and higher to avoid the warnings:

--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.text=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.base/java.net=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/jdk.internal.loader=ALL-UNNAMED
--add-opens java.desktop/javax.swing=ALL-UNNAMED
--add-opens java.desktop/javax.swing.text=ALL-UNNAMED
--add-opens java.desktop/java.awt.font=ALL-UNNAMED
--add-opens java.desktop/java.awt.geom=ALL-UNNAMED
--add-opens java.desktop/java.awt=ALL-UNNAMED
--add-opens java.desktop/java.beans=ALL-UNNAMED
--add-opens java.desktop/javax.swing.table=ALL-UNNAMED
--add-opens java.desktop/com.sun.awt=ALL-UNNAMED
--add-opens java.desktop/sun.awt=ALL-UNNAMED
--add-opens java.desktop/sun.swing=ALL-UNNAMED
--add-opens java.desktop/sun.font=ALL-UNNAMED
--add-opens java.desktop/javax.swing.plaf.basic=ALL-UNNAMED
--add-opens java.desktop/javax.swing.plaf.synth=ALL-UNNAMED
--add-opens java.desktop/com.sun.java.swing.plaf.windows=ALL-UNNAMED
--add-opens java.desktop/com.sun.java.swing.plaf.gtk=ALL-UNNAMED
--add-opens java.desktop/com.apple.laf=ALL-UNNAMED

This should hide the "illegal reflective access" warnings. Note that you cannot use these settings on Java 8 or earlier as it will simply fail at startup, so you will have to have separate startup JVM options for Java 9+ if you want to avoid issues.

Now, once you use these options - you will most probably see a few new warnings. For instance on Windows OS:

WARNING: package com.sun.java.swing.plaf.gtk not in java.desktop
WARNING: package com.apple.laf not in java.desktop

This happens because JVM options listed above are made for cross-platform use and include all different modules accessed by WebLaF which you most probably won't ever have all at once. And JVM simply warns you in that case that some modules you're granting access to do not exist in your application.

These are the modules that are platform-related:

java.desktop/com.sun.java.swing.plaf.windows
java.desktop/com.sun.java.swing.plaf.gtk
java.desktop/com.apple.laf

If you want to completely avoid any warnings - you will need to use a platform-related list of JVM options for your application, basically excluding some of these three.

Although these warnings do not cause any harm and can be ignored, so whether it is worth the extra configuration time to get rid of them or not is completely up to you. If you have different installation setups for different OS versions - it can be really easy to fix, otherwise might not be worth the extra effort.

Also note that some new warnings might appear at some point if you would be accessing your custom components through the styling system because it uses Reflection API to access fields and methods in various classes it uses, including any custom ones. You can block any illegal reflection access to make those cases visible faster by adding next JVM option:

--illegal-access=deny

This will force JVM to throw an exception whenever Reflection API is used illegally anywhere with a full stack trace that can be used to track down the source and add aother JVM option for the module access.

If you would find any JVM modules that I've missed in the list above - I would appreciate if you can post an issue here or contact me directly so I could update the information for other WebLaF users.

Possible future changes?

In a perfect case scenario Reflection wouldn't be needed or at least WebLaF wouldn't access private fields or try to modify any final values, but unfortunately it isn't possible at the moment. So it is very unlikely that Reflection usage will go anywhere, at least in the foreseeable future.

I will do my best to reduce the amount of questionable Reflection usage (some of these changes are coming in v1.3.0 update), but in the current styling implementation it is simply not possible not to use it all. Partially due to being able to provide any settings through XML, partially due to how inconsistent and hard to use Swing UI code is.

There are also some features like native Font that are not available at all without Reflection usage. Some features like various Window settings are also inconsistent between Java versions and are mapped through Reflection in WebLaF.

The list goes on, but you probably got the general idea by now, so I'll stop here.