unify spaces handling in path for different java agents (IDEA-CR-30322)

This commit is contained in:
Dmitry Batkovich
2018-03-27 11:54:35 +03:00
parent 389564e2ef
commit 7ac847e298
8 changed files with 90 additions and 150 deletions
@@ -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")) {
@@ -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<TestDiscoveryDataSocketListener> 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()));
@@ -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 + "=<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;
}
}
@@ -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 + "=<path>");
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;
}
}
@@ -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();
@@ -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");
@@ -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);
}
@@ -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 <IDEA dist>/bin/idea.properties as " + GROOVY_HOTSWAP_AGENT_PATH + "=<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";