diff options
author | George Fraser <george@fivetran.com> | 2017-11-10 13:57:44 -0800 |
---|---|---|
committer | George Fraser <george@fivetran.com> | 2017-11-10 13:57:44 -0800 |
commit | 9dd69d0c1add5d38e981fd53116270c9f56d1fb6 (patch) | |
tree | d94459d7dbc05c635095d4c6bee3dcef5cf6a760 | |
parent | 92a11c89fba02d0dbe94d2ce2f367622612731a9 (diff) | |
download | java-language-server-9dd69d0c1add5d38e981fd53116270c9f56d1fb6.zip |
Figure out platform classes from java.home
-rw-r--r-- | pom.xml | 8 | ||||
-rw-r--r-- | src/main/java/org/javacs/ClassPathIndex.java | 50 | ||||
-rw-r--r-- | src/test/java/org/javacs/ChildFirstClassLoaderTest.java | 31 | ||||
-rw-r--r-- | src/test/java/org/javacs/ClassPathIndexTest.java | 73 | ||||
-rw-r--r-- | src/test/java/org/javacs/CompletionsTest.java | 16 | ||||
-rw-r--r-- | src/test/test-platforms/jdk8-home/lib/rt.jar | bin | 0 -> 656 bytes | |||
-rw-r--r-- | src/test/test-platforms/jdk9-home/jmods/java.compiler.jmod | bin | 0 -> 111460 bytes |
7 files changed, 126 insertions, 52 deletions
@@ -48,6 +48,12 @@ <groupId>org.eclipse.lsp4j</groupId> <artifactId>org.eclipse.lsp4j</artifactId> <version>0.2.0-SNAPSHOT</version> + <exclusions> + <exclusion> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </exclusion> + </exclusions> </dependency> <!-- JSON --> <dependency> @@ -79,7 +85,7 @@ <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> - <version>18.0</version> + <version>23.4-jre</version> </dependency> <!-- HTML-to-markdown --> <dependency> diff --git a/src/main/java/org/javacs/ClassPathIndex.java b/src/main/java/org/javacs/ClassPathIndex.java index d549e70..89976b3 100644 --- a/src/main/java/org/javacs/ClassPathIndex.java +++ b/src/main/java/org/javacs/ClassPathIndex.java @@ -1,5 +1,6 @@ package org.javacs; +import com.google.common.base.StandardSystemProperty; import com.google.common.reflect.ClassPath; import java.io.IOException; import java.lang.reflect.Constructor; @@ -7,7 +8,9 @@ import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import java.util.Optional; import java.util.Set; @@ -15,7 +18,6 @@ import java.util.function.Predicate; import java.util.logging.Logger; import java.util.stream.Collectors; import java.util.stream.Stream; -import sun.misc.Launcher; /** * Index the classpath *without* using the java compiler API. The classpath can contain problematic @@ -42,8 +44,47 @@ class ClassPathIndex { return Integer.compare(left.getSimpleName().length(), right.getSimpleName().length()); } - public static URLClassLoader parentClassLoader() { - URL[] bootstrap = Launcher.getBootstrapClassPath().getURLs(); + private static URL toUrl(Path path) { + try { + return path.toUri().toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + /** Find all the java 8 platform .jar files */ + static URL[] java8Platform(String javaHome) { + Path rt = Paths.get(javaHome).resolve("lib").resolve("rt.jar"); + + if (Files.exists(rt)) return new URL[] {toUrl(rt)}; + else throw new RuntimeException(rt + " does not exist"); + } + + /** Find all the java 9 platform .jmod files */ + static URL[] java9Platform(String javaHome) { + Path jmods = Paths.get(javaHome).resolve("jmods"); + + try { + return Files.list(jmods) + .filter(path -> path.getFileName().toString().endsWith(".jmod")) + .map(path -> toUrl(path)) + .toArray(URL[]::new); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static boolean isJava9() { + return StandardSystemProperty.JAVA_VERSION.value().equals("9"); + } + + private static URL[] platform() { + if (isJava9()) return java9Platform(StandardSystemProperty.JAVA_HOME.value()); + else return java8Platform(StandardSystemProperty.JAVA_HOME.value()); + } + + static URLClassLoader parentClassLoader() { + URL[] bootstrap = platform(); return new URLClassLoader(bootstrap, null); } @@ -58,8 +99,9 @@ class ClassPathIndex { private static URLClassLoader classLoader(Set<Path> classPath) { URL[] urls = classPath.stream().flatMap(ClassPathIndex::url).toArray(URL[]::new); + URLClassLoader platform = new URLClassLoader(platform(), null); - return new URLClassLoader(urls, parentClassLoader()); + return new URLClassLoader(urls, platform); } private static Stream<URL> url(Path path) { diff --git a/src/test/java/org/javacs/ChildFirstClassLoaderTest.java b/src/test/java/org/javacs/ChildFirstClassLoaderTest.java deleted file mode 100644 index a32574c..0000000 --- a/src/test/java/org/javacs/ChildFirstClassLoaderTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.javacs; - -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; - -import org.junit.Test; - -public class ChildFirstClassLoaderTest { - class ExceptionClassLoader extends ClassLoader { - @Override - protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - throw new RuntimeException("This should never be called"); - } - } - - @Test - public void dontCallParent() throws ClassNotFoundException { - String[] packages = {"org.javacs"}; - ClassLoader childFirst = - ChildFirstClassLoader.fromClassPath( - System.getProperty("java.class.path"), - packages, - new ExceptionClassLoader()); - Class<?> found = childFirst.loadClass("org.javacs.ChildFirstClassLoaderTest"); - assertThat("found ChildFirstClassLoaderTest", found, not(nullValue())); - assertThat( - "reloaded ChildFirstClassLoaderTest", - found, - not(equalTo(ChildFirstClassLoaderTest.class))); - } -} diff --git a/src/test/java/org/javacs/ClassPathIndexTest.java b/src/test/java/org/javacs/ClassPathIndexTest.java new file mode 100644 index 0000000..99a3d4a --- /dev/null +++ b/src/test/java/org/javacs/ClassPathIndexTest.java @@ -0,0 +1,73 @@ +package org.javacs; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.reflect.ClassPath; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Optional; +import org.junit.Test; + +public class ClassPathIndexTest { + + @Test + public void createEmptyLoader() throws ClassNotFoundException { + ClassLoader emptyClassLoader = ClassPathIndex.parentClassLoader(); + + assertThat(emptyClassLoader.loadClass("java.util.ArrayList"), not(nullValue())); + + try { + Class<?> found = emptyClassLoader.loadClass("com.google.common.collect.Lists"); + + fail("Found " + found); + } catch (ClassNotFoundException e) { + // OK + } + } + + @Test + public void java8Platform() throws IOException { + String javaHome = + Paths.get("./src/test/test-platforms/jdk8-home").toAbsolutePath().toString(); + URL[] resources = ClassPathIndex.java8Platform(javaHome); + assertThat( + "found example.jar", + resources, + hasItemInArray(hasToString(containsString("rt.jar")))); + ClassPath classPath = ClassPath.from(new URLClassLoader(resources, null)); + assertThat( + classPath.getTopLevelClasses(), + hasItem(hasProperty("simpleName", equalTo("HelloWorld")))); + } + + @Test + public void java9Platform() throws IOException { + String javaHome = + Paths.get("./src/test/test-platforms/jdk9-home").toAbsolutePath().toString(); + URL[] resources = ClassPathIndex.java9Platform(javaHome); + assertThat( + "found java.compiler.jmod", + resources, + hasItemInArray(hasToString(containsString("java.compiler.jmod")))); + ClassPath classPath = ClassPath.from(new URLClassLoader(resources, null)); + assertThat( + classPath.getTopLevelClasses(), + hasItem(hasProperty("simpleName", equalTo("JavaCompiler")))); + } + + @Test + public void topLevelClasses() { + ClassPathIndex index = new ClassPathIndex(Collections.emptySet()); + Optional<ClassPath.ClassInfo> arrayList = + index.topLevelClasses() + .filter(c -> c.getName().equals("java.util.ArrayList")) + .findFirst(); + assertTrue("java.util.ArrayList is on the classpath", arrayList.isPresent()); + } +} diff --git a/src/test/java/org/javacs/CompletionsTest.java b/src/test/java/org/javacs/CompletionsTest.java index 0bd6ffe..ce1455d 100644 --- a/src/test/java/org/javacs/CompletionsTest.java +++ b/src/test/java/org/javacs/CompletionsTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.*; import com.google.common.collect.Lists; import java.io.IOException; -import java.net.URLClassLoader; import java.util.List; import java.util.Map; import java.util.Set; @@ -542,21 +541,6 @@ public class CompletionsTest extends CompletionsBase { } @Test - public void createEmptyLoader() throws ClassNotFoundException { - URLClassLoader emptyClassLoader = ClassPathIndex.parentClassLoader(); - - assertThat(emptyClassLoader.loadClass("java.util.ArrayList"), not(nullValue())); - - try { - Class<?> found = emptyClassLoader.loadClass("com.google.common.collect.Lists"); - - fail("Found " + found); - } catch (ClassNotFoundException e) { - // OK - } - } - - @Test public void emptyClasspath() throws IOException { String file = "/org/javacs/example/AutocompletePackage.java"; diff --git a/src/test/test-platforms/jdk8-home/lib/rt.jar b/src/test/test-platforms/jdk8-home/lib/rt.jar Binary files differnew file mode 100644 index 0000000..4ed10a9 --- /dev/null +++ b/src/test/test-platforms/jdk8-home/lib/rt.jar diff --git a/src/test/test-platforms/jdk9-home/jmods/java.compiler.jmod b/src/test/test-platforms/jdk9-home/jmods/java.compiler.jmod Binary files differnew file mode 100644 index 0000000..3d13129 --- /dev/null +++ b/src/test/test-platforms/jdk9-home/jmods/java.compiler.jmod |