IDEA-190592 Gradle debug doesn't work on JDK9 and JDK10
authorVladislav.Soroka <Vladislav.Soroka@jetbrains.com>
Thu, 19 Apr 2018 17:01:46 +0000 (20:01 +0300)
committerVladislav.Soroka <Vladislav.Soroka@jetbrains.com>
Thu, 19 Apr 2018 17:02:14 +0000 (20:02 +0300)
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java
platform/external-system-rt/src/com/intellij/openapi/externalSystem/rt/execution/ForkedDebuggerConfiguration.java [new file with mode: 0644]
platform/external-system-rt/src/com/intellij/openapi/externalSystem/rt/execution/ForkedDebuggerHelper.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java

index 38668c748cf8cdc943ccc443245786f84984be96..6cb8531d88594872f03e9ec663fa989e0ade8bd8 100644 (file)
@@ -63,7 +63,6 @@ import com.intellij.openapi.vfs.VfsUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.util.ArrayUtil;
-import com.intellij.util.PlatformUtils;
 import com.intellij.util.SmartList;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.net.NetUtils;
@@ -84,6 +83,8 @@ import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.util.List;
 
+import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM;
+import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_SETUP_PREFIX;
 import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.convert;
 import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getConsoleManagerFor;
 
@@ -95,7 +96,6 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
                                                                                           SMRunnerConsolePropertiesProvider {
   public static final Key<InputStream> RUN_INPUT_KEY = Key.create("RUN_INPUT_KEY");
   public static final Key<Class<? extends BuildProgressListener>> PROGRESS_LISTENER_KEY = Key.create("PROGRESS_LISTENER_KEY");
-  public static final String DEBUG_SETUP_PREFIX = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=";
 
   private static final Logger LOG = Logger.getInstance(ExternalSystemRunConfiguration.class);
   private ExternalSystemTaskExecutionSettings mySettings = new ExternalSystemTaskExecutionSettings();
@@ -463,7 +463,7 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i
       if (myDebugPort > 0) {
         jvmAgentSetup = DEBUG_SETUP_PREFIX + myDebugPort;
         if (getForkSocket() != null) {
-          jvmAgentSetup += " -forkSocket" + getForkSocket().getLocalPort();
+          jvmAgentSetup += (" " + DEBUG_FORK_SOCKET_PARAM + getForkSocket().getLocalPort());
         }
       }
       else {
diff --git a/platform/external-system-rt/src/com/intellij/openapi/externalSystem/rt/execution/ForkedDebuggerConfiguration.java b/platform/external-system-rt/src/com/intellij/openapi/externalSystem/rt/execution/ForkedDebuggerConfiguration.java
new file mode 100644 (file)
index 0000000..c9bfac4
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.openapi.externalSystem.rt.execution;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Vladislav.Soroka
+ */
+public class ForkedDebuggerConfiguration {
+  private final int myForkSocketPort;
+  private final int myDebugPort;
+
+  private ForkedDebuggerConfiguration(int forkSocketPort, int debugPort) {
+    this.myForkSocketPort = forkSocketPort;
+    this.myDebugPort = debugPort;
+  }
+
+  public int getForkSocketPort() {
+    return myForkSocketPort;
+  }
+
+  public int getDebugPort() {
+    return myDebugPort;
+  }
+
+  @Nullable
+  public static ForkedDebuggerConfiguration parse(@Nullable String jvmAgentSetup) {
+    if (jvmAgentSetup != null && jvmAgentSetup.startsWith(ForkedDebuggerHelper.DEBUG_SETUP_PREFIX)) {
+      int forkSocketIndex = jvmAgentSetup.indexOf(ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM);
+      if (forkSocketIndex > 0) {
+        try {
+          int forkSocketPort =
+            Integer.parseInt(jvmAgentSetup.substring(forkSocketIndex + ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM.length()));
+          int debugPort = Integer.parseInt(jvmAgentSetup.substring(ForkedDebuggerHelper.DEBUG_SETUP_PREFIX.length(), forkSocketIndex - 1));
+          return new ForkedDebuggerConfiguration(forkSocketPort, debugPort);
+        }
+        catch (NumberFormatException ignore) {
+        }
+      }
+    }
+    return null;
+  }
+
+  public String getJvmAgentSetup(boolean isJdk9orLater) {
+    return ForkedDebuggerHelper.DEBUG_SETUP_PREFIX + (isJdk9orLater ? "127.0.0.1:" : "") + myDebugPort;
+  }
+}
index 58eac59b206429aea196e17e2246366f92d563a3..371471127429fefc44ecb2f0380e808ab0af9dca 100644 (file)
@@ -11,13 +11,16 @@ import java.net.Socket;
  */
 public class ForkedDebuggerHelper {
 
+  public static final String DEBUG_SETUP_PREFIX = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=";
+  public static final String DEBUG_FORK_SOCKET_PARAM = "-forkSocket";
+
   public static String setupDebugger(String processName, int debugPort) {
     String setup = "";
     try {
       if (debugPort > -1) {
         int debugAddress = findAvailableSocketPort();
         if (debugAddress > -1) {
-          setup = "-agentlib:jdwp=transport=dt_socket,server=n,suspend=y,address=" + debugAddress;
+          setup = DEBUG_SETUP_PREFIX + debugAddress;
           send(debugAddress, processName, debugPort);
         }
       }
index 0512f52dbd823f8a3369827f4d7ed18325c19727..63ed83894fdb675b42b086e5aee0995f98fb4326 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys;
 import com.intellij.openapi.externalSystem.model.project.*;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
 import com.intellij.openapi.externalSystem.model.task.TaskData;
+import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerConfiguration;
 import com.intellij.openapi.externalSystem.service.notification.ExternalSystemNotificationManager;
 import com.intellij.openapi.externalSystem.service.notification.NotificationCategory;
 import com.intellij.openapi.externalSystem.service.notification.NotificationData;
@@ -57,7 +58,6 @@ import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.model.*;
-import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
 import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData;
 import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataService;
 import org.jetbrains.plugins.gradle.service.project.data.GradleExtensionsDataService;
@@ -78,7 +78,6 @@ import static com.intellij.openapi.util.Pair.pair;
 import static org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.CONFIGURATION_ARTIFACTS;
 import static org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.MODULES_OUTPUTS;
 import static org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil.*;
-import static org.jetbrains.plugins.gradle.service.task.GradleTaskManager.getForkedDebuggerSetup;
 
 /**
  * {@link BaseGradleProjectResolverExtension} provides base implementation of Gradle project resolver.
@@ -673,9 +672,9 @@ public class BaseGradleProjectResolverExtension implements GradleProjectResolver
                                     @Nullable String jvmAgentSetup,
                                     @NotNull Consumer<String> initScriptConsumer) {
     if (!StringUtil.isEmpty(jvmAgentSetup)) {
-      int debugPort = getForkedDebuggerSetup(jvmAgentSetup);
-      if (debugPort != -1) {
-        setupDebugForAllJvmForkedTasks(initScriptConsumer, debugPort);
+      ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmAgentSetup);
+      if (forkedDebuggerSetup != null) {
+        setupDebugForAllJvmForkedTasks(initScriptConsumer, forkedDebuggerSetup.getForkSocketPort());
       }
       else {
         final String names = "[\"" + StringUtil.join(taskNames, "\", \"") + "\"]";
index 6754ad796158014ba885e240f6801b418bcde323..6093421579eb88e29a0fee06fd6d4bace65182f1 100644 (file)
@@ -21,7 +21,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
 import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemProgressEventUnsupportedImpl;
 import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemTaskExecutionEvent;
-import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
+import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerConfiguration;
 import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.util.Key;
@@ -37,6 +37,7 @@ import org.gradle.tooling.ProjectConnection;
 import org.gradle.util.GradleVersion;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JdkVersionDetector;
 import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
 import org.jetbrains.plugins.gradle.service.execution.UnsupportedCancellationToken;
 import org.jetbrains.plugins.gradle.service.project.GradleProjectResolver;
@@ -87,8 +88,13 @@ public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecut
     GradleExecutionSettings effectiveSettings =
       settings == null ? new GradleExecutionSettings(null, null, DistributionType.BUNDLED, false) : settings;
 
-    if (getForkedDebuggerSetup(jvmAgentSetup) != -1) {
-      effectiveSettings.withVmOption(jvmAgentSetup);
+    ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmAgentSetup);
+    if (forkedDebuggerSetup != null) {
+      String javaHome = effectiveSettings.getJavaHome();
+      JdkVersionDetector.JdkVersionInfo jdkVersionInfo =
+        javaHome == null ? null : JdkVersionDetector.getInstance().detectJdkVersionInfo(javaHome);
+      boolean isJdk9orLater = jdkVersionInfo != null && jdkVersionInfo.version.isAtLeast(9);
+      effectiveSettings.withVmOption(forkedDebuggerSetup.getJvmAgentSetup(isJdk9orLater));
     }
     Function<ProjectConnection, Void> f = connection -> {
       try {
@@ -132,20 +138,6 @@ public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecut
     myHelper.execute(projectPath, effectiveSettings, f);
   }
 
-  public static int getForkedDebuggerSetup(@Nullable String jvmAgentSetup) {
-    if (jvmAgentSetup != null && jvmAgentSetup.startsWith(ExternalSystemRunConfiguration.DEBUG_SETUP_PREFIX)) {
-      int forkSocketIndex = jvmAgentSetup.indexOf("-forkSocket");
-      if (forkSocketIndex > 0) {
-        try {
-          return Integer.parseInt(jvmAgentSetup.substring(forkSocketIndex + "-forkSocket".length()));
-        }
-        catch (NumberFormatException ignore) {
-        }
-      }
-    }
-    return -1;
-  }
-
   public static void appendInitScriptArgument(@NotNull List<String> taskNames,
                                               @Nullable String jvmAgentSetup,
                                               @NotNull GradleExecutionSettings effectiveSettings) {