使用Java代理修改已加载的类? [英] Modify already loaded class with Java agent?

查看:217
本文介绍了使用Java代理修改已加载的类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在尝试修改驻留在已经由JVM 加载的类中的方法体。我知道JVM实际上不允许更改已经加载的类的定义。但是我的研究使我开始使用JRebel或Java Instrumentation API等实现,两者都使用基于代理的方法。我知道如何在代表Javassist加载类之前做到这一点。但考虑到例如在应用程序启动时加载类定义的EJB环境中的JRebel,不应该在加载JVM的类上进行字节码修改吗?

解决方案

嗯,你了解到 Instrumentation API ,它提供了重新定义类作为操作。那么现在是时候重新考虑一下JVM实际上不允许更改已经加载的类的定义的初始前提。



你应该注意到<如链接所示,Instrumentation API是标准API的一部分

  • 但是,支持重新定义类是可选的。您可以询问当前JVM是否支持此功能

  • 它可能仅限于不支持每个类;你可能会问特定班级是否可能

  • 即使支持,也可能会受到限制,引用文档


    重新定义可能会更改方法体,常量池和属性。重定义不得添加,删除或重命名字段或方法,更改方法的签名或更改继承。在将来的版本中可能会解除这些限制。


  • 在执行重新定义时,可能会有线程执行这些类的方法代码;这些执行将使用旧代码完成,然后





  • 因此,Instrumentation仅对调试和分析等有用。



    但是其他框架,如EJB容器,在生产代码中提供类重新加载,通常采用创建新的 ClassLoader ,它们创建了不同版本的类,然后完全独立于旧版本。



    在Java运行时环境中,类的标识由一对< ClassLoader,Qualified Name> 组成,而不仅仅是一个限定名称...


    Currently I'm trying to modify method bodies residing in classes already loaded by the JVM. I'm aware of the JVM actually not allowing to change the definition of classes that have already been loaded. But my researches brought me to implementations like JRebel or Java Instrumentation API, both using an agent-based approach. I know how to do it right before a class is loaded o behalf of Javassist. But considering e.g. JRebel in an EJB environment where class definitions are loaded on application startup, shouldn't bytecode modification be possible on JVM-loaded classes?

    解决方案

    Well, you learned that the Instrumentation API exists and it offers redefinition of classes as an operation. So then it is time to rethink you initial premise of "the JVM actually not allowing to change the definition of classes that have already been loaded".

    You should note that

    • as the links show, the Instrumentation API is part of the standard API
    • the support of redefinition of classes is, however, optional. You may ask whether the current JVM supports this feature
    • it might be limited to not support every class; you may ask whether it’s possible for a particular class
    • Even if it is supported, the changes may be limited, to cite the documentation:

      The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions.

    • at the time you perform the redefinition, there might be threads executing code of methods of these classes; these executions will complete using the old code then


    So the Instrumentation is merely useful for debugging and profiling, etc.

    But other frameworks, like EJB containers, offering class reloading in production code, usually resort to creating new ClassLoaders which create different versions of the classes which then are entirely independent to the older versions.

    In a Java runtime environment, the identity of a class consists of a pair of <ClassLoader, Qualified Name> rather than just a qualified name…

    这篇关于使用Java代理修改已加载的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