From 9072f4ffbfb53602e0bed65094b8919ff47d7777 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 12 Oct 2015 08:08:11 -0400 Subject: [PATCH] Support "bogus" windows classpath entries in JarHell. --- .../org/elasticsearch/bootstrap/JarHell.java | 18 +++++++++++++++++- .../elasticsearch/bootstrap/JarHellTests.java | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java index 53652f1be78..3f77f6bcee0 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/JarHell.java @@ -104,7 +104,9 @@ public class JarHell { */ @SuppressForbidden(reason = "resolves against CWD because that is how classpaths work") static URL[] parseClassPath(String classPath) { - String elements[] = classPath.split(System.getProperty("path.separator")); + String pathSeparator = System.getProperty("path.separator"); + String fileSeparator = System.getProperty("file.separator"); + String elements[] = classPath.split(pathSeparator); URL urlElements[] = new URL[elements.length]; for (int i = 0; i < elements.length; i++) { String element = elements[i]; @@ -118,6 +120,20 @@ public class JarHell { if (element.isEmpty()) { throw new IllegalStateException("Classpath should not contain empty elements! (outdated shell script from a previous version?) classpath='" + classPath + "'"); } + // we should be able to just Paths.get() each element, but unfortunately this is not the + // whole story on how classpath parsing works: if you want to know, start at sun.misc.Launcher, + // be sure to stop before you tear out your eyes. we just handle the "alternative" filename + // specification which java seems to allow, explicitly, right here... + if (element.startsWith("/") && "\\".equals(fileSeparator)) { + // "correct" the entry to become a normal entry + // change to correct file separators + element = element.replace("/", "\\"); + // if there is a drive letter, nuke the leading separator + if (element.length() >= 3 && element.charAt(2) == ':') { + element = element.substring(1); + } + } + // now just parse as ordinary file try { urlElements[i] = PathUtils.get(element).toUri().toURL(); } catch (MalformedURLException e) { diff --git a/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java b/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java index 8005b14ebe7..14a66128eda 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java @@ -21,6 +21,7 @@ package org.elasticsearch.bootstrap; import org.elasticsearch.Version; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.test.ESTestCase; import java.io.IOException; @@ -335,4 +336,22 @@ public class JarHellTests extends ESTestCase { assertTrue(expected.getMessage().contains("should not contain empty elements")); } } + + /** + * Make sure a "bogus" windows classpath element is accepted, java's classpath parsing accepts it, + * therefore eclipse OSGI code does it :) + */ + public void testCrazyEclipseClassPathWindows() throws Exception { + assumeTrue("test is designed for windows-like systems only", ";".equals(System.getProperty("path.separator"))); + assumeTrue("test is designed for windows-like systems only", "\\".equals(System.getProperty("file.separator"))); + + URL expected[] = { + PathUtils.get("c:\\element1").toUri().toURL(), + PathUtils.get("c:\\element2").toUri().toURL(), + PathUtils.get("c:\\element3").toUri().toURL(), + PathUtils.get("c:\\element 4").toUri().toURL(), + }; + URL actual[] = JarHell.parseClassPath("c:\\element1;c:\\element2;/c:/element3;/c:/element 4"); + assertArrayEquals(expected, actual); + } }