I'm writing a Java agent to interact with JVMTI. For reasons I won't get into, I need to use JVMTI (the C interface inside the java
process) rather than the Java APIs like java.lang.instrument
or JDI. I would like to be able to do a couple of things which appear not to be supported directly.
dlclose()
from the JVMTI code if I can find the handle for the dynamically-loaded module?If these operations can't be done, is there a way to pass data to a Java agent after it's loaded? Is there a normal way to do this through some Java command-line utility? If not, can I safely create a thread and have it listen to a socket using the standard C or C++ library calls within the code for my agent?
If it helps, don't worry about supporting Windows with your answer - I'm undertaking this project to extend a Unix-only debugging tool.
Note: I've already seen this but thought there might be some normal way to do it that isn't in the JVMTI standard.
You can only inject (deploy) an agent either at start time of the JVM by passing the argument -agentlib:<agent-lib-name>=<options>
or -agentpath:<path-to-agent>=<options>
.
The other way is through Java itself. This depends heavily on the JVM, for that reason it is out of JVMTI specification scope. For instance if there is the VirtualMachine
class through the method loadAgentPath(agentPath, options)
. If you want to execute this from within the native JVMTI code you would need to do Bytecode instrumentation.
I am not sure, similar to 1. you could run the Java unload
method through Bytecode instrumentation. If dlclose()
works I do not see a problem in doing that.
As you see, you can pass data to the Java agent by using the options. Alternatively, if you want to pass data continuously between both instances you can open two sockets and write/read between them. I used Protobuf
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With