Our main problem is ClassFileUtils which use CL to invoke defineClass(). In order to do this, you need to setAccessible() those methods which is a no-go for JDK 9+.
There are two approaches that we can take:
1. Use Unsafe to crack open the CL's methods and keep the code as it is
- This is a "safe" way in that we know all will work as it did up to this point
- We cannot be sure when/if/whether Oracle guys wake up one morning and say "Hey, we are removing those Unsafe methods!" (case of Unsafe.defineClass() in EA JDK 11)
2. We can use MethodHandles.Lookup, namely privateLookupIn() to define new classes (branch with simple impl draft)
- This is the intended way, but it has limitations:
- Lookup.defineClass() has no way to specify ProtectionDomain which is something we currently do, we enrich it, so that newly added classes always have "getDeclaredFields()" rights
- In WFLY, proxies built from JDK classes (Map,...) use (top level) CL of the deployment's module
- Hence on undeploy those proxies are tossed away (no leaks)
- We cannot (easily) get such MethodHandle.Lookup from WFLY and if we define those classes on our CL, we have a memory leak
- This also entails change to our API where WFLY hands us over some MethodHandles.Lookup which we can work with
- In WFLY, static modules w/o Weld dependency use (top level) CL of the deployment's module
- Same problem as above
- This approach implies the need for multi-release JAR of at least core-impl artifact (branch with draft)
- Easy to do, nuisance to maintain and test (and bothersome with the current state of IDE support for those JDKs)
Another illegal access issues is usage of JDK's internal BCEL classes.
- We will replace this with optional Maven dependency
- Hence this functionality will only work if user adds that dependency
- This only hinders reporting error lines in bytecode
There might be some changes required in classfilewriter itself which is to be discovered (likely related to https://github.com/jbossas/jboss-classfilewriter/issues/14)
- Newest version uses Unsafe.defineClass() so we need to update to that one for the time being (1.2.2.Final)
Another part of this issue is to ensure we are continuously testing on JDK 9 (or 10, doesn't matter) as well as JDK 8.
- Releases will be tested on JDK 8 + latest fully released JDK (9/10/11)
- All PRs will be tested on JDK 8 + latest fully released JDK (9/10/11)
- In the future with illegal access denied
Goal is to be able to execute all our tests with JDK 9+ with --illegal-access=deny switch.