首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javaagent类卸载

Javaagent类卸载
EN

Stack Overflow用户
提问于 2009-08-08 05:39:46
回答 4查看 2.3K关注 0票数 3

我有一个java代理,它测量字节码。我正在使用Java6中的attach apis,以允许用户使用我的java代理动态加载代理和插入和释放代码。我使用Boot-Class-Path清单属性来确保我的javagent类在引导类路径中,这样我的用户就可以插入ArrayList等类。

然而,版本化带来了问题。假设用户动态附加我的代理的版本1。现在,自从他附加了我的代理的版本1之后,他的应用服务器就再也没有关闭过,所以版本1的类仍然会被加载。

我需要一些方法,这样当我的客户端javaagent版本2时,版本1就会被卸载。

我知道一种方法是为我的javaagent的类编写一个客户类加载器,并将类加载器引用设置为null。然而,在这种情况下,我将无法在引导类路径中插入类,因为我的类加载器将位于引导类加载器的层次结构的下面,因此我的用户不能插入像ArrayList这样的类,因为如果我在ArrayList的方法中向代理的一个类方法添加调用,那么引导类加载器将无法看到它们。

那么,有没有办法解决引导类路径问题,同时仍然卸载以前代理的类呢?

EN

回答 4

Stack Overflow用户

发布于 2009-08-12 17:04:07

我不是这个话题的专家,但似乎不直接支持这种卸载到替换的方式。

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

您是否可以创建一个与外部世界对话的永不改变的类,在这个类中您可以在内部引入一个版本控制系统?

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

我不知道这在您的情况下是否可行,但一般来说,JVM似乎不支持直接换入新版本,但您应该能够以某种方式隐藏这一点。

票数 1
EN

Stack Overflow用户

发布于 2009-08-13 20:19:07

我不确定这是否可行,但它可能会给你一些选择...

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

如果使用版本号命名安装程序代理并将其作为类名(MyToolInstallerV1)的一部分,则可以继续加载更新工具代理的新安装程序。如果大小成了问题,也许安装程序代理可以查找以前的安装程序,并将它们的类替换为一个小的无操作存根。

票数 0
EN

Stack Overflow用户

发布于 2009-08-17 11:34:31

到目前为止,我还没有安装任何工具,但我只是在使用java.util.ServiceLoader,并实现了某种插件架构,使用URLClassLoader的方法实现了动态JAR加载-卸载。

我不知道“指令插入”可以以这种方式改变,但是版本控制和动态加载-卸载问题可以被追踪到,而且测试它真的很快,因为困难的事情是由ServiceLoader完成的(只需遵循tiny /META-INF/services/XXX规范),您已经准备好了:)

致以问候。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1248061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档