IDEA-228415: breakpoints are ignored in Java if android module present in the project
authorAndrei Kuznetsov <andrei.kuznetsov@jetbrains.com>
Tue, 11 Feb 2020 09:42:46 +0000 (12:42 +0300)
committerintellij-monorepo-bot <intellij-monorepo-bot-no-reply@jetbrains.com>
Fri, 14 Feb 2020 11:39:06 +0000 (11:39 +0000)
Java process forked by Gradle does not include debugger agent due to missing cmd line argument.
Gradle script debugging also does not work due to missing cmd line argument.
This is only the case when android modules are present since in this case AndroidGradleTaskManager takes control over gradle task execution.
When there is no android modules, Idea's GradleTaskManager takes control, and all the JVM options are added as expected.

GitOrigin-RevId: 1e20557c5d89921378746dc8917943d1884365c8

platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemJdkUtil.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunnableState.java
platform/external-system-impl/src/com/intellij/openapi/externalSystem/task/BaseExternalSystemTaskManager.java [deleted file]
platform/external-system-rt/src/com/intellij/openapi/externalSystem/rt/execution/ForkedDebuggerConfiguration.java [deleted file]
plugins/gradle/java/src/service/project/JavaGradleProjectResolver.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/execution/GradleRunConfiguration.java
plugins/gradle/src/org/jetbrains/plugins/gradle/service/task/GradleTaskManager.java

index bee72dcea0edf5de91972dc92739b894e50ca231..3e783174067e3e4f91a2bf133431f3bd41201ab4 100644 (file)
@@ -18,6 +18,7 @@ import com.intellij.util.EnvironmentUtil;
 import org.jetbrains.annotations.Contract;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.JdkVersionDetector;
 
 import java.io.File;
 import java.util.Arrays;
@@ -211,4 +212,11 @@ public class ExternalSystemJdkUtil {
   private static Sdk getInternalJdk() {
     return ExternalSystemJdkProvider.getInstance().getInternalJdk();
   }
+
+  @Contract("null -> false")
+  public static boolean isJdk9orLater(@Nullable String javaHome) {
+    JdkVersionDetector.JdkVersionInfo jdkVersionInfo =
+      javaHome == null ? null : JdkVersionDetector.getInstance().detectJdkVersionInfo(javaHome);
+    return jdkVersionInfo != null && jdkVersionInfo.version.isAtLeast(9);
+  }
 }
\ No newline at end of file
index d9b75e4557d1c440069211b71509c76d7be7990a..078bab0c8f21c89f06fa918063851349d9b26f1d 100644 (file)
@@ -31,13 +31,13 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotifica
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter;
 import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemBuildEvent;
 import com.intellij.openapi.externalSystem.model.task.event.ExternalSystemTaskExecutionEvent;
-import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
 import com.intellij.openapi.externalSystem.service.internal.ExternalSystemExecuteTaskTask;
 import com.intellij.openapi.externalSystem.util.ExternalSystemBundle;
 import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.UserDataHolderBase;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.ArrayUtil;
@@ -45,6 +45,7 @@ import com.intellij.util.net.NetUtils;
 import com.intellij.util.text.DateFormatUtil;
 import com.intellij.xdebugger.XDebugProcess;
 import com.intellij.xdebugger.XDebugSession;
+import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -52,12 +53,15 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 
-import static com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper.DEBUG_FORK_SOCKET_PARAM;
 import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.convert;
 import static com.intellij.openapi.externalSystem.util.ExternalSystemUtil.getConsoleManagerFor;
 import static com.intellij.openapi.util.text.StringUtil.nullize;
 
 public class ExternalSystemRunnableState extends UserDataHolderBase implements RunProfileState {
+  @ApiStatus.Internal
+  public static final Key<Integer> DEBUGGER_DISPATCH_PORT_KEY = Key.create("DEBUGGER_DISPATCH_PORT");
+  @ApiStatus.Internal
+  public static final Key<Integer> BUILD_PROCESS_DEBUGGER_PORT_KEY = Key.create("GRADLE_SCRIPT_DEBUGGER_PORT");
 
   @NotNull private final ExternalSystemTaskExecutionSettings mySettings;
   @NotNull private final Project myProject;
@@ -123,6 +127,7 @@ public class ExternalSystemRunnableState extends UserDataHolderBase implements R
 
     final ExternalSystemExecuteTaskTask task = new ExternalSystemExecuteTaskTask(myProject, mySettings, jvmParametersSetup);
     copyUserDataTo(task);
+    addDebugUserDataTo(task);
 
     final String executionName = StringUtil.isNotEmpty(mySettings.getExecutionName())
                                  ? mySettings.getExecutionName()
@@ -263,19 +268,22 @@ public class ExternalSystemRunnableState extends UserDataHolderBase implements R
     return executionResult;
   }
 
