mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] AppMain improvements: ability to operate as a Java agent
This commit is contained in:
+25
-14
@@ -24,27 +24,42 @@ import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ProcessProxyFactoryImpl extends ProcessProxyFactory {
|
||||
private static final String DONT_USE_LAUNCHER_PROPERTY = "idea.no.launcher";
|
||||
private static final boolean ourMayUseLauncher = !Boolean.getBoolean("idea.no.launcher");
|
||||
|
||||
@Override
|
||||
public ProcessProxy createCommandLineProxy(JavaCommandLine javaCmdLine) throws ExecutionException {
|
||||
JavaParameters javaParameters = javaCmdLine.getJavaParameters();
|
||||
if (useLauncher(javaParameters)) {
|
||||
String mainClass = javaParameters.getMainClass();
|
||||
if (mainClass != null) {
|
||||
String mainClass = javaParameters.getMainClass();
|
||||
|
||||
if (ourMayUseLauncher && mainClass != null) {
|
||||
String moduleName = javaParameters.getModuleName();
|
||||
String rtJarPath = JavaSdkUtil.getIdeaRtJarPath();
|
||||
|
||||
if (moduleName == null || new File(rtJarPath).isFile()) {
|
||||
try {
|
||||
ProcessProxyImpl proxy = new ProcessProxyImpl();
|
||||
|
||||
JavaSdkUtil.addRtJar(javaParameters.getClassPath());
|
||||
ParametersList vmParametersList = javaParameters.getVMParametersList();
|
||||
vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_PORT_NUMBER, String.valueOf(proxy.getPortNumber()));
|
||||
vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_BIN_PATH, PathManager.getBinPath());
|
||||
String port = String.valueOf(proxy.getPortNumber());
|
||||
String binPath = PathManager.getBinPath();
|
||||
|
||||
if (moduleName == null) {
|
||||
JavaSdkUtil.addRtJar(javaParameters.getClassPath());
|
||||
|
||||
ParametersList vmParametersList = javaParameters.getVMParametersList();
|
||||
vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_PORT_NUMBER, port);
|
||||
vmParametersList.defineProperty(ProcessProxyImpl.PROPERTY_BIN_PATH, binPath);
|
||||
|
||||
javaParameters.getProgramParametersList().prepend(mainClass);
|
||||
javaParameters.setMainClass(ProcessProxyImpl.LAUNCH_MAIN_CLASS);
|
||||
}
|
||||
else {
|
||||
javaParameters.getVMParametersList().add("-javaagent:" + rtJarPath + '=' + port + ':' + binPath);
|
||||
}
|
||||
|
||||
javaParameters.getProgramParametersList().prepend(mainClass);
|
||||
javaParameters.setMainClass(ProcessProxyImpl.LAUNCH_MAIN_CLASS);
|
||||
return proxy;
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -60,8 +75,4 @@ public class ProcessProxyFactoryImpl extends ProcessProxyFactory {
|
||||
public ProcessProxy getAttachedProxy(ProcessHandler processHandler) {
|
||||
return processHandler != null ? processHandler.getUserData(ProcessProxyImpl.KEY) : null;
|
||||
}
|
||||
|
||||
private static boolean useLauncher(JavaParameters parameters) {
|
||||
return !Boolean.getBoolean(DONT_USE_LAUNCHER_PROPERTY) && parameters.getModuleName() == null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Premain-Class: com.intellij.rt.execution.application.AppMain
|
||||
@@ -36,68 +36,79 @@ public class AppMain {
|
||||
|
||||
private static native void triggerControlBreak();
|
||||
|
||||
private static final boolean ourHelperLibLoaded;
|
||||
static {
|
||||
boolean libLoaded = false;
|
||||
try {
|
||||
String osName = System.getProperty("os.name").toLowerCase(Locale.US);
|
||||
if (osName.startsWith("windows")) {
|
||||
String arch = System.getProperty("os.arch").toLowerCase(Locale.US);
|
||||
String libName = arch.equals("amd64") ? "breakgen64.dll" : "breakgen.dll";
|
||||
File libFile = new File(System.getProperty(PROPERTY_BIN_PATH), libName);
|
||||
if (libFile.isFile()) {
|
||||
System.load(libFile.getAbsolutePath());
|
||||
libLoaded = true;
|
||||
}
|
||||
private static boolean loadHelper(String binPath) {
|
||||
String osName = System.getProperty("os.name").toLowerCase(Locale.US);
|
||||
if (osName.startsWith("windows")) {
|
||||
String arch = System.getProperty("os.arch").toLowerCase(Locale.US);
|
||||
File libFile = new File(binPath, arch.equals("amd64") ? "breakgen64.dll" : "breakgen.dll");
|
||||
if (libFile.isFile()) {
|
||||
System.load(libFile.getAbsolutePath());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void startMonitor(final int portNumber, final boolean helperLibLoaded) {
|
||||
Thread t = new Thread("Monitor Ctrl-Break") {
|
||||
public void run() {
|
||||
try {
|
||||
Socket client = new Socket("127.0.0.1", portNumber);
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(), "US-ASCII"));
|
||||
try {
|
||||
while (true) {
|
||||
String msg = reader.readLine();
|
||||
if ("TERM".equals(msg)) {
|
||||
return;
|
||||
}
|
||||
else if ("BREAK".equals(msg)) {
|
||||
if (helperLibLoaded) {
|
||||
triggerControlBreak();
|
||||
}
|
||||
}
|
||||
else if ("STOP".equals(msg)) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) { }
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static void premain(String args) {
|
||||
try {
|
||||
int p = args.indexOf(':');
|
||||
if (p < 0) throw new IllegalArgumentException("incorrect parameter: " + args);
|
||||
boolean helperLibLoaded = loadHelper(args.substring(p + 1));
|
||||
int portNumber = Integer.parseInt(args.substring(0, p));
|
||||
startMonitor(portNumber, helperLibLoaded);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
System.out.println("Thread dumps in console not supported: failed to load a native helper (" + t.getMessage() + ')');
|
||||
System.err.println("Launcher failed - \"Dump Threads\" and \"Exit\" actions are unavailable (" + t.getMessage() + ')');
|
||||
}
|
||||
ourHelperLibLoaded = libLoaded;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
try {
|
||||
final int portNumber = Integer.getInteger(PROPERTY_PORT_NUMBER).intValue();
|
||||
Thread t = new Thread("Monitor Ctrl-Break") {
|
||||
public void run() {
|
||||
try {
|
||||
Socket client = new Socket("127.0.0.1", portNumber);
|
||||
try {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(), "US-ASCII"));
|
||||
try {
|
||||
while (true) {
|
||||
String msg = reader.readLine();
|
||||
if ("TERM".equals(msg)) {
|
||||
return;
|
||||
}
|
||||
else if ("BREAK".equals(msg)) {
|
||||
if (ourHelperLibLoaded) {
|
||||
triggerControlBreak();
|
||||
}
|
||||
}
|
||||
else if ("STOP".equals(msg)) {
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ignored) { }
|
||||
}
|
||||
};
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
boolean helperLibLoaded = loadHelper(System.getProperty(PROPERTY_BIN_PATH));
|
||||
int portNumber = Integer.parseInt(System.getProperty(PROPERTY_PORT_NUMBER));
|
||||
startMonitor(portNumber, helperLibLoaded);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
System.out.println("Thread dumps and \"soft exit\" not supported: failed to start a monitor thread (" + t.getMessage() + ')');
|
||||
System.err.println("Launcher failed - \"Dump Threads\" and \"Exit\" actions are unavailable (" + t.getMessage() + ')');
|
||||
}
|
||||
|
||||
String mainClass = args[0];
|
||||
|
||||
Reference in New Issue
Block a user