Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify already loaded class with Java agent?

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?

like image 481
pklndnst Avatar asked Dec 15 '22 14:12

pklndnst


2 Answers

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…

like image 190
Holger Avatar answered Dec 17 '22 03:12

Holger


I wasn't aware that you can use the instrumentation API to redefine classes (see @Holger's answer). However, as he notes, there are some significant limitations on that approach. Furthermore, the javadoc says:

"This method is intended for use in instrumentation, as described in the class specification."

Using it to materially change the semantics of a class is ... all sorts of bad from the perspective of the Java type system.

like image 44
Stephen C Avatar answered Dec 17 '22 03:12

Stephen C