Implement (override) a class implementation in Runtime (Java)

Is there a way to substitute (override) an implementation of a Java class that is already loaded by the loader of the System class with another implementation (available as an array of bytes)?

To illustrate my doubts, this code follows:

public class Main { public static void main(String ... args) { Foo foo = new Foo(); foo.print(); ClassLoader cl = ... Foo foo2 = (Foo) cl.newInstance(); foo2.print(); } } 

The print () method of the first Foo prints "Implementation 1", and the second prints "Implementation 2". The second instance of foo is retrieved by the class loader from the byte array (which can be stored in a file or retrieved from any stream ...)

PS: The requirement that Foo is a class, not an interface, and cannot be extended, that is, the actual bytes (inside the virtual machine) that define the implementation of the class, are overridden.

+6
java classloader runtime
source share
4 answers

Yes, this is not a problem. You should use java.net.URLClassLoader . For example, you can give it the URL where your redefining Foo.class file is located.

Edit: Then the cl.loadClass("Foo").newInstance() call you need. You cannot pass the result to Foo , but you can use reflection to call its print method. Or, make Foo a subclass (or interface implementation) of something that you will not override that the print method defines, and apply to it.

+4
source share

CGLib does such things. It is used in Spring and Hibernate for this purpose.

0
source share

You can implement the toolkit agent and use java.lang.instrument.Instrumentation # redefineClasses (...) to replace the bytecode of already loaded classes.

0
source share

I use JMX to deploy and redeploy classes.

0
source share

All Articles