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

ConfigFileApplicationListener#loadPostProcessors can not load EnvironmentPostProcessor in child classLoader #26126

Closed
ChenKangQiang opened this issue Apr 15, 2021 · 4 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@ChenKangQiang
Copy link

My spring-boot version is 2.3.3.RELEASE. I want use spring.factories to load EnvironmentPostProcessor.
In my project, I haven a parent-child classLoader structure. ConfigFileApplicationListener.class is loaded by parent classLoader, and my environmentPostProcessorImpl is in child classloader path. The source code show that ConfigFileApplicationListener use its classloader to load EnvironmentPostProcessor. So,it can not load.
image
With Java SPI,it use ThreadContextClassLoader to load implementation class. Why Spring do not use ThreadContextClassLoader? Or is there any other solutions.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 15, 2021
@snicoll
Copy link
Member

snicoll commented Apr 15, 2021

@ChenKangQiang I don't really understand what you're doing or why the child context is necessary. An application has a designated ClassLoader and loads its resources from it. If you create a child ClassLoader, the app classloader is not supposed to have access to that. These are general principles that are not linked to Spring Boot.

If you want support, you need to share more about your setup in the form of a small sample that shows the issue. You can do so by attaching a zip to this issue or sharing a GitHub repo url. Thanks.

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Apr 15, 2021
@ChenKangQiang
Copy link
Author

@snicoll We design such a structure,be similar to Tomcat,but follow the parental delegation mechanism.
image

We use a SharedClassLoader to load shared spring class in order to reduce jvm matespace,and FunctionClassLoader to load function. We use different thread to load every function,and every function has own ApplicationContext with different beans. so, every function has its own spring.factories.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Apr 15, 2021
@wilkinsona
Copy link
Member

SpringApplication loads all ApplicationListeners, including ConfigFileApplicationListener, via spring.factories using its resource loader's class loader. If it has no resource loader, it'll use ClassUtils.getDefaultClassLoader() which is typically the thread context class loader. ConfigFileApplicationListener then uses its own ClassLoader to load EnvironmentPostProcessors. This feels a bit inconsistent to me, although using getClass().getClassLoader() is a common pattern with SpringFactoriesLoader elsewhere in Spring Boot and in other projects including Spring Framework.

For this specific instance, we could make ConfigFileApplicationListener ApplicationContextAware and use the application context's class loader, but that won't help with calls made elsewhere in Spring Boot or by other projects. I think we'll have to discuss this one as a team to figure out what, if anything, we want to do and when we should do it.

@wilkinsona wilkinsona added the for: team-meeting An issue we'd like to discuss as a team to make progress label Apr 15, 2021
@ChenKangQiang
Copy link
Author

@wilkinsona Thank you, we look forward to the results of your discussion.

@philwebb philwebb added type: bug A general bug and removed for: team-meeting An issue we'd like to discuss as a team to make progress status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged labels Apr 16, 2021
@philwebb philwebb added this to the 2.5.x milestone Apr 16, 2021
@wilkinsona wilkinsona self-assigned this May 13, 2021
@wilkinsona wilkinsona modified the milestones: 2.5.x, 2.5.0 May 13, 2021
jaminh pushed a commit to jaminh/spring-boot that referenced this issue May 28, 2021
Previously, classes involved in config loading used a variety of
potentially different class loaders when calling SpringFactoriesLoader.
Some classes would use their own class loader and others would use null
which results in SpringFactoriesLoader's class loader being used.

This commit updates the config loading classes to consistently use the
resource loader's class loader.

Fixes spring-projectsgh-26126
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants