【问题标题】:Attach to already running JVM附加到已经运行的 JVM
【发布时间】:2014-03-17 17:16:55
【问题描述】:

有没有办法附加到已经运行的 JVM?

例如,在 JNI 中,您可以使用 JNI_CreateJavaVM 创建 VM 并运行 jar 并检查其所有类..

但是,如果 jar 已经在运行,我无法找到附加到其 JVM 并与其类进行通信或获取其env 指针的方法..

另一个问题是,如果 jar 加载了我的本机库 (.dll) 并且我想在 .dll 中创建一个 JVM,我不能......我也不能在没有 jar 调用我的函数的情况下附加 jar 的当前 JVM。 .

Java 端的示例:

class Foo
{
    static {loadLibrary("Foo")}
}

在 C++ 方面:

void Foo()
{
    //CreateJVM
    //Attach to the current process..
    //Call function from the jar that loaded me.
}

如果 jar 首先调用 Foo,这是无法完成的。

有什么想法吗?有没有办法获取当前的 JVM 或附加到它或外部的 jvm 实例?

【问题讨论】:

  • 这适用于 windows 或 linux 还是其他一些操作系统?您使用的是哪个 C 调试器/IDE?
  • 我可能错过了一些东西,但你不能打开调试端口并附加到它吗?在调试器中点击暂停 VM 并期待一切?
  • 我正在使用代码块并且我在 Windows 上。我不确定你打开调试器并点击暂停是什么意思..
  • @CantChooseUsernames 如果您设法使用我的答案,请告诉我。它工作正常。

标签: java c++ jvm java-native-interface


【解决方案1】:

是的,你可以。

1) 在托管 JVM 的进程中注入 DLL(例如,java.exe,或javaw.exe,或iexplore.exe)。一种常见的注入技术是使用SetWindowsHookEx

2) 在DLL中,使用GetModuleHandle获取jvm.dll的模块句柄

3) 获取JNI_GetCreatedJavaVMs函数的地址,使用GetProcAddress

4) 调用该函数,如果成功,则使用JavaVM 结构中的AttachCurrentThread 函数指针将您的线程附加到找到的第一个JVM。

5) 完成。

有用链接:The Invocation API

【讨论】:

  • 是的!这行得通:D 我没有使用SetWindowsHook。相反,我只是使用CreateThreadLoadLibrary 组合进行注入。尽管如此,它仍然有效 =) 我很高兴!
  • @CantChooseUsernames 编码愉快! (并注意 JNI 内存泄漏 :-)
  • @CantChooseUsernames 旁注:使用SetWindowsHookEx,您可以选择附加到“GUI”线程。这可能很重要。
【解决方案2】:

不,你不能。 JNI 只允许两个模型:

  • 您的非 Java 程序会创建 JVM。
  • 您的 Java 程序调用了本机方法。

如果您需要在其他情况下进行通信,则需要使用其他机制。 Web 服务是一种直接的方法。

【讨论】:

  • 可以在运行的java进程中注入动态链接库,并附加到JVM上。看我的回答。在 Windows 上运行良好。
猜你喜欢
  • 1970-01-01
  • 2011-07-17
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
相关资源
最近更新 更多