-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow AOP proxies to be created using the original ClassLoader #26601
Comments
This is related to the recent #26403 where we were trying to prevent an illegal access warning for defining proxy classes in Boot's RestartClassLoader when the original class lives in the parent ClassLoader. Ironically by not using that recent Looking at it the other way round, when do we have to define the proxy class in the restart loader in such a scenario? Only really when the original class has also been loaded there, so that'd be covered by using I tend to see the restart class loader as a special case here. For general class loaders, we cannot reasonably infer whether the proxy class loader is necessary or the original bean class loader is sufficient. However, for restart class loaders, we should only really use the restart loader if the original bean class has also been loaded there. In all other scenarios, the application's bean class loader is sufficient or even preferable (given the package-private method scenario). We could simply introduce such an indication in the |
Let's assume the following code in
Boot would then override |
Thanks very much, Juergen. This all sounds good to me. In particular, I agree that the restart class loader is a special case here. Our intention would be to implement this fix in DevTools. Doing that by making We also have spring-projects/spring-boot#19010 which I think is another variant of the same problem. In that scenario, the restart class loader was being used to create a proxy that's sub-classing a private class (I mistakenly said package-private in the issue). The super-class is part of Spring Security and was loaded by the app class loader. This causes the proxying attempt to fail with an IllegalAccessError occurs. Applying the same hack to change the class loader fixes this problem too with the proxy now being created using the app class loader. |
Even more elegantly, |
Unfortunately, outside of DevTools, we don't always control the ClassLoader. For example, when an application's launched in your IDE or run via Maven or Gradle, the ClassLoader will be the JVM's system class loader. |
Being at it, could Boot allow for setting up a custom SmartClassLoader in such IDE/Maven/Gradle scenarios even outside of DevTools? With custom user configuration, just in case anyone complains about remaining illegal access warnings in their scenario? It probably will be less of an issue in JDK 16+, actually, since denying illegal access by default there leads to us silently defining the class in the original bean's ClassLoader via |
That's something that I'd quite like us to be able to do, but I haven't had the time to figure out how we could do it in a consistent manner. It would also help in instrumentation scenarios, such as spring-projects/spring-boot#22109, where users would rely on things like Tomcat's |
@jhoeller Would it be possible to make a similar change to |
Indeed, that's pretty much the same case there. Done! |
Thanks! |
Affects: 5.3
There's a problem in Spring Boot's DevTools that's caused by an AOP proxy being created using the restart class loader rather than the class loader of the proxy's target. This causes problem when calling package-private methods on the proxy.
I've hacked together something that overrides the proxy creator to use the target's class loader and it fixes the problem. I'd now like to explore how we could make the solution more robust and I think some Framework changes are required. The override of AbstractAutoProxyCreator.createProxy is only changing the behaviour of a single line:
spring-framework/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java
Line 461 in a9240e0
Rather than using
getProxyClassLoader()
, my override usesbeanClass.getClassLoader()
.The other part of the problem is then configuring the context to use the customized
AnnotationAwareAspectJAutoProxyCreator
. I'm changing the class of its bean definition at the moment. Perhaps there's already a more elegant way to do this?The text was updated successfully, but these errors were encountered: