Is there a way to undefine and redefine a class of a class loader?

Stoffer K. :

Is there a way to undefine and redefine a class of a class loader with another runtime compiled class?

Stephen C :

No there isn't a way to undefine a class and redefine it.

The closest you can get to this is to create a new classloader and use it to load a new version of the class. This is how "hot loading" is implemented.

However, what you are actually doing is creating a new type, from the perspective of the Java runtime type system. (The JLS says that two classes with the same fully-qualified names and different class loaders are different types.)

Notes:

  • Having multiple versions of a type at the same time can lead to unintuitive runtime type errors.

  • You need to be careful about the relationship between the 2 class loaders. If the new one has the old one as a parent, things would get rather messed up.

  • This kind of thing can lead to some rather obscure memory leaks. While Class and ClassLoader objects can be garbage collected, there are some complex (hidden) dependencies between classloaders, classes and instances that mean that a single reachable instance can cause a classloader and all of its loaded classes remain reachable.


Why is there no way to do it?

One reason is that is there was, it would blow a massive whole in the JVM's runtime type security. Consider the following sequence.

  1. Load the following class

      public class Sneaky {
          public long x = 42;
      }
    
  2. Create an instance

      Sneaky s = new Sneaky();
    
  3. Redefine the class to a new version

      public class Sneaky {
          public String x;
      }
    
  4. Try to use the x field of the object we created before.

      System.out.println(s.x.length());
    

    Something very bad would happen ....

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=172080&siteId=1