-
Notifications
You must be signed in to change notification settings - Fork 235
Java 9 and higher
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.
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.
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.
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.
If you found any mistakes or inconsistency in this article, feel that it is lacking explanation or simply want to request an additional wiki article covering some topic:
I will do my best to answer and provide assistance as soon as possible!