Skip to content
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

ClassUtils.forName fails to load class from ContextTypeMatchClassLoader [SPR-17452] #21984

Closed
spring-issuemaster opened this issue Oct 31, 2018 · 5 comments
Assignees
Milestone

Comments

@spring-issuemaster
Copy link
Collaborator

@spring-issuemaster spring-issuemaster commented Oct 31, 2018

Christoph Empl opened SPR-17452 and commented

#21867 changed the implementation of ClassUtils#forName: classloading is implemented with Class#forName instead of Classloader#loadClass.

 Since this change one of our Spring-components ("ClassA") isn't found as an autowiring candidate for an interface ("InterfaceA") anymore:
Class.forName("ClassA", false, clToUse) 
clToUse: (e.g.)

org.springframework.context.support.ContextTypeMatchClassLoader@34d89c26

Results in: ClassA - its classloader is another instance of  ContextTypeMatchClassLoader: (e.g.)

org.springframework.context.support.ContextTypeMatchClassLoader$ContextOverridingClassLoader@3a2db42b

This classloader has two loaded classes: InterfaceA and ClassA.

In contrast, clToUse.loadClass("ClassA") returns the expected result:
ClassA, its classloader is the parent of clToUse 

 
The affected project uses openjdk 11 (11+28). 

The somehow weird behaviour of Class#forName is already mentioned in #18631 and #7300.

 

 

 


Affects: 5.1.1, 5.1.2

Issue Links:

  • #18631 ClassUtils.forName() performance
  • #21867 ClassUtils could use long form of Class.forName
  • #7300 Class.forName() produces different results to ClassLoader.loadClass() in certain circumstances

Referenced from: commits 5cd525a

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 31, 2018

Juergen Hoeller commented

So Class.forName still has issues even on modern-day JVMs... what a shame, in particular since it is an important enabler on GraalVM.

Are you using load-time weaving there? That's pretty much the only reason to use ContextTypeMatchClassLoader...

I suppose we'll have to differentiate in our ClassUtils.forName implementation, only delegating to ClassUtils.forName for standard ClassLoader arrangements.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Oct 31, 2018

Christoph Empl commented

Yes, i'm using load time weaving.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 5, 2018

Juergen Hoeller commented

We're enforcing the use of ClassLoader.loadClass in case of a temporary ClassLoader now, as well as in case of a dynamically re-resolved class name from a SpEL expression. This will be available in the upcoming 5.1.3.BUILD-SNAPSHOT should hopefully address your regression.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 8, 2018

Christoph Empl commented

With the latest build snapshot the application starts fine and the affected Spring component is correctly identified as an autowiring candidate. Thank you!

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

@spring-issuemaster spring-issuemaster commented Nov 8, 2018

Juergen Hoeller commented

Good to hear :-) Hopefully this is the right balance now... We have yet to see whether other special class loading scenarios are affected as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.