|
16 | 16 |
|
17 | 17 | package org.springframework.boot.loader; |
18 | 18 |
|
| 19 | +import java.io.ByteArrayOutputStream; |
19 | 20 | import java.io.IOException; |
| 21 | +import java.io.InputStream; |
20 | 22 | import java.net.JarURLConnection; |
21 | 23 | import java.net.URL; |
22 | 24 | import java.net.URLClassLoader; |
|
38 | 40 | */ |
39 | 41 | public class LaunchedURLClassLoader extends URLClassLoader { |
40 | 42 |
|
| 43 | + private static final int BUFFER_SIZE = 4096; |
| 44 | + |
41 | 45 | static { |
42 | 46 | ClassLoader.registerAsParallelCapable(); |
43 | 47 | } |
@@ -96,7 +100,7 @@ public Enumeration<URL> findResources(String name) throws IOException { |
96 | 100 | protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { |
97 | 101 | if (name.startsWith("org.springframework.boot.loader.jarmode.")) { |
98 | 102 | try { |
99 | | - Class<?> result = findClass(name); |
| 103 | + Class<?> result = loadClassInLaunchedClassLoader(name); |
100 | 104 | if (resolve) { |
101 | 105 | resolveClass(result); |
102 | 106 | } |
@@ -129,6 +133,35 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE |
129 | 133 | } |
130 | 134 | } |
131 | 135 |
|
| 136 | + private Class<?> loadClassInLaunchedClassLoader(String name) throws ClassNotFoundException { |
| 137 | + String internalName = name.replace('.', '/') + ".class"; |
| 138 | + InputStream inputStream = getParent().getResourceAsStream(internalName); |
| 139 | + if (inputStream == null) { |
| 140 | + throw new ClassNotFoundException(name); |
| 141 | + } |
| 142 | + try { |
| 143 | + try { |
| 144 | + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| 145 | + byte[] buffer = new byte[BUFFER_SIZE]; |
| 146 | + int bytesRead = -1; |
| 147 | + while ((bytesRead = inputStream.read(buffer)) != -1) { |
| 148 | + outputStream.write(buffer, 0, bytesRead); |
| 149 | + } |
| 150 | + inputStream.close(); |
| 151 | + byte[] bytes = outputStream.toByteArray(); |
| 152 | + Class<?> definedClass = defineClass(name, bytes, 0, bytes.length); |
| 153 | + definePackageIfNecessary(name); |
| 154 | + return definedClass; |
| 155 | + } |
| 156 | + finally { |
| 157 | + inputStream.close(); |
| 158 | + } |
| 159 | + } |
| 160 | + catch (IOException ex) { |
| 161 | + throw new ClassNotFoundException("Cannot load resource for class [" + name + "]", ex); |
| 162 | + } |
| 163 | + } |
| 164 | + |
132 | 165 | /** |
133 | 166 | * Define a package before a {@code findClass} call is made. This is necessary to |
134 | 167 | * ensure that the appropriate manifest for nested JARs is associated with the |
|
0 commit comments