Is there an alternate way to launch remote jvm?

Deadly 提交于 2019-12-04 13:20:57

EDIT: I've found a bug in this - this shouldn't work, because the JDWP not attached to the new VM.


Yes, this can be accomplished with a quick hack. Adapted version of my description follows:

The hack relies on replacing the agent in the VM started by JShell. It can be injected through the remoteAgent execution parameter.

CLASSPATH="<injectpath>" ./jshell --execution "jdi:hostname(localhost),launch(false),remoteAgent(jshellhack.DumpPort),timeout(10000)"

The new dummy agent has to somehow give out the port number it was supposed to connect to. If you don't mind ugly hacks, it can be as simple as writing it to a file. You can also take advantage of a named pipe. I wouldn't recommend this for anything serious, though.

A simple agent:

package jshellhack;

import java.nio.file.*;
import java.lang.*;

import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;

public class DumpPort {

    public static void main(String[] args) throws Exception {
        String str = args[0] + "\n";
        OpenOption[] opts = new OpenOption[] { CREATE, WRITE, TRUNCATE_EXISTING };
        Files.write(Paths.get("/tmp/jshellargs"), str.getBytes(), opts);
    }
}

JShell on your computer is the listening side of the JDWP channel. To reuse the existing remote agent, you have to reverse-forward a chosen port to the remote side. Then, you have to run the original agent on the remote side with the remote port as an argument.

Using SSH, it may look like this:

ssh -R "8000:localhost:$(cat /tmp/jshellargs)" ssh.example.org java jdk.jshell.execution.RemoteExecutionControl 8000

A more robust solution will probably involve cloning the JdiDefaultExecutionControl and JdiInitiator implementations and extending them with remote connection capability.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!