2009-11-05 12 views
6

¿Hay alguna forma de sustituir (anular) una implementación de clase Java, que ya está cargada por el cargador de clases del sistema por otra implementación (disponible como una matriz de bytes)?Implementación de clase sustituta (reemplazo) en Runtime (Java)

Para ilustrar mi duda, sigue este código:

public class Main { 
    public static void main(String ... args) { 
     Foo foo = new Foo(); 
     foo.print(); 

     ClassLoader cl = ... 

     Foo foo2 = (Foo) cl.newInstance(); 
     foo2.print(); 
    } 
} 

El método de impresión() de las primeras impresiones Foo "de aplicación 1", como los segundos uno imprime "Aplicación 2". La segunda instancia de foo es recuperada por el cargador de clases de una matriz de bytes (que puede almacenarse en un archivo o obtenerse de cualquier secuencia ...)

PD: Es un requisito que Foo sea una clase, no una interfaz, y no se puede extender, es decir, se sobrescriben los bytes reales (dentro de la VM) que definen la implementación de la clase.

+0

¿Estás seguro de que realmente quieres hacer esto? sería bueno explicar por qué en la pregunta. –

Respuesta

0

CGLib hace cosas como esta. Se utiliza en Spring & Hibernate para este fin.

0

Puede implementar un agente de instrumentación y usar java.lang.instrument.Instrumentation # redefineClasses (...) para reemplazar el bytecode de las clases ya cargadas.

4

Sí, esto no es un problema. Debe usar un java.net.URLClassLoader. Por ejemplo, podría darle una url que es un directorio donde vive su archivo Foo.class.

Editar: Entonces la llamada que desea es cl.loadClass("Foo").newInstance(). No puede convertir el resultado en Foo, pero puede usar el reflejo para llamar al método print. O haga de Foo una subclase (o implementación de interfaz) de algo que no va a volver a implementar, que define un método print, y transfiéralo a eso.

0

Utilizo JMX para anular la implementación y volver a implementar las clases.