+  private void addDebugUserDataTo(UserDataHolderBase holder) {
+    if (myDebugPort > 0) {
+      holder.putUserData(BUILD_PROCESS_DEBUGGER_PORT_KEY, myDebugPort);
+      if (getForkSocket() != null) {
+        holder.putUserData(DEBUGGER_DISPATCH_PORT_KEY, getForkSocket().getLocalPort());
+      }
+    }
+  }
+
   @Nullable
   private String getJvmParametersSetup() throws ExecutionException {
     final SimpleJavaParameters extensionsJP = new SimpleJavaParameters();
     ExternalSystemRunConfiguration.EP_NAME.forEachExtensionSafe(
       extension -> extension.updateVMParameters(myConfiguration, extensionsJP, myEnv.getRunnerSettings(), myEnv.getExecutor()));
-    String jvmParametersSetup;
-    if (myDebugPort > 0) {
-      jvmParametersSetup = ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + myDebugPort;
-      if (getForkSocket() != null) {
-        jvmParametersSetup += (" " + DEBUG_FORK_SOCKET_PARAM + getForkSocket().getLocalPort());
-      }
-    }
-    else {
+    String jvmParametersSetup = "";
+    if (myDebugPort <= 0) {
       final ParametersList allVMParameters = new ParametersList();
       final ParametersList data = myEnv.getUserData(ExternalSystemTaskExecutionSettings.JVM_AGENT_SETUP_KEY);
       if (data != null) {
diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/task/BaseExternalSystemTaskManager.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/task/BaseExternalSystemTaskManager.java
deleted file mode 100644 (file)
index 3cb147a..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2000-2019 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.task;
-
-import com.intellij.openapi.externalSystem.model.settings.ExternalSystemExecutionSettings;
-import org.jetbrains.jps.model.java.JdkVersionDetector;
-
-public abstract class BaseExternalSystemTaskManager<S extends ExternalSystemExecutionSettings> implements ExternalSystemTaskManager<S> {
-  protected boolean isJdk9orLater( String javaHome) {
-    JdkVersionDetector.JdkVersionInfo jdkVersionInfo =
-      javaHome == null ? null : JdkVersionDetector.getInstance().detectJdkVersionInfo(javaHome);
-    return jdkVersionInfo != null && jdkVersionInfo.version.isAtLeast(9);
-  }
-}
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
deleted file mode 100644 (file)
index 3c88742..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.JVM_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.JVM_DEBUG_SETUP_PREFIX.length(), forkSocketIndex - 1));
-          return new ForkedDebuggerConfiguration(forkSocketPort, debugPort);
-        }
-        catch (NumberFormatException ignore) {
-        }
-      }
-    }
-    return null;
-  }
-
-  public String getJvmAgentSetup(boolean isJdk9orLater) {
-    return ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + (isJdk9orLater ? "127.0.0.1:" : "") + myDebugPort;
-  }
-}
index d6cdb5ee77024b659017cec5395bc2a3a0451bb7..e3ae47862dd9f2e942084afdb6b5db18ec1f6b6f 100644 (file)
@@ -9,7 +9,7 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys;
 import com.intellij.openapi.externalSystem.model.project.ModuleData;
 import com.intellij.openapi.externalSystem.model.project.ProjectData;
 import com.intellij.openapi.externalSystem.model.project.dependencies.ProjectDependencies;
-import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerConfiguration;
+import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
 import com.intellij.openapi.externalSystem.util.Order;
