EDIT: I found an error in this - this should not work because JDWP is not connected to the new virtual machine.
Yes, this can be achieved with a quick hack. An adapted version of my description follows:
Hack relies on agent replacement in a virtual machine running JShell. It can be entered through the remoteAgent parameter.
CLASSPATH="<injectpath>" ./jshell --execution "jdi:hostname(localhost),launch(false),remoteAgent(jshellhack.DumpPort),timeout(10000)"
The new dummy agent must somehow give out the port number to which it was supposed to connect. If you don't mind ugly hacks, it can be as simple as writing it to a file. You can also use a named pipe. I would not recommend this for anything serious.
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 an existing remote agent, you need to flip the selected port to the remote side. Then you need to start the source agent on the remote side with the remote port as an argument.
Using SSH, it might look like this:
ssh -R "8000:localhost:$(cat /tmp/jshellargs)" ssh.example.org java jdk.jshell.execution.RemoteExecutionControl 8000
A more robust solution is probably related to the cloning of JdiDefaultExecutionControl and JdiInitiator and extends them with remote connectivity.
KubaV
source share