2009-08-08 52 views
3

我有一个java代理,它测试字节码。 我正在使用java 6中的attach apis来允许用户使用我的java代理动态加载代理和工具以及解除代码。 我正在使用Boot-Class-Path清单属性来确保我的javagent类在引导类路径中,以便我的用户可以使用ArrayList等工具类。Javaagent类卸载

但是,版本控制会带来问题。 可以说用户动态地附加了我的代理的版本1。 然后我给了他第2版。现在,由于他的应用程序服务器从未关闭,因为他连接了我的代理的版本1,所以版本1的类仍然被加载。

我需要某种方式,当我的客户端版本2的Javaagent,版本1被卸载。

我知道一个办法是写一个客户类加载器为我javaagent的课程,并设置类加载器引用设置为null。 然而,在那种情况下,我不能在引导类路径中检测类,因为我的类加载器将在引导类加载器的层次结构中处于下方,因此我的用户不能像ArrayList那样的工具类,因为如果我在ArrayList的方法中添加一个调用,我的代理程序的类的方法引导类加载程序将无法看到它们。

那么有什么办法来解决引导类路径问题,并仍然卸载以前的代理类?

+1

您可能想看看JavaRebel(http://www.zeroturnaround.com/javarebel/),它是您试图执行的商业实现。它可能会告诉你什么是和不可能的。 – skaffman 2009-08-12 17:06:18

回答

1

我不是这方面的专家,但它似乎像这种卸载替换不直接支持。

但是你需要卸载 - 替换类吗?

你能代替创建一个永不更改的类,外界会谈,在其中内部imlpement一个版本的系统?

例如,创建具有,比如,与ToolAgentImplementation的类名来使用静态字符串类MyToolAgent。当你第一次发布时,它被设置为使用ToolAgentImplementation1_0。当您升级到版本2.0时,您将部署一个名为ToolAgentImplmenetation2_0的附加类,并更新MyToolAgent类以加载并使用它。你永远不会卸载1.0版本,但你停止使用它。你在这里浪费了一些内存,但你实现了版本升级。

我不知道这是不是在您的情况是可行的,但总体看来JVM不支持直接换一个新的版本,但你应该能够隐藏在某些方面。

0

我不知道这会工作,但它可能给你一些选项...

而不是试图加载当前代理(我们称之为工具剂),增加新的代理(一安装代理)。安装程序代理只有1个功能:使用RedefineClasses()来替换原始工具代理类。

如果你的名字有一个版本号的类名(MyToolInstallerV1),可以随时加载新安装该更新工具代理的一部分安装代理。如果大小成为问题,则安装程序代理可能会寻找以前的安装程序,并用一个小的无操作存根替换它们的类。

0

我现在还没有装备任何东西,但我只是在玩java.util.ServiceLoader并实现了某种插件架构,并使用URLClassLoader的方法实现了动态JAR加载卸载。

我不知道“仪表”可以用这种方式进行修改,但版本控制和动态加载 - 卸载问题可以被追踪,并且测试真的很快,因为硬件是由ServiceLoader完成的只需遵循微小的/ META-INF/services/XXX规范),并且您已准备好:)

此致敬礼。

0

OSGI的完美用例。不知道你是否可以将你的经纪人作为一个捆绑销售。