Merge branch 'jarhell2.0' into 1702090
This commit is contained in:
commit
c663d9b6a5
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.logging.ESLogger;
|
|||
import org.elasticsearch.common.logging.Loggers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.FileVisitResult;
|
||||
|
@ -70,21 +71,43 @@ public class JarHell {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks the current classloader for duplicate classes
|
||||
* Checks the current classpath for duplicate classes
|
||||
* @throws IllegalStateException if jar hell was found
|
||||
*/
|
||||
public static void checkJarHell() throws Exception {
|
||||
ClassLoader loader = JarHell.class.getClassLoader();
|
||||
if (loader instanceof URLClassLoader == false) {
|
||||
return;
|
||||
}
|
||||
ESLogger logger = Loggers.getLogger(JarHell.class);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("java.class.path: {}", System.getProperty("java.class.path"));
|
||||
logger.debug("sun.boot.class.path: {}", System.getProperty("sun.boot.class.path"));
|
||||
logger.debug("classloader urls: {}", Arrays.toString(((URLClassLoader)loader).getURLs()));
|
||||
if (loader instanceof URLClassLoader ) {
|
||||
logger.debug("classloader urls: {}", Arrays.toString(((URLClassLoader)loader).getURLs()));
|
||||
}
|
||||
}
|
||||
checkJarHell(((URLClassLoader) loader).getURLs());
|
||||
checkJarHell(parseClassPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the classpath into a set of URLs
|
||||
*/
|
||||
@SuppressForbidden(reason = "resolves against CWD because that is how classpaths work")
|
||||
public static URL[] parseClassPath() {
|
||||
String elements[] = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
|
||||
URL urlElements[] = new URL[elements.length];
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
String element = elements[i];
|
||||
// empty classpath element behaves like CWD.
|
||||
if (element.isEmpty()) {
|
||||
element = System.getProperty("user.dir");
|
||||
}
|
||||
try {
|
||||
urlElements[i] = PathUtils.get(element).toUri().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
// should not happen, as we use the filesystem API
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return urlElements;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.env.Environment;
|
|||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.AccessMode;
|
||||
import java.nio.file.FileAlreadyExistsException;
|
||||
import java.nio.file.Files;
|
||||
|
@ -133,27 +132,21 @@ final class Security {
|
|||
*/
|
||||
@SuppressForbidden(reason = "proper use of URL")
|
||||
static void setCodebaseProperties() {
|
||||
ClassLoader loader = Security.class.getClassLoader();
|
||||
if (loader instanceof URLClassLoader) {
|
||||
for (URL url : ((URLClassLoader)loader).getURLs()) {
|
||||
for (Map.Entry<Pattern,String> e : SPECIAL_JARS.entrySet()) {
|
||||
if (e.getKey().matcher(url.getPath()).matches()) {
|
||||
String prop = e.getValue();
|
||||
if (System.getProperty(prop) != null) {
|
||||
throw new IllegalStateException("property: " + prop + " is unexpectedly set: " + System.getProperty(prop));
|
||||
}
|
||||
System.setProperty(prop, url.toString());
|
||||
for (URL url : JarHell.parseClassPath()) {
|
||||
for (Map.Entry<Pattern,String> e : SPECIAL_JARS.entrySet()) {
|
||||
if (e.getKey().matcher(url.getPath()).matches()) {
|
||||
String prop = e.getValue();
|
||||
if (System.getProperty(prop) != null) {
|
||||
throw new IllegalStateException("property: " + prop + " is unexpectedly set: " + System.getProperty(prop));
|
||||
}
|
||||
System.setProperty(prop, url.toString());
|
||||
}
|
||||
}
|
||||
for (String prop : SPECIAL_JARS.values()) {
|
||||
if (System.getProperty(prop) == null) {
|
||||
System.setProperty(prop, "file:/dev/null"); // no chance to be interpreted as "all"
|
||||
}
|
||||
}
|
||||
for (String prop : SPECIAL_JARS.values()) {
|
||||
if (System.getProperty(prop) == null) {
|
||||
System.setProperty(prop, "file:/dev/null"); // no chance to be interpreted as "all"
|
||||
}
|
||||
} else {
|
||||
// we could try to parse the classpath or something, but screw it for now.
|
||||
throw new UnsupportedOperationException("Unsupported system classloader type: " + loader.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ import java.io.IOException;
|
|||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
|
@ -315,10 +314,7 @@ public class PluginManager {
|
|||
private void jarHellCheck(Path candidate, boolean isolated) throws IOException {
|
||||
// create list of current jars in classpath
|
||||
final List<URL> jars = new ArrayList<>();
|
||||
ClassLoader loader = PluginManager.class.getClassLoader();
|
||||
if (loader instanceof URLClassLoader) {
|
||||
Collections.addAll(jars, ((URLClassLoader) loader).getURLs());
|
||||
}
|
||||
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
||||
|
||||
// read existing bundles. this does some checks on the installation too.
|
||||
List<Bundle> bundles = PluginsService.getPluginBundles(environment.pluginsFile());
|
||||
|
|
|
@ -47,6 +47,7 @@ import java.nio.file.DirectoryStream;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -331,12 +332,7 @@ public class PluginsService extends AbstractComponent {
|
|||
// pluginmanager does it, but we do it again, in case lusers mess with jar files manually
|
||||
try {
|
||||
final List<URL> jars = new ArrayList<>();
|
||||
ClassLoader parentLoader = getClass().getClassLoader();
|
||||
if (parentLoader instanceof URLClassLoader) {
|
||||
for (URL url : ((URLClassLoader) parentLoader).getURLs()) {
|
||||
jars.add(url);
|
||||
}
|
||||
}
|
||||
jars.addAll(Arrays.asList(JarHell.parseClassPath()));
|
||||
jars.addAll(bundle.urls);
|
||||
JarHell.checkJarHell(jars.toArray(new URL[0]));
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -86,7 +86,7 @@ public class BootstrapForTesting {
|
|||
// initialize paths the same exact way as bootstrap.
|
||||
Permissions perms = new Permissions();
|
||||
// add permissions to everything in classpath
|
||||
for (URL url : ((URLClassLoader)BootstrapForTesting.class.getClassLoader()).getURLs()) {
|
||||
for (URL url : JarHell.parseClassPath()) {
|
||||
Path path = PathUtils.get(url.toURI());
|
||||
// resource itself
|
||||
perms.add(new FilePermission(path.toString(), "read,readlink"));
|
||||
|
|
Loading…
Reference in New Issue