From bb9bdff10f0495d7624f3b4a1a0ca4c65cc45a9e Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Wed, 20 Jun 2018 14:28:35 -0400 Subject: [PATCH] PT #158478912: Add jrt-fs.jar on classpath for fallback in case of JDK >8 --- atom-extensions/atom-spring-boot/build.sh | 18 +++- .../lib/spring-boot-language-client.ts | 2 +- .../gradle/GradleProjectClasspath.java | 67 ++++---------- .../commons/gradle/GradleProjectTest.java | 19 ++-- .../languageserver/java/JavaUtils.java | 89 +++++++++++++++++++ .../ide/vscode/commons/maven/MavenCore.java | 42 +++++---- 6 files changed, 156 insertions(+), 81 deletions(-) create mode 100644 headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java diff --git a/atom-extensions/atom-spring-boot/build.sh b/atom-extensions/atom-spring-boot/build.sh index 725ee72fa..9cedded75 100755 --- a/atom-extensions/atom-spring-boot/build.sh +++ b/atom-extensions/atom-spring-boot/build.sh @@ -2,8 +2,20 @@ set -e set -x workdir=`pwd` -cd ../atom-commons -npm install + +# Cleanup old jars +rm -rf server +mkdir server + +# Build fat jar and copy it over into +cd ../../headless-services/spring-boot-language-server +./build.sh +cp -f target/spring-boot-language-server-*.jar $workdir/server/spring-boot-language-server.jar + +# Installs atom-commons from source rather than npm registry +# cd ../atom-commons +# npm install + cd $workdir npm install -apm link . +npm run build diff --git a/atom-extensions/atom-spring-boot/lib/spring-boot-language-client.ts b/atom-extensions/atom-spring-boot/lib/spring-boot-language-client.ts index 29773b7f6..a9f148f07 100644 --- a/atom-extensions/atom-spring-boot/lib/spring-boot-language-client.ts +++ b/atom-extensions/atom-spring-boot/lib/spring-boot-language-client.ts @@ -51,7 +51,7 @@ export class SpringBootLanguageClient extends JavaProcessLanguageClient { launchVmArgs(jvm: JVM) { let vmargs = [ // '-Xdebug', - // '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=n', + // '-agentlib:jdwp=transport=dt_socket,server=y,address=7999,suspend=y', '-Dorg.slf4j.simpleLogger.logFile=boot-java.log' ]; if (!jvm.isJdk()) { diff --git a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java index 000f5feff..8668eb82c 100644 --- a/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java +++ b/headless-services/commons/commons-gradle/src/main/java/org/springframework/ide/vscode/commons/gradle/GradleProjectClasspath.java @@ -11,14 +11,9 @@ package org.springframework.ide.vscode.commons.gradle; import java.io.File; -import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.gradle.tooling.model.build.BuildEnvironment; @@ -26,16 +21,10 @@ import org.gradle.tooling.model.eclipse.EclipseExternalDependency; import org.gradle.tooling.model.eclipse.EclipseProject; import org.gradle.tooling.model.eclipse.EclipseProjectDependency; import org.gradle.tooling.model.eclipse.EclipseSourceDirectory; -import org.springframework.ide.vscode.commons.jandex.JandexClasspath; -import org.springframework.ide.vscode.commons.jandex.JandexIndex; -import org.springframework.ide.vscode.commons.java.ClasspathData; import org.springframework.ide.vscode.commons.java.IClasspath; -import org.springframework.ide.vscode.commons.java.IJavadocProvider; -import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider; -import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl; +import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath; import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; -import org.springframework.ide.vscode.commons.util.Log; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; @@ -61,26 +50,6 @@ public class GradleProjectClasspath implements IClasspath { this.buildEnvironment = gradle.getModel(projectDir, BuildEnvironment.class); } -// @Override -// protected JandexIndex[] getBaseIndices() { -// return new JandexIndex[] { new JandexIndex(getJreLibs().map(path -> path.toFile()).collect(Collectors.toList()), -// jarFile -> findIndexFile(jarFile), (classpathResource) -> { -// try { -// String javaVersion = getJavaRuntimeMinorVersion(); -// if (javaVersion == null) { -// javaVersion = "8"; -// } -// URL javadocUrl = new URL("https://docs.oracle.com/javase/" + javaVersion + "/docs/api/"); -// return new HtmlJavadocProvider( -// (type) -> SourceUrlProviderFromSourceContainer.JAVADOC_FOLDER_URL_SUPPLIER -// .sourceUrl(javadocUrl, type.getFullyQualifiedName())); -// } catch (MalformedURLException e) { -// Log.log(e); -// return null; -// } -// }) }; -// } - private EclipseProject getRootProject() { EclipseProject root = project; if (root == null) { @@ -99,6 +68,22 @@ public class GradleProjectClasspath implements IClasspath { return ImmutableList.of(); } else { Builder entries = ImmutableList.builder(); + getJreLibs().forEach(path -> { + CPE cpe = CPE.binary(path.toString()); + String javaVersion = JavaUtils.getJavaRuntimeMinorVersion(getJavaRuntimeVersion()); + if (javaVersion == null) { + javaVersion = "8"; + } + String urlStr = "https://docs.oracle.com/javase/" + javaVersion + "/docs/api/"; + try { + cpe.setJavadocContainerUrl(new URL(urlStr)); + } catch (MalformedURLException e) { + log.error("Invalid javadoc URL: " + urlStr, e); + } + cpe.setSystem(true); + entries.add(cpe); + }); + for (EclipseExternalDependency dep : project.getClasspath()) { entries.add(new CPE(Classpath.ENTRY_KIND_BINARY, dep.getFile().getAbsolutePath())); } @@ -148,17 +133,6 @@ public class GradleProjectClasspath implements IClasspath { return System.getProperty(JAVA_RUNTIME_VERSION); } - public String getJavaRuntimeMinorVersion() { - String fullVersion = getJavaRuntimeVersion(); - String[] tokenized = fullVersion.split("\\."); - if (tokenized.length > 1) { - return tokenized[1]; - } else { - Log.log("Cannot determine minor version for the Java Runtime Version: " + fullVersion); - return null; - } - } - private String getJavaHome() { if (buildEnvironment == null) { return System.getProperty(JAVA_HOME); @@ -168,12 +142,7 @@ public class GradleProjectClasspath implements IClasspath { } private Stream getJreLibs() { - String s = System.getProperty(JAVA_BOOT_CLASS_PATH); - return Arrays.stream(s.split(File.pathSeparator)) - .map(strPath -> strPath.replace(System.getProperty(JAVA_HOME), getJavaHome())) - .map(File::new) - .filter(f -> f.canRead()) - .map(f -> f.toPath()); + return JavaUtils.jreLibs(() -> JavaUtils.getJavaRuntimeMinorVersion(getJavaRuntimeVersion()), this::getJavaHome, () -> System.getProperty(JAVA_BOOT_CLASS_PATH)); } @Override diff --git a/headless-services/commons/commons-gradle/src/test/java/org/springframework/ide/vscode/commons/gradle/GradleProjectTest.java b/headless-services/commons/commons-gradle/src/test/java/org/springframework/ide/vscode/commons/gradle/GradleProjectTest.java index ff6927bae..aa709ef05 100644 --- a/headless-services/commons/commons-gradle/src/test/java/org/springframework/ide/vscode/commons/gradle/GradleProjectTest.java +++ b/headless-services/commons/commons-gradle/src/test/java/org/springframework/ide/vscode/commons/gradle/GradleProjectTest.java @@ -17,6 +17,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.springframework.ide.vscode.languageserver.testharness.ClasspathTestUtil.getOutputFolder; import java.io.File; import java.io.FileWriter; @@ -30,18 +31,14 @@ import java.util.Optional; import org.assertj.core.util.Files; import org.junit.Before; import org.junit.Test; +import org.springframework.ide.vscode.commons.java.IClasspathUtil; import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.javadoc.JavaDocProviders; import org.springframework.ide.vscode.commons.languageserver.Sts4LanguageServer; import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver.Listener; -import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE; import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService; import org.springframework.ide.vscode.commons.util.BasicFileObserver; -import static org.springframework.ide.vscode.languageserver.testharness.ClasspathTestUtil.*; - -import com.google.common.collect.ImmutableList; - /** * Tests covering Gradle project data * @@ -80,8 +77,8 @@ public class GradleProjectTest { @Test public void testEclipseGradleProject() throws Exception { GradleJavaProject project = getGradleProject("empty-gradle-project"); - ImmutableList calculatedClassPath = project.getClasspath().getClasspathEntries(); - assertEquals(51, calculatedClassPath.size()); + List nonSystemClasspathEntries = IClasspathUtil.getBinaryRoots(project.getClasspath(), (cpe) -> !cpe.isSystem()); + assertEquals(51, nonSystemClasspathEntries.size()); } @Test @@ -127,8 +124,8 @@ public class GradleProjectTest { GradleJavaProject cachedProject = manager.project(gradleFile); assertNotNull(cachedProject); - ImmutableList calculatedClassPath = cachedProject.getClasspath().getClasspathEntries(); - assertEquals(51, calculatedClassPath.size()); + List nonSystemClasspathEntries = IClasspathUtil.getBinaryRoots(cachedProject.getClasspath(), (cpe) -> !cpe.isSystem()); + assertEquals(51, nonSystemClasspathEntries.size()); fileObserver.notifyFileChanged(gradleFile.toURI().toString()); assertNull(projectChanged[0]); @@ -137,8 +134,8 @@ public class GradleProjectTest { fileObserver.notifyFileChanged(gradleFile.toURI().toString()); assertNotNull(projectChanged[0]); assertEquals(cachedProject, projectChanged[0]); - calculatedClassPath = cachedProject.getClasspath().getClasspathEntries(); - assertEquals(52, calculatedClassPath.size()); + nonSystemClasspathEntries = IClasspathUtil.getBinaryRoots(cachedProject.getClasspath(), (cpe) -> !cpe.isSystem()); + assertEquals(52, nonSystemClasspathEntries.size()); fileObserver.notifyFileDeleted(gradleFile.toURI().toString()); diff --git a/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java new file mode 100644 index 000000000..66e4ad1bc --- /dev/null +++ b/headless-services/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaUtils.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2018 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.languageserver.java; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.stream.Stream; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Supplier; + +/** + * Various Java installation utility methods + * + * @author Alex Boyko + * + */ +public class JavaUtils { + + private static Logger log = LoggerFactory.getLogger(JavaUtils.class); + + /** + * Find JRE libs jars + * + * @param javaMinorVersionSupplier + * @param javaHomeSupplier + * @param bootClasspathSupplier + * @return + */ + public static Stream jreLibs(Supplier javaMinorVersionSupplier, Supplier javaHomeSupplier, Supplier bootClasspathSupplier) { + String versionString = javaMinorVersionSupplier.get(); + try { + int version = versionString == null ? 8 : Integer.valueOf(versionString); + if (version > 8) { + String javaHome = javaHomeSupplier.get(); + if (javaHome != null) { + Path rtPath= Paths.get(javaHome, "lib", "jrt-fs.jar"); + if (Files.exists(rtPath)) { + return Stream.of(rtPath); + } else { + log.error("Cannot find file " + rtPath); + } + } + } else { + String s = bootClasspathSupplier.get(); + if (s != null) { + return Arrays.stream(s.split(File.pathSeparator)).map(File::new).filter(f -> f.canRead()).map(f -> Paths.get(f.toURI())); + } + } + } catch (NumberFormatException e) { + log.error("Cannot extract java minor version number.", e); + } + return Stream.empty(); + } + + /** + * Extracts java version string from full version string, i.e. "8" from 1.8.0_151, "9" from 9.0.1, "10" from 10.0.1 + * + * @param fullVersion + * @return + */ + public static String getJavaRuntimeMinorVersion(String fullVersion) { + String[] tokenized = fullVersion.split("\\."); + if (tokenized[0] == "1") { + if (tokenized.length > 1) { + return tokenized[1]; + } else { + log.error("Cannot determine minor version for the Java Runtime Version: " + fullVersion); + return null; + } + } else { + return tokenized[0]; + } + } + +} diff --git a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java index 1fa5c6e14..fa68242f3 100644 --- a/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java +++ b/headless-services/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java @@ -17,7 +17,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -53,7 +52,9 @@ import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor; import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor; -import org.springframework.ide.vscode.commons.util.Log; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils; /** * Maven Core functionality @@ -76,6 +77,8 @@ public class MavenCore { private static MavenCore defaultInstance = null; + private static Logger log = LoggerFactory.getLogger(MavenCore.class); + private MavenBridge maven; public static MavenCore getDefault() { @@ -227,7 +230,7 @@ public class MavenCore { try { artifact = maven.resolve(artifact, project.getRemoteArtifactRepositories(), request); } catch (MavenException e) { - Log.log(e); + log.error("", e); // Maven 2.x quirk: an artifact always points at the local repo, // regardless whether resolved or not LocalRepositoryManager lrm = session.getLocalRepositoryManager(); @@ -266,8 +269,23 @@ public class MavenCore { } public Stream getJreLibs() throws MavenException { - String s = (String) maven.createExecutionRequest().getSystemProperties().get(JAVA_BOOT_CLASS_PATH); - return s == null ? Stream.empty() : Arrays.stream(s.split(File.pathSeparator)).map(File::new).filter(f -> f.canRead()).map(f -> Paths.get(f.toURI())); + return JavaUtils.jreLibs(this::getJavaRuntimeMinorVersion, () -> { + try { + return maven.createExecutionRequest().getSystemProperties().getProperty(JAVA_HOME); + } catch (MavenException e) { + log.error("Cannot determine java home", e); + return null; + } + }, + () -> { + try { + return (String) maven.createExecutionRequest().getSystemProperties().get(JAVA_BOOT_CLASS_PATH); + } catch (MavenException e) { + log.error("Cannot determine boot classpath", e); + return null; + } + } + ); } public String getJavaRuntimeVersion() throws MavenException { @@ -276,21 +294,11 @@ public class MavenCore { public String getJavaRuntimeMinorVersion() { try { - String fullVersion = getJavaRuntimeVersion(); - String[] tokenized = fullVersion.split("\\."); - if (tokenized.length > 1) { - return tokenized[1]; - } else { - Log.log("Cannot determine minor version for the Java Runtime Version: " + fullVersion); - } + return JavaUtils.getJavaRuntimeMinorVersion(getJavaRuntimeVersion()); } catch (MavenException e) { - Log.log("Cannot determine Java runtime version. Defaulting to version 8", e); + log.error("Cannot determine Java runtime version. Defaulting to version 8", e); } return null; } - private String getJavaHome() throws MavenException { - return maven.createExecutionRequest().getSystemProperties().getProperty(JAVA_HOME); - } - }