Skip to content

Commit 6573e24

Browse files
committed
Scan all non null ClassLoaders for config file, close AsyncHttpClient#1345
Motivation: Class::getClassLoader can return null if the Class was loaded by the bootstrap ClassLoader. Modification: Scan all non null ClassLoaders. Result: No more NPE when class was loaded by the bootstrap ClassLoader
1 parent 823cc92 commit 6573e24

File tree

1 file changed

+38
-18
lines changed

1 file changed

+38
-18
lines changed

client/src/main/java/org/asynchttpclient/config/AsyncHttpClientConfigHelper.java

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.IOException;
44
import java.io.InputStream;
5+
import java.util.ArrayList;
6+
import java.util.List;
57
import java.util.Properties;
68
import java.util.concurrent.ConcurrentHashMap;
79

@@ -18,10 +20,8 @@ public static Config getAsyncHttpClientConfig() {
1820
}
1921

2022
/**
21-
* This method invalidates the property caches. So if a system property has
22-
* been changed and the effect of this change is to be seen then call
23-
* reloadProperties() and then getAsyncHttpClientConfig() to get the new
24-
* property values.
23+
* This method invalidates the property caches. So if a system property has been changed and the effect of this change is to be seen then call reloadProperties() and then
24+
* getAsyncHttpClientConfig() to get the new property values.
2525
*/
2626
public static void reloadProperties() {
2727
if (config != null)
@@ -34,30 +34,50 @@ public static class Config {
3434
public static final String CUSTOM_AHC_PROPERTIES = "ahc.properties";
3535

3636
private final ConcurrentHashMap<String, String> propsCache = new ConcurrentHashMap<>();
37-
private final Properties defaultProperties = parsePropertiesFile(DEFAULT_AHC_PROPERTIES);
38-
private volatile Properties customProperties = parsePropertiesFile(CUSTOM_AHC_PROPERTIES);
37+
private final Properties defaultProperties = parsePropertiesFile(DEFAULT_AHC_PROPERTIES, true);
38+
private volatile Properties customProperties = parsePropertiesFile(CUSTOM_AHC_PROPERTIES, false);
3939

4040
public void reload() {
41-
customProperties = parsePropertiesFile(CUSTOM_AHC_PROPERTIES);
41+
customProperties = parsePropertiesFile(CUSTOM_AHC_PROPERTIES, false);
4242
propsCache.clear();
4343
}
4444

45-
private Properties parsePropertiesFile(String file) {
45+
private Properties parsePropertiesFile(String file, boolean required) {
4646
Properties props = new Properties();
47-
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(file)) {
47+
48+
List<ClassLoader> cls = new ArrayList<>();
49+
50+
ClassLoader cl = Thread.currentThread().getContextClassLoader();
51+
if (cl != null) {
52+
cls.add(cl);
53+
}
54+
cl = getClass().getClassLoader();
55+
if (cl != null) {
56+
cls.add(cl);
57+
}
58+
cl = ClassLoader.getSystemClassLoader();
59+
if (cl != null) {
60+
cls.add(cl);
61+
}
62+
63+
InputStream is = null;
64+
for (ClassLoader classLoader : cls) {
65+
is = classLoader.getResourceAsStream(file);
4866
if (is != null) {
67+
break;
68+
}
69+
}
70+
71+
if (is != null) {
72+
try {
4973
props.load(is);
50-
} else {
51-
//Try loading from this class classloader instead, e.g. for OSGi environments.
52-
try(InputStream is2 = this.getClass().getClassLoader().getResourceAsStream(file)) {
53-
if (is2 != null) {
54-
props.load(is2);
55-
}
56-
}
74+
} catch (IOException e) {
75+
throw new IllegalArgumentException("Can't parse config file " + file, e);
5776
}
58-
} catch (IOException e) {
59-
throw new IllegalArgumentException("Can't parse file", e);
77+
} else if (required) {
78+
throw new IllegalArgumentException("Can't locate config file " + file);
6079
}
80+
6181
return props;
6282
}
6383

0 commit comments

Comments
 (0)