6

I need to stop a process by invoking a particular method on an instance of a given class. The process has been running for a day, and if I shut it down hard, I lose a lot of work. Due to a bug in the API, the GUI is wrongly wired and doesn't call the correct stop function. I have an interactive Java (Scala) interpreter attached, so if I could get hold of the instance of the process, I could easily invoke the correct method.

I am not in a debugging session, there is no com.sun.jdi. I can see the instance in a stack trace dump, but StackTraceElement doesn't contain actual instances, just classes and line numbers.

Is there any way in a running session, without specific instrumentation, to get hold of that instance -- through its class, through a thread dump?

0__
  • 66,707
  • 21
  • 171
  • 266
  • You can use the [Attach API](http://docs.oracle.com/javase/8/docs/technotes/guides/attach/) to force the loading of an agent into the running virtual machine if you’re on the same machine. If the JVM doesn’t support this, the chances are low… – Holger Oct 18 '16 at 13:46
  • @Holger thanks, that looks interesting. I'm on HotSpot, so I suppose it would work. Do you have any pointer to an "example attachment"? – 0__ Oct 18 '16 at 16:43
  • This looks like a useful pointer to understand how to add instrumentation on the run (perhaps through the attach API?): http://stackoverflow.com/questions/2681459/how-can-i-list-all-classes-loaded-in-a-specific-class-loader – 0__ Oct 18 '16 at 16:52
  • Well, you have to change the manifest attribute from `Premain-Class:` to `Agent-Class:` (or specify both) and provide a method `agentmain` rather than `premain` (see [“Starting Agents After VM Startup” in the package description](http://docs.oracle.com/javase/8/docs/api/?java/lang/instrument/package-summary.html)). See [here for an example](http://stackoverflow.com/a/19400008/2711488) of a program attaching to a JVM and loading an agent, though it’s an already existing agent implementation—the JMX agent, but loading custom Java agents works similar. – Holger Oct 18 '16 at 17:16
  • @Holger - cool. I will explore this, and if I come up with a working solution for the original question, I would confirm and ask you to make it an answer, so it can be accepted and closed. – 0__ Oct 18 '16 at 17:37

1 Answers1

2

It is possible to get all instances of the given class using JVMTI IterateOverInstancesOfClass function. See an example in this answer.

Create a JNI library that will find the required instance using the above function and invoke a method on it from JNI_OnLoad entry. Then invoke System.load from the interpreter console to load this library.

Community
  • 1
  • 1
apangin
  • 92,924
  • 10
  • 193
  • 247