java - 引用另一个虚拟机中的类加载器

标签 java reflection jndi instrumentation

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

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

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

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

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

我真的不想把所有的逻辑都放在代理中,所以我想在走这条路之前先问问你们。谷歌搜索这一点并没有取得什么成果。提前致谢!

最佳答案

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

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

关于java - 引用另一个虚拟机中的类加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33600506/

相关文章:

java - 这是很简单的java代码,但是无法识别错误。我收到语法错误

java - 需要 Jersey2 技术来在运行时启用或禁用服务

java - 如何将属性 ;DB_CLOSE_ON_EXIT=FALSE 设置为 oracle db url?

java - 当从 Java 剪贴板对象中检索为图像时,来自 Outlook 的剪贴板副本始终设置为黑色背景

.net - BindingFlags 枚举中的 GetField、SetField、GetProperty 和 SetProperty 是什么?

c# - 给定类型 ExpressionType.MemberAccess,如何获取字段值?

Java 泛型类标记

java - JNDI LDAP 如何解码SSHA密码

tomcat - 使用 JNDI 连接的 Grails 3.1.1 部署

java - Hibernate 映射文件中的 DOCTYPE 标记有何用途?