Skip to content

Commit

Permalink
Use servlet context that can access classloader
Browse files Browse the repository at this point in the history
Update `SpringBootServletInitializer` to use the `ServletContext` that
was provided to the initial `onStartup` call rather than the
one from the `ServletContextEvent`. This allows the `getClassLoader()`
call to complete without throwing an `UnsupportedOperationException`.

Fixes gh-21684
  • Loading branch information
philwebb committed Jun 4, 2020
1 parent 2925326 commit 4d37430
Showing 1 changed file with 37 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,27 +92,9 @@ public void onStartup(ServletContext servletContext) throws ServletException {
// Logger initialization is deferred in case an ordered
// LogServletContextInitializer is being used
this.logger = LogFactory.getLog(getClass());
WebApplicationContext rootAppContext = createRootApplicationContext(servletContext);
if (rootAppContext != null) {
servletContext.addListener(new ContextLoaderListener(rootAppContext) {

@Override
public void contextInitialized(ServletContextEvent event) {
// no-op because the application context is already initialized
}

@Override
public void contextDestroyed(ServletContextEvent event) {
try {
super.contextDestroyed(event);
}
finally {
deregisterJdbcDrivers(event.getServletContext());
}
}

});

WebApplicationContext rootApplicationContext = createRootApplicationContext(servletContext);
if (rootApplicationContext != null) {
servletContext.addListener(new SpringBootContextLoaderListener(rootApplicationContext, servletContext));
}
else {
this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not "
Expand Down Expand Up @@ -212,6 +194,10 @@ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder;
}

/**
* {@link ApplicationListener} to trigger
* {@link ConfigurableWebEnvironment#initPropertySources(ServletContext, javax.servlet.ServletConfig)}.
*/
private static final class WebEnvironmentPropertySourceInitializer
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {

Expand All @@ -236,4 +222,34 @@ public int getOrder() {

}

/**
* {@link ContextLoaderListener} for the initialized context.
*/
private class SpringBootContextLoaderListener extends ContextLoaderListener {

private final ServletContext servletContext;

SpringBootContextLoaderListener(WebApplicationContext applicationContext, ServletContext servletContext) {
super(applicationContext);
this.servletContext = servletContext;
}

@Override
public void contextInitialized(ServletContextEvent event) {
// no-op because the application context is already initialized
}

@Override
public void contextDestroyed(ServletContextEvent event) {
try {
super.contextDestroyed(event);
}
finally {
// Use original context so that the classloader can be accessed
deregisterJdbcDrivers(this.servletContext);
}
}

}

}

0 comments on commit 4d37430

Please sign in to comment.