From 30f267f7585fbf685cf49c3cff049eeb2b31011b Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 1 Jul 2015 13:26:00 -0400 Subject: [PATCH 1/3] Don't jarhell check system jars --- .../org/elasticsearch/bootstrap/JarHell.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java index fecc370f748..862320954ea 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java @@ -46,6 +46,11 @@ import java.util.jar.Manifest; /** Simple check for duplicate class files across the classpath */ public class JarHell { + /** Simple driver class, can be used eg. from builds. Returns non-zero on jar-hell */ + public static void main(String args[]) throws Exception { + checkJarHell(); + } + /** * Checks the current classloader for duplicate classes * @throws IllegalStateException if jar hell was found @@ -57,9 +62,9 @@ public class JarHell { } 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())); + 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())); } checkJarHell(((URLClassLoader)loader).getURLs()); } @@ -70,14 +75,26 @@ public class JarHell { */ @SuppressForbidden(reason = "needs JarFile for speed, just reading entries") public static void checkJarHell(URL urls[]) throws Exception { + ESLogger logger = Loggers.getLogger(JarHell.class); + // we don't try to be sneaky and use deprecated/internal/not portable stuff + // like sun.boot.class.path, and with jigsaw we don't yet have a way to get + // a "list" at all. So just exclude any elements underneath the java home + String javaHome = System.getProperty("java.home"); final Map clazzes = new HashMap<>(32768); Set seenJars = new HashSet<>(); for (final URL url : urls) { String path = URLDecoder.decode(url.getPath(), "UTF-8"); + // exclude system resources + if (path.startsWith(javaHome)) { + logger.debug("excluding system resource: {}", path); + continue; + } if (path.endsWith(".jar")) { if (!seenJars.add(path)) { + logger.debug("excluding duplicate classpath element: {}", path); continue; // we can't fail because of sheistiness with joda-time } + logger.debug("examining jar: {}", path); try (JarFile file = new JarFile(path)) { Manifest manifest = file.getManifest(); if (manifest != null) { @@ -111,6 +128,7 @@ public class JarHell { } } } else { + logger.debug("examining directory: {}", path); // case for tests: where we have class files in the classpath final Path root = PathUtils.get(url.toURI()); final String sep = root.getFileSystem().getSeparator(); From 41ac191cac5806cf9e90ea84e7a0e909a95c02e9 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 1 Jul 2015 14:06:53 -0400 Subject: [PATCH 2/3] Add java.home to debug logging --- core/src/main/java/org/elasticsearch/bootstrap/JarHell.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java index 862320954ea..dac62415549 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java @@ -80,6 +80,7 @@ public class JarHell { // like sun.boot.class.path, and with jigsaw we don't yet have a way to get // a "list" at all. So just exclude any elements underneath the java home String javaHome = System.getProperty("java.home"); + logger.debug("java.home: {}", javaHome); final Map clazzes = new HashMap<>(32768); Set seenJars = new HashSet<>(); for (final URL url : urls) { From 976ace21e06e44a0bfa9764babee2327bb03e5f0 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 1 Jul 2015 14:29:57 -0400 Subject: [PATCH 3/3] let IDEs have jar hell in tests --- .../org/elasticsearch/bootstrap/BootstrapForTesting.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapForTesting.java b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapForTesting.java index 1fbb1462ac6..e73805ff995 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapForTesting.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapForTesting.java @@ -25,6 +25,7 @@ import org.elasticsearch.bootstrap.ESPolicy; import org.elasticsearch.bootstrap.Security; import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.PathUtils; +import org.elasticsearch.common.logging.Loggers; import java.io.FilePermission; import java.nio.file.Path; @@ -55,7 +56,13 @@ public class BootstrapForTesting { try { JarHell.checkJarHell(); } catch (Exception e) { - throw new RuntimeException("found jar hell in test classpath", e); + if (Boolean.parseBoolean(System.getProperty("tests.maven"))) { + throw new RuntimeException("found jar hell in test classpath", e); + } else { + Loggers.getLogger(BootstrapForTesting.class) + .warn("Your ide or custom test runner has jar hell issues, " + + "you might want to look into that", e); + } } // make sure java.io.tmpdir exists always (in case code uses it in a static initializer)