Fix exploded jar classloader issues
Fix a bug in `ExplodedURLClassLoader` and merge the code into the existing `LaunchedURLClassLoader` class. Also polish a few method names relating to layer support. See gh-19848 See gh-19767
This commit is contained in:
parent
b4229239ab
commit
951d0b0fdf
|
|
@ -164,8 +164,8 @@ public abstract class ExecutableArchiveLauncher extends Launcher {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsNestedJars() {
|
||||
return this.archive.supportsNestedJars();
|
||||
protected boolean isExploded() {
|
||||
return this.archive.isExploded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.loader;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
* {@link URLClassLoader} used for exploded archives.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ExplodedURLClassLoader extends URLClassLoader {
|
||||
|
||||
ExplodedURLClassLoader(URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
try {
|
||||
Class<?> result = findClass(name);
|
||||
if (resolve) {
|
||||
resolveClass(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
}
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -42,17 +42,33 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
|||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
private final boolean exploded;
|
||||
|
||||
/**
|
||||
* Create a new {@link LaunchedURLClassLoader} instance.
|
||||
* @param urls the URLs from which to load classes and resources
|
||||
* @param parent the parent class loader for delegation
|
||||
*/
|
||||
public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
|
||||
this(false, urls, parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link LaunchedURLClassLoader} instance.
|
||||
* @param exploded the the underlying archive is exploded
|
||||
* @param urls the URLs from which to load classes and resources
|
||||
* @param parent the parent class loader for delegation
|
||||
*/
|
||||
public LaunchedURLClassLoader(boolean exploded, URL[] urls, ClassLoader parent) {
|
||||
super(urls, parent);
|
||||
this.exploded = exploded;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL findResource(String name) {
|
||||
if (this.exploded) {
|
||||
return super.findResource(name);
|
||||
}
|
||||
Handler.setUseFastConnectionExceptions(true);
|
||||
try {
|
||||
return super.findResource(name);
|
||||
|
|
@ -64,6 +80,9 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
|||
|
||||
@Override
|
||||
public Enumeration<URL> findResources(String name) throws IOException {
|
||||
if (this.exploded) {
|
||||
return super.findResources(name);
|
||||
}
|
||||
Handler.setUseFastConnectionExceptions(true);
|
||||
try {
|
||||
return new UseFastConnectionExceptionsEnumeration(super.findResources(name));
|
||||
|
|
@ -86,6 +105,9 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
|||
catch (ClassNotFoundException ex) {
|
||||
}
|
||||
}
|
||||
if (this.exploded) {
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
Handler.setUseFastConnectionExceptions(true);
|
||||
try {
|
||||
try {
|
||||
|
|
@ -168,6 +190,9 @@ public class LaunchedURLClassLoader extends URLClassLoader {
|
|||
* Clear URL caches.
|
||||
*/
|
||||
public void clearCache() {
|
||||
if (this.exploded) {
|
||||
return;
|
||||
}
|
||||
for (URL url : getURLs()) {
|
||||
try {
|
||||
URLConnection connection = url.openConnection();
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public abstract class Launcher {
|
|||
* @throws Exception if the application fails to launch
|
||||
*/
|
||||
protected void launch(String[] args) throws Exception {
|
||||
if (supportsNestedJars()) {
|
||||
if (!isExploded()) {
|
||||
JarFile.registerUrlProtocolHandler();
|
||||
}
|
||||
ClassLoader classLoader = createClassLoader(getClassPathArchivesIterator());
|
||||
|
|
@ -94,10 +94,7 @@ public abstract class Launcher {
|
|||
* @throws Exception if the classloader cannot be created
|
||||
*/
|
||||
protected ClassLoader createClassLoader(URL[] urls) throws Exception {
|
||||
if (supportsNestedJars()) {
|
||||
return new LaunchedURLClassLoader(urls, getClass().getClassLoader());
|
||||
}
|
||||
return new ExplodedURLClassLoader(urls, getClass().getClassLoader());
|
||||
return new LaunchedURLClassLoader(isExploded(), urls, getClass().getClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -168,12 +165,12 @@ public abstract class Launcher {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns if the launcher needs to support fully nested JARs. If this method returns
|
||||
* {@code false} then only regular JARs are supported and the additional URL and
|
||||
* ClassLoader support infrastructure will not be installed.
|
||||
* @return if nested JARs are supported
|
||||
* Returns if the launcher is running in an exploded mode. If this method returns
|
||||
* {@code true} then only regular JARs are supported and the additional URL and
|
||||
* ClassLoader support infrastructure can be optimized.
|
||||
* @return if the jar is exploded.
|
||||
*/
|
||||
protected boolean supportsNestedJars() {
|
||||
protected boolean isExploded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,8 +90,12 @@ public interface Archive extends Iterable<Archive.Entry>, AutoCloseable {
|
|||
@Override
|
||||
Iterator<Entry> iterator();
|
||||
|
||||
default boolean supportsNestedJars() {
|
||||
return true;
|
||||
/**
|
||||
* Return if the archive is exploded (already unpacked).
|
||||
* @return if the archive is exploded
|
||||
*/
|
||||
default boolean isExploded() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -114,8 +114,8 @@ public class ExplodedArchive implements Archive {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsNestedJars() {
|
||||
return false;
|
||||
public boolean isExploded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
Loading…
Reference in New Issue