@@ -221,27 +221,27 @@ public class JavaGradleProjectResolver extends AbstractProjectResolverExtension
                                     @Nullable String jvmParametersSetup,
                                     @NotNull Consumer<String> initScriptConsumer) {
     if (!StringUtil.isEmpty(jvmParametersSetup)) {
-      ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmParametersSetup);
-      if (forkedDebuggerSetup == null) {
-        final String names = "[" + toStringListLiteral(taskNames, ", ") + "]";
-        List<String> argv = ParametersListUtil.parse(jvmParametersSetup);
-        if (SystemInfo.isWindows) {
-          argv = ContainerUtil.map(argv, s -> CommandLineUtil.escapeParameterOnWindows(s, false));
-        }
-        final String jvmArgs = toStringListLiteral(argv, " << ");
+      LOG.assertTrue(!jvmParametersSetup.contains(ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX),
+                     "Please use org.jetbrains.plugins.gradle.service.debugger.GradleJvmDebuggerBackend to setup debugger");
 
-        final String[] lines = {
-          "gradle.taskGraph.beforeTask { Task task ->",
-          "    if (task instanceof JavaForkOptions && (" + names + ".contains(task.name) || " + names + ".contains(task.path))) {",
-          "        def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
-          "        jvmArgs << " + jvmArgs,
-          "        task.jvmArgs = jvmArgs",
-          "    }",
-          "}",
-        };
-        final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
-        initScriptConsumer.consume(script);
+      final String names = "[" + toStringListLiteral(taskNames, ", ") + "]";
+      List<String> argv = ParametersListUtil.parse(jvmParametersSetup);
+      if (SystemInfo.isWindows) {
+        argv = ContainerUtil.map(argv, s -> CommandLineUtil.escapeParameterOnWindows(s, false));
       }
+      final String jvmArgs = toStringListLiteral(argv, " << ");
+
+      final String[] lines = {
+        "gradle.taskGraph.beforeTask { Task task ->",
+        "    if (task instanceof JavaForkOptions && (" + names + ".contains(task.name) || " + names + ".contains(task.path))) {",
+        "        def jvmArgs = task.jvmArgs.findAll{!it?.startsWith('-agentlib:jdwp') && !it?.startsWith('-Xrunjdwp')}",
+        "        jvmArgs << " + jvmArgs,
+        "        task.jvmArgs = jvmArgs",
+        "    }",
+        "}",
+      };
+      final String script = StringUtil.join(lines, SystemProperties.getLineSeparator());
+      initScriptConsumer.consume(script);
     }
 
     final String testEventListenerDefinition = loadTestEventListenerDefinition();
index 2b25c6fd31295ba2d236db511d9d99ecf93f4f7c..d6da599e46173270e0ee0c0e7ab52ee5eeb7cd75 100644 (file)
@@ -28,8 +28,6 @@ public class GradleRunConfiguration extends ExternalSystemRunConfiguration imple
   public static final Key<Boolean> DEBUG_FLAG_KEY = Key.create("DEBUG_GRADLE_SCRIPT");
 
   @ApiStatus.Internal
-  public static final Key<Integer> DEBUGGER_DISPATCH_PORT_KEY = Key.create("DEBUGGER_DISPATCH_PORT");
-  @ApiStatus.Internal
   public static final Key<String> DEBUGGER_PARAMETERS_KEY = Key.create("DEBUGGER_PARAMETERS");
 
   private boolean isScriptDebugEnabled = true;
index 8b3162d1b3b4211b95b514c2c5da33ef486851d4..a931ef0ae62e2bcd1fc77f57ed972293c744db5e 100644 (file)
@@ -9,10 +9,11 @@ import com.intellij.openapi.externalSystem.model.ExternalSystemException;
 import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId;
 import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListener;
-import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerConfiguration;
+import com.intellij.openapi.externalSystem.rt.execution.ForkedDebuggerHelper;
+import com.intellij.openapi.externalSystem.service.execution.ExternalSystemJdkUtil;
 import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration;
 import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
-import com.intellij.openapi.externalSystem.task.BaseExternalSystemTaskManager;
+import com.intellij.openapi.externalSystem.task.ExternalSystemTaskManager;
 import com.intellij.openapi.externalSystem.task.TaskCallback;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
@@ -46,13 +47,15 @@ import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
+import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunnableState.BUILD_PROCESS_DEBUGGER_PORT_KEY;
+import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunnableState.DEBUGGER_DISPATCH_PORT_KEY;
 import static com.intellij.util.containers.ContainerUtil.*;
 import static org.jetbrains.plugins.gradle.util.GradleUtil.determineRootProject;
 
 /**
  * @author Denis Zhdanov
  */
-public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecutionSettings> {
+public class GradleTaskManager implements ExternalSystemTaskManager<GradleExecutionSettings> {
 
   public static final Key<String> INIT_SCRIPT_KEY = Key.create("INIT_SCRIPT_KEY");
   public static final Key<String> INIT_SCRIPT_PREFIX_KEY = Key.create("INIT_SCRIPT_PREFIX_KEY");
@@ -82,18 +85,11 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
     GradleExecutionSettings effectiveSettings =
       settings == null ? new GradleExecutionSettings(null, null, DistributionType.BUNDLED, false) : settings;
 
-    ForkedDebuggerConfiguration forkedDebuggerSetup = ForkedDebuggerConfiguration.parse(jvmParametersSetup);
-    if (forkedDebuggerSetup != null) {
-      if (isGradleScriptDebug(settings)) {
-        effectiveSettings.withVmOption(forkedDebuggerSetup.getJvmAgentSetup(isJdk9orLater(effectiveSettings.getJavaHome())));
-      }
-      effectiveSettings.putUserData(GradleRunConfiguration.DEBUGGER_DISPATCH_PORT_KEY, forkedDebuggerSetup.getForkSocketPort());
-    }
-
     CancellationTokenSource cancellationTokenSource = GradleConnector.newCancellationTokenSource();
     myCancellationMap.put(id, cancellationTokenSource);
     Function<ProjectConnection, Void> f = connection -> {
       try {
+        setupGradleScriptDebugging(effectiveSettings);
         appendInitScriptArgument(taskNames, jvmParametersSetup, effectiveSettings);
         try {
           for (GradleBuildParticipant buildParticipant : effectiveSettings.getExecutionWorkspace().getBuildParticipants()) {
@@ -187,7 +183,7 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
       String isTestExecution = String.valueOf(Boolean.TRUE == effectiveSettings.getUserData(GradleConstants.RUN_TASK_AS_TEST));
       enhancementParameters.put(GradleProjectResolverExtension.TEST_EXECUTION_EXPECTED_KEY, isTestExecution);
 
-      Integer debugDispatchPort = effectiveSettings.getUserData(GradleRunConfiguration.DEBUGGER_DISPATCH_PORT_KEY);
+      Integer debugDispatchPort = effectiveSettings.getUserData(DEBUGGER_DISPATCH_PORT_KEY);
 
       if (debugDispatchPort != null) {
         enhancementParameters.put(GradleProjectResolverExtension.DEBUG_DISPATCH_PORT_KEY, String.valueOf(debugDispatchPort));
@@ -233,6 +229,15 @@ public class GradleTaskManager extends BaseExternalSystemTaskManager<GradleExecu
     }
   }
 
+  public static void setupGradleScriptDebugging(@NotNull GradleExecutionSettings effectiveSettings) {
+    Integer gradleScriptDebugPort = effectiveSettings.getUserData(BUILD_PROCESS_DEBUGGER_PORT_KEY);
+    if (gradleScriptDebugPort != null && gradleScriptDebugPort > 0) {
+      boolean isJdk9orLater = ExternalSystemJdkUtil.isJdk9orLater(effectiveSettings.getJavaHome());
+      String jvmOpt = ForkedDebuggerHelper.JVM_DEBUG_SETUP_PREFIX + (isJdk9orLater ? "127.0.0.1:" : "") + gradleScriptDebugPort;
+      effectiveSettings.withVmOption(jvmOpt);
+    }
+  }
+
   public static void runCustomTask(@NotNull Project project,
                                    @NotNull String executionName,
                                    @NotNull Class<? extends Task> taskClass,