Proxy creation improvements for JPMS, remove the need for --add-opens in some cases #25132
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Raising as a draft, because this improves only a few places. Hopefully all tests pass and we can add more improvements gradually.
In short, use JPMS compatible MethodHandles.Lookup instead of calling ClassLoader.defineClass by reflection. This approach has some limitations. We need a class to be used as a template (the generated class will have the same classloader and protection domain derived from it). And the generated class must have the same package name as the template class.
For Weld proxies, I decided to generate a class with a different name than Weld requests, because the generated class must be in the same package as the anchor class and Weld requests a different package name for the generated classes. It looks like Weld doesn't care and all worked on my sample app with EJBs.
Ideally, all methods in
ClassGenerator
that I marked as deprecated, will be removed and callers will be refactored to use the non-deprecated methods. The deprecated methods use reflection incompatible with JPMS, the other ones use the JPMS compatible MethodHandles. There are still a lot of places, though, where the deprecated methods are used, so it will take some time.Yet to refactor:
ProxyServicesImpl.classPoolMap
should be moved to a global service rather than be a static field. It must be global becauseProxyServicesImpl
is created for each app deployment, while the classloader where the classes are generated, is shared. So the cache needs to be preserved, otherwise we'd attempt to create a new class that already exists in the classloader.