【问题标题】:Referencing ClassLoaders in another VM在另一个 VM 中引用 ClassLoader
【发布时间】:2015-11-08 23:57:45
【问题描述】:

所以我正在创建一个分析器应用程序。它有一个用于控制探查器的 GUI 类。它在运行时由两部分组成: 1) 用于控制的应用程序 (GUI) 2)要加载到目标应用程序中的代理

它列出了 PID,然后在 VM 上调用 loadAgent()。所以我希望所有的逻辑都在主应用程序中完成。我的想法是从我的代理获取 Instrumentation 类的实例,然后通过反射调用回调方法。这会将主应用程序中的静态字段设置为 Instrumentation 实例,并通知主应用程序代理已成功加载。

我遇到的问题是我无法获取包含 Instrumentation 字段的主应用程序的类。 Class.forName(String) 隐式地在 ClassLoader 中查找该应用程序。另一种方法可以在另一个 ClassLoader 中查找类...不幸的是,我完全无法从主应用程序中获取代理/目标应用程序的 ClassLoader 以传递给它!

我在 Instrumentation 或 VirtualMachine 类中没有看到允许我执行此操作的方法。我也没有在互联网上找到任何以令人满意的方法回答的此类问题。

我有一些想法... A)如果 ClassLoader 有某种等价的 Class.forName 也许我可以序列化 ClassLoader 并通过套接字发送序列化的字符串,然后以这种方式获取它。到目前为止,我还没有发现任何类似的东西。 B) 浏览代理中的 ClassLoader(有一个 ClassLoader.getParent() 方法..但这是我看到的唯一导航方式),并通过深度等于比较找到合适的 ClassLoader。我什至不知道从哪里开始......我希望我可以遍历 VirtualMachines.list() 并且会有一些我可以调用的东西。没有。 C) 在主应用程序中加载代理,并以某种方式将代理的特定实例传递给目标应用程序。由于它们是不同的类加载器,我只能假设这不起作用。据我所知,可能有办法做到这一点? D) 在主应用程序中创建一个自定义 ClassLoader 并使用它加载目标应用程序。这里的问题是我想要完整的“附加”功能,这会阻止。

我真的不想把所有的逻辑都放在代理中,所以我想在走那条路之前先问问你们。谷歌搜索这个结果并不好。提前致谢!

【问题讨论】:

    标签: java reflection jndi instrumentation


    【解决方案1】:

    我认为您误解了 attach API 在这种情况下的工作原理。附加 API 允许将代理从 本地 VM 进程注册到 远程 JVM 进程。附加后,远程VM在指定线程中执行代理的agentmain方法。代理不知道其附加过程,无法将远程堆中的对象传递到附加 VM 的堆。

    另外,ClassLoaders 通常不可序列化。您宁愿需要通过进程之间的某个套接字来传递必要的信息。为此,本地虚拟机可以例如将套接字地址作为参数传递给代理,本地进程稍后在代理上等待来自远程虚拟机的信息到达。在这种情况下,您还应该考虑要从远程 VM 公开哪些信息。您可能不想发送可序列化的对象。

    【讨论】:

      猜你喜欢
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2012-09-19
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      相关资源
      最近更新 更多