From 33c80743eac96d9967a6d878288cf51119ab18bc Mon Sep 17 00:00:00 2001 From: Laszlo Kishalmi Date: Mon, 5 Dec 2022 20:11:25 -0800 Subject: [PATCH] Use Project Dictated JVM for Gradle Discovery (#4985) --- .../GradleJavaCompatProblemsProvider.java | 90 ++++++++++++++++--- .../gradle/GradleProjectConnection.java | 61 +++++++------ .../execute/GradleDistributionManager.java | 29 ++---- .../gradle/execute/GradleDaemonExecutor.java | 1 - .../gradle/spi/execute/package-info.java | 35 ++++++++ 5 files changed, 154 insertions(+), 62 deletions(-) create mode 100644 extide/gradle/src/org/netbeans/modules/gradle/spi/execute/package-info.java diff --git a/extide/gradle/src/org/netbeans/modules/gradle/GradleJavaCompatProblemsProvider.java b/extide/gradle/src/org/netbeans/modules/gradle/GradleJavaCompatProblemsProvider.java index 52c7d2e382cc..66711bb0bd0f 100644 --- a/extide/gradle/src/org/netbeans/modules/gradle/GradleJavaCompatProblemsProvider.java +++ b/extide/gradle/src/org/netbeans/modules/gradle/GradleJavaCompatProblemsProvider.java @@ -21,17 +21,23 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; import java.util.Collection; import java.util.Collections; +import java.util.Properties; import org.netbeans.api.project.Project; import org.netbeans.modules.gradle.api.NbGradleProject; import org.netbeans.modules.gradle.api.execute.GradleDistributionManager; import org.netbeans.modules.gradle.api.execute.GradleDistributionManager.GradleDistribution; import org.netbeans.modules.gradle.spi.execute.GradleDistributionProvider; +import org.netbeans.modules.gradle.spi.execute.GradleJavaPlatformProvider; import org.netbeans.spi.project.ProjectServiceProvider; import org.netbeans.spi.project.ui.ProjectProblemsProvider; import static org.netbeans.spi.project.ui.ProjectProblemsProvider.PROP_PROBLEMS; -import org.openide.util.NbBundle; import org.openide.util.NbBundle.Messages; /** @@ -71,26 +77,82 @@ public void removePropertyChangeListener(PropertyChangeListener listener) { "# {1} - Supported Java Version", "# {2} - Required Gradle Version", "# {3} - Forced Gradle Version", - "TXT_JavaVersionMismatch=The IDE is running on Java {0} that is not supported by Gradle {2}.\n" - + "The IDE will attempt to use Gradle {3} to gather the project information.\n\n" - + "Either upgrade your Gradle version on your project or run the IDE on " - + "Java {1} to avoid this problem!" + "TXT_JavaVersionMismatch=The Java version: {0}, that is seletced for the project " + + "is not supported by Gradle {2}." + + "The IDE will attempt to use Gradle {3} to gather the project information.

" + + "Possible solutions:" + + "

" }) @Override public Collection getProblems() { + GradleDistribution dist = getGradleDistribution(); + int javaVersion = getJavaVersion(); + if (!dist.isCompatibleWithJava(javaVersion)) { + GradleDistribution compatDist = GradleDistributionManager.get(dist.getGradleUserHome()).defaultDistribution(); + ProjectProblem problem = ProjectProblem.createWarning( + Bundle.LBL_JavaVersionMismatch(), + Bundle.TXT_JavaVersionMismatch(javaVersion, dist.lastSupportedJava(),dist.getVersion(), compatDist.getVersion())); + return Collections.singleton(problem); + } + return Collections.emptySet(); + } + + private GradleDistribution getGradleDistribution() { + GradleDistribution dist = null; GradleDistributionProvider pvd = project.getLookup().lookup(GradleDistributionProvider.class); if (pvd != null) { - GradleDistribution dist = pvd.getGradleDistribution(); - if ((dist != null) && !dist.isCompatibleWithSystemJava()) { - String javaVersion = System.getProperty("java.specification.version", System.getProperty("java.version")); //NOI18N - GradleDistribution compatDist = GradleDistributionManager.get(dist.getGradleUserHome()).defaultDistribution(); - ProjectProblem problem = ProjectProblem.createWarning( - Bundle.LBL_JavaVersionMismatch(), - Bundle.TXT_JavaVersionMismatch(javaVersion, dist.lastSupportedJava(),dist.getVersion(), compatDist.getVersion())); - return Collections.singleton(problem); + dist = pvd.getGradleDistribution(); + } + return dist != null ? dist : GradleDistributionManager.get().defaultDistribution(); + } + + private int getJavaVersion() { + File javaHome = null; + GradleJavaPlatformProvider pvd = project.getLookup().lookup(GradleJavaPlatformProvider.class); + try { + javaHome = pvd != null ? pvd.getJavaHome() : null; + } catch (FileNotFoundException ex) { + // That's a broken Java Home, other Problem Provider should pick that up + } + + if (javaHome == null) { + String javaVersion = System.getProperty("java.specification.version"); + int dot = javaVersion.indexOf('.'); + if (dot > 0) { + javaVersion = javaVersion.substring(0, dot); } + return Integer.parseInt(javaVersion); + } else { + return getJavaMajorVersion(javaHome); } - return Collections.emptySet(); + } + + private static int getJavaMajorVersion(File javaHome) { + // If anything goes wrong just assume Java 8 + int ret = 8; + + // The release file was introduced in JDK 9 and provided ever since + File release = new File(javaHome, "release"); //NOI18N + if (release.isFile()) { + Properties releasePros = new Properties(); + try (InputStream is = new FileInputStream(release)) { + releasePros.load(is); + } catch (IOException ex) { + + } + String javaVersion = releasePros.getProperty("JAVA_VERSION"); //NOI18N + if ((javaVersion != null) && javaVersion.startsWith("\"") && javaVersion.endsWith("\"")) { + javaVersion = javaVersion.substring(1, javaVersion.indexOf('.')); + try { + ret = Integer.parseInt(javaVersion); + } catch (NumberFormatException ex) { + // Do nothing return empty + } + } + } + return ret; } } diff --git a/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectConnection.java b/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectConnection.java index b0a40c65fa38..d74535dcd98b 100644 --- a/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectConnection.java +++ b/extide/gradle/src/org/netbeans/modules/gradle/GradleProjectConnection.java @@ -19,13 +19,17 @@ package org.netbeans.modules.gradle; import java.io.File; +import java.io.FileNotFoundException; import java.nio.file.Path; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.gradle.tooling.BuildAction; import org.gradle.tooling.BuildActionExecuter; import org.gradle.tooling.BuildLauncher; +import org.gradle.tooling.ConfigurableLauncher; import org.gradle.tooling.GradleConnectionException; import org.gradle.tooling.GradleConnector; import org.gradle.tooling.ModelBuilder; @@ -37,6 +41,7 @@ import org.netbeans.modules.gradle.api.execute.GradleDistributionManager; import org.netbeans.modules.gradle.api.execute.GradleDistributionManager.GradleDistribution; import org.netbeans.modules.gradle.spi.execute.GradleDistributionProvider; +import org.netbeans.modules.gradle.spi.execute.GradleJavaPlatformProvider; import org.netbeans.spi.project.ProjectServiceProvider; import org.openide.filesystems.FileUtil; import org.openide.util.WeakListeners; @@ -48,9 +53,11 @@ @ProjectServiceProvider(service = ProjectConnection.class, projectType = NbGradleProject.GRADLE_PROJECT_TYPE) public final class GradleProjectConnection implements ProjectConnection { + private static final Logger LOG = Logger.getLogger(GradleProjectConnection.class.getName()); + final Project project; ProjectConnection conn; - ProjectConnection compatConn; + final ChangeListener listener = (ChangeEvent e) -> { close(); }; @@ -61,42 +68,42 @@ public GradleProjectConnection(Project project) { @Override public T getModel(Class type) throws GradleConnectionException, IllegalStateException { - return getConnection(true).getModel(type); + return getConnection().getModel(type); } @Override public void getModel(Class type, ResultHandler rh) throws IllegalStateException { - getConnection(true).getModel(type, rh); + getConnection().getModel(type, rh); } @Override public BuildLauncher newBuild() { - return getConnection(false).newBuild(); + return setJavaHome(getConnection().newBuild()); } @Override public TestLauncher newTestLauncher() { - return getConnection(false).newTestLauncher(); + return setJavaHome(getConnection().newTestLauncher()); } @Override public ModelBuilder model(Class type) { - return getConnection(true).model(type); + return setJavaHome(getConnection().model(type)); } @Override public BuildActionExecuter action(BuildAction action) { - return getConnection(true).action(action); + return setJavaHome(getConnection().action(action)); } @Override public BuildActionExecuter.Builder action() { - return getConnection(true).action(); + return getConnection().action(); } @Override public void notifyDaemonsAboutChangedPaths(List list) { - getConnection(false).notifyDaemonsAboutChangedPaths(list); + getConnection().notifyDaemonsAboutChangedPaths(list); } @Override @@ -104,41 +111,44 @@ public synchronized void close() { if (conn != null) { conn.close(); } - if (conn != compatConn) { - compatConn.close(); - } conn = null; - compatConn = null; } synchronized boolean hasConnection() { - return conn != null || compatConn != null; + return conn != null; } - private synchronized ProjectConnection getConnection(boolean compatible) { + private synchronized ProjectConnection getConnection() { if (conn == null) { File projectDir = FileUtil.toFile(project.getProjectDirectory()); - GradleConnector gconn = GradleConnector.newConnector(); GradleDistributionProvider pvd = project.getLookup().lookup(GradleDistributionProvider.class); + if (pvd != null) { pvd.addChangeListener(WeakListeners.change(listener, pvd)); GradleDistribution dist = pvd.getGradleDistribution(); if (dist != null) { conn = createConnection(dist, projectDir); - if (dist.isCompatibleWithSystemJava()) { - compatConn = conn; - } else { - GradleDistribution compatDist = GradleDistributionManager.get(dist.getGradleUserHome()).defaultDistribution(); - compatConn = createConnection(compatDist, projectDir); - } } } if (conn == null) { - conn = gconn.forProjectDirectory(projectDir).connect(); - compatConn = conn; + conn = createConnection(GradleDistributionManager.get().defaultDistribution(), projectDir); } } - return compatible ? compatConn : conn; + return conn; + } + + private > T setJavaHome(T launcher) { + GradleJavaPlatformProvider pvd = project.getLookup().lookup(GradleJavaPlatformProvider.class); + if (pvd != null) { + try { + File javaHome = pvd.getJavaHome(); + launcher.setJavaHome(javaHome); + LOG.log(Level.FINE, "Using JAVA_HOME=''{0}'' for project info load for: {1}", new Object[]{javaHome, project}); + } catch (FileNotFoundException ex) { + LOG.log(Level.WARNING, "JAVA_HOME for project " + project + " not found.", ex); + } + } + return launcher; } private static ProjectConnection createConnection(GradleDistribution dist, File projectDir) { @@ -151,4 +161,5 @@ private static ProjectConnection createConnection(GradleDistribution dist, File } return gconn.forProjectDirectory(projectDir).connect(); } + } diff --git a/extide/gradle/src/org/netbeans/modules/gradle/api/execute/GradleDistributionManager.java b/extide/gradle/src/org/netbeans/modules/gradle/api/execute/GradleDistributionManager.java index 6228015b2f60..28ec81b85ad7 100644 --- a/extide/gradle/src/org/netbeans/modules/gradle/api/execute/GradleDistributionManager.java +++ b/extide/gradle/src/org/netbeans/modules/gradle/api/execute/GradleDistributionManager.java @@ -69,7 +69,6 @@ import org.netbeans.modules.gradle.spi.GradleSettings; import org.openide.awt.Notification; import org.openide.awt.NotificationDisplayer; -import org.openide.util.Exceptions; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; @@ -99,25 +98,8 @@ public final class GradleDistributionManager { GradleVersion.version("7.0"), // JDK-16 GradleVersion.version("7.3"), // JDK-17 GradleVersion.version("7.5"), // JDK-18 + GradleVersion.version("7.6"), // JDK-19 }; - private static final int JAVA_VERSION; - - static { - int ver = 8; - String version = System.getProperty("java.specification.version", System.getProperty("java.version")); //NOI18N - try { - int dot = version.indexOf('.'); - ver = dot > 0 ? Integer.parseInt(version.substring(0, dot)) : Integer.parseInt(version); - if (ver == 1) { - version = version.substring(dot + 1); - dot = version.indexOf('.'); - ver = dot > 0 ? Integer.parseInt(version.substring(0, dot)) : Integer.parseInt(version); - } - } catch (NumberFormatException ex) { - Exceptions.printStackTrace(ex); - } - JAVA_VERSION = ver; - } final File gradleUserHome; @@ -379,7 +361,7 @@ File distributionBaseDir(URI downloadLocation, String version) { return new File(dist.getDistributionDir(), "gradle-" + version); } - + @SuppressWarnings("PackageVisibleInnerClass") static final class GradleVersionRange { public final GradleVersion lowerBound; @@ -528,10 +510,12 @@ public int lastSupportedJava() { * Checks if this Gradle distribution is compatible the NetBeans * runtime JDK. * - * @return true if this version is supported with the runtime JDK. + * @return true. + * @deprecated shall be no reason to be used. */ + @Deprecated public boolean isCompatibleWithSystemJava() { - return isCompatibleWithJava(JAVA_VERSION); + return true; } /** @@ -668,6 +652,7 @@ public Void call() throws Exception { } @Override + @SuppressWarnings("NestedAssignment") public void download(URI uri, File file) throws Exception { URL url = uri.toURL(); URLConnection conn = url.openConnection(); diff --git a/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java index cd10f28c59d6..a16f530139a8 100644 --- a/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java +++ b/extide/gradle/src/org/netbeans/modules/gradle/execute/GradleDaemonExecutor.java @@ -283,7 +283,6 @@ private boolean setPlatformAndEnv(BuildLauncher buildLauncher, GradleJavaPlatfor String javaHome = null; if (platformProvider != null) { try { - buildLauncher.setJavaHome(platformProvider.getJavaHome()); javaHome = platformProvider.getJavaHome().getCanonicalPath(); } catch (IOException ex) { io.getErr().println(Bundle.NO_PLATFORM(ex.getMessage())); diff --git a/extide/gradle/src/org/netbeans/modules/gradle/spi/execute/package-info.java b/extide/gradle/src/org/netbeans/modules/gradle/spi/execute/package-info.java new file mode 100644 index 000000000000..b798cae9b1bf --- /dev/null +++ b/extide/gradle/src/org/netbeans/modules/gradle/spi/execute/package-info.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/** + * If a project needs direct access to Gradle, there is a + * {@link org.gradle.tooling.ProjectConnection} + * can be retrieved from the project's lookup. The returned implementation + * takes account the {@link org.netbeans.modules.gradle.spi.execute.GradleJavaPlatformProvider} and the {@link org.netbeans.modules.gradle.spi.execute.GradleDistributionProvider} + * implementations if they are available in the project lookup. + *
+ *  ProjectConnection connection = project.getLookup().lookup(ProjectConnection.class);
+ *
+ *  connection.newBuild()
+ *    .forTasks("tasks")
+ *    .setStandardOutput(System.out)
+ *    .run();
+ *
+ * 
+ */ +package org.netbeans.modules.gradle.spi.execute;