Skip to content

Commit dc75ca3

Browse files
committed
Avoid capturing TCCL when creating DefaultResourceLoaders
Previously, DefaultResourceLoader instances were created using the default constructor. This causes the resource loader to capture the TCCL that was in place at that time. This can lead to a class loader leak if the resource loader is referenced directly or indirectly from a static field of a class loaded by a different class loader. This commit updates the creation of DefaultResourceLoader instances in main code so that the resource load will use the class loader of the creating class. In almost all cases this will be the same class loader as was the thread context class loader that was being captured so the change in behavior is minimal. Crucially, it will still address the situation where the TCCL was different. Note the DevTools' ApplicationContextResourceLoader has been updated to explicitly use the TCCL. This ensures that it uses the restart class loader which is required for DevTools to function correctly. Fixes gh-20900
1 parent d53be18 commit dc75ca3

File tree

5 files changed

+13
-8
lines changed

5 files changed

+13
-8
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceInitializer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -67,7 +67,8 @@ class DataSourceInitializer {
6767
DataSourceInitializer(DataSource dataSource, DataSourceProperties properties, ResourceLoader resourceLoader) {
6868
this.dataSource = dataSource;
6969
this.properties = properties;
70-
this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();
70+
this.resourceLoader = (resourceLoader != null) ? resourceLoader
71+
: new DefaultResourceLoader(getClass().getClassLoader());
7172
}
7273

7374
/**

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/MustacheResourceTemplateLoader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public class MustacheResourceTemplateLoader implements TemplateLoader, ResourceL
4747

4848
private String charSet = "UTF-8";
4949

50-
private ResourceLoader resourceLoader = new DefaultResourceLoader();
50+
private ResourceLoader resourceLoader = new DefaultResourceLoader(getClass().getClassLoader());
5151

5252
public MustacheResourceTemplateLoader() {
5353
}

spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/ClassLoaderFilesResourcePatternResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -238,6 +238,8 @@ private static class ApplicationContextResourceLoader extends DefaultResourceLoa
238238
private final Supplier<Collection<ProtocolResolver>> protocolResolvers;
239239

240240
ApplicationContextResourceLoader(Supplier<Collection<ProtocolResolver>> protocolResolvers) {
241+
// Use the restart class loader
242+
super(Thread.currentThread().getContextClassLoader());
241243
this.protocolResolvers = protocolResolvers;
242244
}
243245

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/config/ConfigFileApplicationListener.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ private class Loader {
320320
Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
321321
this.environment = environment;
322322
this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
323-
this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();
323+
this.resourceLoader = (resourceLoader != null) ? resourceLoader
324+
: new DefaultResourceLoader(getClass().getClassLoader());
324325
this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
325326
getClass().getClassLoader());
326327
this.patternResolver = new PathMatchingResourcePatternResolver(this.resourceLoader);

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/StringToFileConverter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -33,7 +33,8 @@
3333
*/
3434
class StringToFileConverter implements Converter<String, File> {
3535

36-
private static final ResourceLoader resourceLoader = new DefaultResourceLoader();
36+
private static final ResourceLoader resourceLoader = new DefaultResourceLoader(
37+
StringToFileConverter.class.getClassLoader());
3738

3839
@Override
3940
public File convert(String source) {

0 commit comments

Comments
 (0)