Skip to content

Commit 3bbe114

Browse files
committed
fix: handle nested jar class path fallback
Fixes apolloconfig/apollo#5592
1 parent c89320a commit 3bbe114

File tree

2 files changed

+63
-16
lines changed

2 files changed

+63
-16
lines changed

apollo-core/src/main/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtil.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@
1717
package com.ctrip.framework.apollo.core.utils;
1818

1919
import com.google.common.base.Strings;
20-
2120
import org.slf4j.Logger;
2221
import org.slf4j.LoggerFactory;
23-
2422
import java.net.URL;
25-
import java.net.URLDecoder;
23+
import java.nio.file.Paths;
2624

2725
/**
2826
* @author Jason Song(song_s@ctrip.com)
@@ -39,20 +37,11 @@ public class ClassLoaderUtil {
3937
loader = ClassLoader.getSystemClassLoader();
4038
}
4139

40+
String defaultClassPath = System.getProperty("user.dir");
4241
try {
43-
URL url = loader.getResource("");
44-
// get class path
45-
if (url != null) {
46-
classPath = url.getPath();
47-
classPath = URLDecoder.decode(classPath, "utf-8");
48-
}
49-
50-
// 如果是jar包内的,则返回当前路径
51-
if (Strings.isNullOrEmpty(classPath) || classPath.contains(".jar!")) {
52-
classPath = System.getProperty("user.dir");
53-
}
42+
classPath = resolveClassPath(loader, defaultClassPath);
5443
} catch (Throwable ex) {
55-
classPath = System.getProperty("user.dir");
44+
classPath = defaultClassPath;
5645
logger.warn("Failed to locate class path, fallback to user.dir: {}", classPath, ex);
5746
}
5847
}
@@ -65,6 +54,19 @@ public static String getClassPath() {
6554
return classPath;
6655
}
6756

57+
static String resolveClassPath(ClassLoader classLoader, String defaultClassPath) throws Exception {
58+
URL url = classLoader.getResource("");
59+
if (url == null || !"file".equalsIgnoreCase(url.getProtocol())) {
60+
return defaultClassPath;
61+
}
62+
63+
String resolvedClassPath = Paths.get(url.toURI()).toString();
64+
if (Strings.isNullOrEmpty(resolvedClassPath)) {
65+
return defaultClassPath;
66+
}
67+
return resolvedClassPath;
68+
}
69+
6870
public static boolean isClassPresent(String className) {
6971
try {
7072
Class.forName(className);

apollo-core/src/test/java/com/ctrip/framework/apollo/core/utils/ClassLoaderUtilTest.java

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,42 @@
1818

1919
import static org.junit.Assert.*;
2020

21+
import java.net.URL;
22+
import java.net.URLConnection;
23+
import java.net.URLStreamHandler;
24+
import java.nio.file.Files;
25+
import java.nio.file.Path;
2126
import org.junit.Test;
2227

2328
public class ClassLoaderUtilTest {
2429
private static boolean shouldFailInInitialization = false;
30+
2531
@Test
2632
public void testGetClassLoader() {
2733
assertNotNull(ClassLoaderUtil.getLoader());
2834
}
2935

36+
@Test
37+
public void testResolveClassPathWithFileUrl() throws Exception {
38+
Path tempDir = Files.createTempDirectory("apollo class path");
39+
try {
40+
ClassLoader classLoader = classLoaderReturning(tempDir.toUri().toURL());
41+
42+
assertEquals(tempDir.toString(), ClassLoaderUtil.resolveClassPath(classLoader, "fallback"));
43+
} finally {
44+
Files.deleteIfExists(tempDir);
45+
}
46+
}
47+
48+
@Test
49+
public void testResolveClassPathFallsBackForNestedJarUrl() throws Exception {
50+
String fallback = "/tmp/fallback";
51+
URL nestedJarUrl = createUrl("jar:nested:/tmp/apollo-app.jar/!BOOT-INF/classes/!/");
52+
ClassLoader classLoader = classLoaderReturning(nestedJarUrl);
53+
54+
assertEquals(fallback, ClassLoaderUtil.resolveClassPath(classLoader, fallback));
55+
}
56+
3057
@Test
3158
public void testIsClassPresent() {
3259
assertTrue(ClassLoaderUtil.isClassPresent("java.lang.String"));
@@ -50,4 +77,22 @@ public static class ClassWithInitializationError {
5077
}
5178
}
5279
}
53-
}
80+
81+
private ClassLoader classLoaderReturning(URL resource) {
82+
return new ClassLoader(null) {
83+
@Override
84+
public URL getResource(String name) {
85+
return resource;
86+
}
87+
};
88+
}
89+
90+
private URL createUrl(String spec) throws Exception {
91+
return new URL(null, spec, new URLStreamHandler() {
92+
@Override
93+
protected URLConnection openConnection(URL url) {
94+
throw new UnsupportedOperationException();
95+
}
96+
});
97+
}
98+
}

0 commit comments

Comments
 (0)