【问题标题】:Run Eclipse RCP application with Java instrumentation使用 Java 工具运行 Eclipse RCP 应用程序
【发布时间】:2014-09-11 11:53:37
【问题描述】:

使用 Java 工具,我们可以访问由 Java 类加载器从 JVM 加载的类,并通过插入我们的自定义代码来修改其字节码,所有这些都在运行时完成。我们不必担心安全性,它们由适用于 Java 类和相应类加载器的相同安全上下文管理。

我们可以使用它访问一些 java 应用程序,因为它们在同一个类加载器中运行。

现在我们要做的是使用 java 工具访问 Eclipse RCP 应用程序,但在 RCP 中,每个包都有自己的类加载器,我们的工具代码使用 java 应用程序类加载器运行。 当我们访问它时,它会抛出“尚未创建工作台”异常,而工作台已启动并正在运行。(我希望这是因为它们的类加载器不同)。

我尝试从here 做事,但没有成功。 有什么方法可以让我们使用 java 工具处理 RCP 应用程序。

【问题讨论】:

    标签: eclipse swt classloader rcp instrumentation


    【解决方案1】:

    当您检测一个类时,插入代码的引用由修改后的类的ClassLoader 解析。如果该类加载器没有委托给应用程序加载器,例如因为它是基于规则的,并且不知道您的仪器特定类,所以您无法强制执行委派。

    你可以做什么:

    • 在检测类的加载器范围内使用对define classes 的访问覆盖。由于defineClassfinal,bundle 类加载器无法拦截它。但是,这些注入类的引用再次由捆绑加载器解析,因此您必须以这种方式添加所有所需的检测类。
    • 由于捆绑类加载器将为官方 Java API 类执行父加载器委托,因此您可以检测核心 Java 类之一以添加将由检测类调用的辅助方法并代表您的仪表类,必须是added to the boostrap loader
    • 您可以使用answer you have already linked 中描述的技巧将MethodHandle 放入系统属性中。检测类可以检索和调用它,因为MethodHandle 是一个核心类,它将由捆绑加载器正确解析,并且可以调用底层方法而无需访问其定义类(假设参数和返回类型都是原始的类型或核心类)。

    【讨论】:

    • 最后一种方法有一个问题,如果您在同一个 JVM 中有多个应用程序,您必须注意。例如,当您在 servlet 容器中部署多个战争时。问题是,当您可能需要为每个应用程序使用不同的实例时,MethodHandle 仅指向您的类的一个实例。
    • @Felix:可以通过键处理,例如如果您使用检测类(Class 对象)作为键,则不会发生冲突。尽管如此,Java 9 的模块化可能会带来新的障碍,但也可能会带来新的解决方案……
    猜你喜欢
    • 1970-01-01
    • 2014-11-23
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    相关资源
    最近更新 更多