5

A similar question has already been answered for Windows, but I could not find out how to achieve the same on Linux.

I want to deepen my knowledge in JNI. I already got JNI projects working with JNI_CreateJavaVM, creating a new JVM from within the native application.

But this time I would like to not create the JVM within the native application (i.e., not using JNI_CreateJavaVM), but to attach to an already running one (i.e., using AttachCurrentThread on a VM that has been started before the native application by some java myApplication call).

Is there a way on Linux how to achieve this? I need to get a JavaVM object of the running JVM. I tried to use JNI_GetCreatedJavaVMs, but this does not return any JVMs (I think this method only returns VMs created by the current process, e.g., by using JNI_CreateJavaVM, and not all VMs that are running on the system)

Community
  • 1
  • 1
Markus Weninger
  • 11,931
  • 7
  • 64
  • 137
  • When you create a JVM it is running in your current process as a part of your memory space. What do you mean by attach? What do you expect that to do? – Peter Lawrey Jul 26 '16 at 11:33
  • @PeterLawrey: I now changed the question a bit to make my goals more clear hopefully. What I want to achieve is to _attach_ (`AttachCurrentThread`) to an already running VM. I need to get this VM's `JavaVM` object for this, but I don't know how. – Markus Weninger Jul 26 '16 at 11:39
  • You can't move a thread from one process to another or share threads between processes. No OS that I know of will allow this. So it's not clear to me what you expect attach to do. You can create a TCP connection to an existing process and manage it remotely but this is not JNI, it's TCP. – Peter Lawrey Jul 26 '16 at 11:42
  • @PeterLawrey: For example, I would like to be able execute calls to some (static) methods within an already running JVM from my native application. I thought I could use JNI for this, by using JNI's `GetStaticMethodID` & `CallStaticIntMethod`, as I already did before in other projects. The only difference is that the JVM would already be running this time, and not created within the native application using `JNI_CreateJavaVM` as in my older projects. Basically, with "attach", I mean that I want to obtain "JNI-access" to an already running JVM (i.e., retrieve its `JNIEnv` and `JavaVM` objects) – Markus Weninger Jul 26 '16 at 11:49

2 Answers2

1

If i understand correctly, you want to make calls from one OS process (your native application) to a separate OS process (running a java application). You can't make "direct" calls to a JVM in another process. You need to use some sort of remote protocol. Two "builtin" options are JMX (via RMI) or straight RMI. Alternately, you could expose a webservice on the other JVM and invoke it using standard HTTP interactions.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
1

JNI functions can be used only within the process that started JVM. JNI does not allow you to control other processes.

However, there is a way to load your code in the context of different JVM process using HotSpot Dynamic Attach API.

  • Compile your code into an agent library (.so);
  • Create Agent_OnAttach function that will be an entry point for your code;
  • Load the agent library using Dynamic Attach.

There is Java API to attach to remote JVM and to load agent library in its context. But you can also do it from native code like in my jattach project.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • Dynamic Attach API is the way I then used yesterday, thanks for the answer! And I will surely look into jattach! – Markus Weninger Jul 27 '16 at 09:57
  • You also can use [jvm-attach](https://github.com/mageddo-projects/jvm-attach) which is a wrapper for jattach, then you can attach programatically from Java – deFreitas Jun 22 '20 at 21:31