From 7ac847e2981d31bb5e630b4e1f99856282aa47e7 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 27 Mar 2018 11:47:44 +0300 Subject: [PATCH] unify spaces handling in path for different java agents (IDEA-CR-30322) --- .../debugger/impl/DebuggerManagerImpl.java | 48 +-------------- .../testDiscovery/TestDiscoveryExtension.java | 8 ++- .../testframework/JavaTestAgentUtil.java | 60 ------------------- .../intellij/execution/JavaExecutionUtil.java | 58 ++++++++++++++++++ .../intellij/coverage/IDEACoverageRunner.java | 6 +- .../coverage/JaCoCoCoverageRunner.java | 7 ++- .../intellij/coverage/JavaCoverageRunner.java | 18 +++++- .../groovy/debugger/GroovyHotSwapper.java | 35 +---------- 8 files changed, 90 insertions(+), 150 deletions(-) delete mode 100644 java/execution/impl/src/com/intellij/execution/testframework/JavaTestAgentUtil.java diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java index 437314207dc3..5fb48f3ddde5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java @@ -11,6 +11,7 @@ import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint; import com.intellij.debugger.ui.tree.render.BatchEvaluator; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.configurations.RemoteConnection; @@ -542,7 +543,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent } } if (agentFile.exists()) { - String agentPath = handleSpacesInPath(agentFile.getAbsolutePath()); + String agentPath = JavaExecutionUtil.handleSpacesInAgentPath(agentFile.getAbsolutePath(), "captureAgent", null); if (agentPath != null) { parametersList.add(prefix + agentPath + "=" + generateAgentSettings()); } @@ -559,51 +560,6 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent } } - @Nullable - private static String handleSpacesInPath(String agentPath) { - if (agentPath.contains(" ")) { - File targetDir = new File(PathManager.getSystemPath(), "captureAgent"); - String res = copyAgent(agentPath, targetDir); - if (res == null) { - try { - targetDir = FileUtil.createTempDirectory("capture", "jars"); - res = copyAgent(agentPath, targetDir); - if (res == null && targetDir.getAbsolutePath().contains(" ")) { - LOG.info("Capture agent was not used since the agent path contained spaces: " + agentPath); - return null; - } - } - catch (IOException e) { - LOG.info(e); - return null; - } - } - - return res; - } - return agentPath; - } - - @Nullable - private static String copyAgent(String agentPath, File targetDir) { - if (!targetDir.getAbsolutePath().contains(" ")) { - try { - //noinspection ResultOfMethodCallIgnored - targetDir.mkdirs(); - Path source = Paths.get(agentPath); - Path target = targetDir.toPath().resolve(AGENT_FILE_NAME); - Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); - Files.copy(source.getParent().resolve(STORAGE_FILE_NAME), targetDir.toPath().resolve(STORAGE_FILE_NAME), - StandardCopyOption.REPLACE_EXISTING); - return target.toString(); - } - catch (IOException e) { - LOG.info(e); - } - } - return null; - } - private static String generateAgentSettings() { Properties properties = new Properties(); if (Registry.is("debugger.capture.points.agent.debug")) { diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java index 0d7e17a24a91..023014200550 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/TestDiscoveryExtension.java @@ -1,6 +1,7 @@ // 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.execution.testDiscovery; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.JavaTestConfigurationBase; import com.intellij.execution.RunConfigurationExtension; import com.intellij.execution.TestDiscoveryListener; @@ -8,7 +9,6 @@ import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunnerSettings; import com.intellij.execution.process.ProcessHandler; -import com.intellij.execution.testframework.JavaTestAgentUtil; import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsAdapter; import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsListener; import com.intellij.execution.testframework.sm.runner.SMTestProxy; @@ -40,6 +40,7 @@ import java.nio.file.Path; public class TestDiscoveryExtension extends RunConfigurationExtension { public static final String TEST_DISCOVERY_REGISTRY_KEY = "testDiscovery.enabled"; + private static final String TEST_DISCOVERY_AGENT_PATH = "test.discovery.agent.path"; private static final boolean USE_SOCKET = SystemProperties.getBooleanProperty("test.discovery.use.socket", true); public static final Key SOCKET_LISTENER_KEY = Key.create("test.discovery.socket.data.listener"); @@ -83,8 +84,9 @@ public class TestDiscoveryExtension extends RunConfigurationExtension { if (runnerSettings != null || !isApplicableFor(configuration)) { return; } - params.getVMParametersList().add("-javaagent:" + JavaTestAgentUtil - .handleSpacesInAgentPath(PathUtil.getJarPathForClass(TestDiscoveryProjectData.class))); + String agentPath = JavaExecutionUtil.handleSpacesInAgentPath(PathUtil.getJarPathForClass(TestDiscoveryProjectData.class), "testDiscovery", TEST_DISCOVERY_AGENT_PATH); + if (agentPath == null) return; + params.getVMParametersList().add("-javaagent:" + agentPath); TestDiscoveryDataSocketListener listener = tryInstallSocketListener(configuration); if (listener != null) { params.getVMParametersList().addProperty(SocketTestDiscoveryProtocolDataListener.PORT_PROP, Integer.toString(listener.getPort())); diff --git a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestAgentUtil.java b/java/execution/impl/src/com/intellij/execution/testframework/JavaTestAgentUtil.java deleted file mode 100644 index a61b715064a0..000000000000 --- a/java/execution/impl/src/com/intellij/execution/testframework/JavaTestAgentUtil.java +++ /dev/null @@ -1,60 +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.execution.testframework; - -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.io.FileUtilRt; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; - -public class JavaTestAgentUtil { - private static final Logger LOG = Logger.getInstance(JavaTestAgentUtil.class); - public static final String JAVA_TEST_AGENT_AGENT_PATH = "java.test.agent.lib.path"; - - @NotNull - public static String handleSpacesInAgentPath(@NotNull String agentPath) { - return FileUtil.join(handleSpacesInContainingDir(agentPath), new File(agentPath).getName()); - } - - private static String handleSpacesInContainingDir(String agentPath) { - String agentContainingDir; - String userDefined = System.getProperty(JAVA_TEST_AGENT_AGENT_PATH); - if (userDefined != null && new File(userDefined).exists()) { - agentContainingDir = userDefined; - } else { - agentContainingDir = new File(agentPath).getParent(); - } - if (!SystemInfo.isWindows && agentContainingDir.contains(" ")) { - File dir = new File(PathManager.getSystemPath(), "testAgentJars"); - if (dir.getAbsolutePath().contains(" ")) { - try { - dir = FileUtil.createTempDirectory("testAgent", "jars"); - if (dir.getAbsolutePath().contains(" ")) { - LOG.info("Java test agent not used since the agent path contains spaces: " + agentContainingDir + "\n" + - "One can move the agent libraries to a directory with no spaces in path and specify its path in idea.properties as " + - JAVA_TEST_AGENT_AGENT_PATH + "="); - return agentContainingDir; - } - } - catch (IOException e) { - LOG.info(e); - return agentContainingDir; - } - } - - try { - LOG.info("Agent jars were copied to " + dir.getPath()); - FileUtil.copyDir(new File(agentContainingDir), dir, pathname -> FileUtilRt.extensionEquals(pathname.getPath(), "jar")); - return dir.getPath(); - } - catch (IOException e) { - LOG.info(e); - } - } - return agentContainingDir; - } -} diff --git a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java index 1c17a8013133..05954127eb74 100644 --- a/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java +++ b/java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java @@ -24,11 +24,16 @@ import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.util.ExecutionErrorDialog; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -38,6 +43,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.io.File; +import java.io.IOException; import java.util.HashSet; import java.util.Set; @@ -45,6 +52,8 @@ import java.util.Set; * @author spleaner */ public class JavaExecutionUtil { + private static final Logger LOG = Logger.getInstance(JavaExecutionUtil.class); + private JavaExecutionUtil() { } @@ -203,4 +212,53 @@ public class JavaExecutionUtil { public static void showExecutionErrorMessage(final ExecutionException e, final String title, final Project project) { ExecutionErrorDialog.show(e, title, project); } + + @Nullable + public static String handleSpacesInAgentPath(@NotNull String agentPath, @NotNull String copyDirName, @Nullable String agentPathPropertyKey) { + String agentName = new File(agentPath).getName(); + String containingDir = handleSpacesInContainingDir(agentPath, copyDirName, agentPathPropertyKey); + return containingDir == null ? null : FileUtil.join(containingDir, agentName); + } + + @Nullable + private static String handleSpacesInContainingDir(@NotNull String agentPath, + @NotNull String copyDirName, + @Nullable String agentPathPropertyKey) { + String agentContainingDir; + String userDefined = agentPathPropertyKey == null ? null : System.getProperty(agentPathPropertyKey); + if (userDefined != null && new File(userDefined).exists()) { + agentContainingDir = userDefined; + } else { + agentContainingDir = new File(agentPath).getParent(); + } + if (!SystemInfo.isWindows && agentContainingDir.contains(" ")) { + File dir = new File(PathManager.getSystemPath(), copyDirName); + if (dir.getAbsolutePath().contains(" ")) { + try { + dir = FileUtil.createTempDirectory(copyDirName, "jars"); + if (dir.getAbsolutePath().contains(" ")) { + LOG.info("agent not used since the agent path contains spaces: " + agentContainingDir + "\n" + + "One can move the agent libraries to a directory with no spaces in path and specify its path in idea.properties as " + + agentPathPropertyKey + "="); + return null; + } + } + catch (IOException e) { + LOG.info(e); + return null; + } + } + + try { + LOG.info("Agent jars were copied to " + dir.getPath()); + FileUtil.copyDir(new File(agentContainingDir), dir, pathname -> FileUtilRt.extensionEquals(pathname.getPath(), "jar")); + return dir.getPath(); + } + catch (IOException e) { + LOG.info(e); + return null; + } + } + return agentContainingDir; + } } diff --git a/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java index 6d63270e6125..6a08a479a18d 100644 --- a/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java +++ b/plugins/coverage/src/com/intellij/coverage/IDEACoverageRunner.java @@ -2,9 +2,9 @@ package com.intellij.coverage; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configurations.SimpleJavaParameters; import com.intellij.execution.configurations.coverage.JavaCoverageEnabledConfiguration; -import com.intellij.execution.testframework.JavaTestAgentUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.rt.coverage.data.ClassData; import com.intellij.rt.coverage.data.ProjectData; @@ -66,7 +66,9 @@ public class IDEACoverageRunner extends JavaCoverageRunner { final boolean isSampling, @Nullable String sourceMapPath) { StringBuilder argument = new StringBuilder("-javaagent:"); - argument.append(JavaTestAgentUtil.handleSpacesInAgentPath(PathUtil.getJarPathForClass(ProjectData.class))); + String agentPath = handleSpacesInAgentPath(PathUtil.getJarPathForClass(ProjectData.class)); + if (agentPath == null) return; + argument.append(agentPath); argument.append("="); try { final File tempFile = createTempFile(); diff --git a/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java index f870084ad8d2..ac2501781123 100644 --- a/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java +++ b/plugins/coverage/src/com/intellij/coverage/JaCoCoCoverageRunner.java @@ -1,9 +1,9 @@ package com.intellij.coverage; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.SimpleJavaParameters; -import com.intellij.execution.testframework.JavaTestAgentUtil; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -164,8 +164,9 @@ public class JaCoCoCoverageRunner extends JavaCoverageRunner { public void appendCoverageArgument(final String sessionDataFilePath, final String[] patterns, final SimpleJavaParameters javaParameters, final boolean collectLineInfo, final boolean isSampling) { StringBuilder argument = new StringBuilder("-javaagent:"); - final String parentPath = JavaTestAgentUtil.handleSpacesInAgentPath(PathUtil.getJarPathForClass(RT.class)); - argument.append(parentPath); + final String agentPath = handleSpacesInAgentPath(PathUtil.getJarPathForClass(RT.class)); + if (agentPath == null) return; + argument.append(agentPath); argument.append("="); argument.append("destfile=").append(sessionDataFilePath); argument.append(",append=false"); diff --git a/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java b/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java index 59fd72a532ff..6cc462b4ce86 100644 --- a/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java +++ b/plugins/coverage/src/com/intellij/coverage/JavaCoverageRunner.java @@ -15,12 +15,14 @@ */ package com.intellij.coverage; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configurations.SimpleJavaParameters; -import com.intellij.execution.testframework.JavaTestAgentUtil; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.util.PathUtil; +import com.vladium.emma.rt.RT; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,6 +33,8 @@ import java.io.IOException; * @author Roman.Chernyatchik */ public abstract class JavaCoverageRunner extends CoverageRunner { + private static final String JAVA_COVERAGE_AGENT_AGENT_PATH = "java.test.agent.lib.path"; + public boolean isJdk7Compatible() { return true; } @@ -53,7 +57,15 @@ public abstract class JavaCoverageRunner extends CoverageRunner { appendCoverageArgument(sessionDataFilePath, patterns, parameters, collectLineInfo, isSampling); } - protected static void write2file(File tempFile, String arg) throws IOException { + + @Nullable + public static String handleSpacesInAgentPath(@NotNull String agentPath) { + String agentName = new File(agentPath).getName(); + String containingDir = JavaExecutionUtil.handleSpacesInAgentPath(agentPath, "testAgent", JAVA_COVERAGE_AGENT_AGENT_PATH); + return containingDir == null ? null : FileUtil.join(containingDir, agentName); + } + + protected static void write2file(File tempFile, String arg) throws IOException { FileUtil.writeToFile(tempFile, (arg + "\n").getBytes(CharsetToolkit.UTF8_CHARSET), true); } @@ -62,7 +74,7 @@ public abstract class JavaCoverageRunner extends CoverageRunner { if (!SystemInfo.isWindows && tempFile.getAbsolutePath().contains(" ")) { tempFile = FileUtil.createTempFile(new File(PathManager.getSystemPath(), "coverage"), "coverage", "args", true); if (tempFile.getAbsolutePath().contains(" ")) { - final String userDefined = System.getProperty(JavaTestAgentUtil.JAVA_TEST_AGENT_AGENT_PATH); + final String userDefined = System.getProperty(JAVA_COVERAGE_AGENT_AGENT_PATH); if (userDefined != null && new File(userDefined).isDirectory()) { tempFile = FileUtil.createTempFile(new File(userDefined), "coverage", "args", true); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java index 5118de926d50..e6fef6160656 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyHotSwapper.java @@ -16,6 +16,7 @@ package org.jetbrains.plugins.groovy.debugger; import com.intellij.execution.Executor; +import com.intellij.execution.JavaExecutionUtil; import com.intellij.execution.configurations.JavaParameters; import com.intellij.execution.configurations.ModuleBasedConfiguration; import com.intellij.execution.configurations.RunConfiguration; @@ -23,7 +24,6 @@ import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.runners.JavaProgramPatcher; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.PluginPathManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; @@ -32,7 +32,6 @@ import com.intellij.openapi.projectRoots.JdkUtil; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.LanguageLevelModuleExtensionImpl; import com.intellij.openapi.roots.LanguageLevelProjectExtension; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.search.FileTypeIndex; import com.intellij.psi.search.GlobalSearchScope; @@ -40,11 +39,9 @@ import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.PathUtil; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import java.io.File; -import java.io.IOException; import java.util.jar.Attributes; import java.util.regex.Pattern; @@ -121,42 +118,14 @@ public class GroovyHotSwapper extends JavaProgramPatcher { } if (!project.isDefault() && containsGroovyClasses(project)) { - final String agentPath = handleSpacesInPath(getAgentJarPath()); + String agentPath = JavaExecutionUtil.handleSpacesInAgentPath(getAgentJarPath(), "groovyHotSwap", GROOVY_HOTSWAP_AGENT_PATH); if (agentPath != null) { javaParameters.getVMParametersList().add("-javaagent:" + agentPath); } } } - @Nullable - private static String handleSpacesInPath(String agentPath) { - if (agentPath.contains(" ")) { - final File dir = new File(PathManager.getSystemPath(), "groovyHotSwap"); - if (dir.getAbsolutePath().contains(" ")) { - LOG.info("Groovy hot-swap not used since the agent path contains spaces: " + agentPath + "\n" + - "One can move the agent to a directory with no spaces in path," + - " and specify its path in /bin/idea.properties as " + GROOVY_HOTSWAP_AGENT_PATH + "="); - return null; - } - - final File toFile = new File(dir, "gragent.jar"); - try { - FileUtil.copy(new File(agentPath), toFile); - return toFile.getPath(); - } - catch (IOException e) { - LOG.info(e); - } - } - return agentPath; - } - private static String getAgentJarPath() { - final String userDefined = System.getProperty(GROOVY_HOTSWAP_AGENT_PATH); - if (userDefined != null && new File(userDefined).exists()) { - return userDefined; - } - final File ourJar = new File(PathUtil.getJarPathForClass(GroovyHotSwapper.class)); if (ourJar.isDirectory()) { //development mode return PluginPathManager.getPluginHomePath("groovy") + "/hotswap/gragent.jar";