2009-04-23 20 views
17

En Java, ¿es posible crear una definición de clase sobre la marcha mientras se está ejecutando una aplicación y luego crear un objeto de esa clase?Definición de una clase mientras se ejecuta una aplicación Java

Por ejemplo, una aplicación en ejecución leería en un archivo de texto que contiene una lista de miembros de la clase para incluir en la nueva clase. La aplicación definiría una definición de clase basada en la lista de miembros y luego la insantaría.

+25

Así es como se inicia SkyNet. – TheTXI

+7

Si SkyNet se escribió en Java, requeriría demasiada memoria como para ser una amenaza. – Pesto

+4

SkyNet simplemente construiría un clúster más grande para ejecutar. El hecho de que esté escrito en Java tendría sentido, ya que SkyNet y Java terminarán siendo el fin de la humanidad. – TheTXI

Respuesta

11

Sí, es posible hacerlo en teoría, su archivo de clase es un código de bytes que al final es una matriz de bytes. luego puede usar el método defineClass (String, byte [], int, int) para obtener una instancia de clase que se pueda usar para crear instancias de objetos a través de la reflexión.

En la práctica puede usar algo como CGLib o javaassist.

También puede usar la forma larga de generar el código java en un archivo, invocando el compilador, luego cargando el archivo.

1

Puede hacer esto escribiendo el código para su nueva clase en un archivo, luego invocando el compilador de Java en ese archivo y usando un cargador de clases para cargar dinámicamente esa clase en la aplicación en ejecución. Apache Tomcat hace esto para sus páginas JSP; toma el código, realiza algunos cambios, lo envuelve en un bloque try/catch en el medio de una clase, que luego escribe en el sistema de archivos, lo compila y utiliza un cargador de clases para obtener y demandarlo para atender las solicitudes.

2

Puede generar dinámicamente clases utilizando ASM

0

Tal vez un poco exagerado, la Apache BCEL (código de bytes Biblioteca de ingeniería) se puede utilizar para crear class archivos en tiempo de ejecución.

Aunque yo no lo he probado, uno podría crear una clase, cargarla y crear una instancia durante el tiempo de ejecución.

0

Sí, eso es posible.

Puede crear clases con Javassist en tiempo de ejecución definiendo el cuerpo de la clase y haciendo que javassist compile su nueva clase.

Javassist tiene un compilador personalizado que crea bytecode basado en la definición de su clase. Tiene algunas formas particulares de manejar las cosas, pero es muy fácil e intuitivo usar esta biblioteca.

Javassist se utiliza en JBoss, y creo que es una buena referencia :)

Lo mismo se puede lograr con BCEL, sin embargo, es mucho más difícil (pero de esta manera usted tiene más control sobre lo que se está generando)

0

Probablemente puedas hacer algo como eso con JRuby, o JPython o Groovy si es necesario.

Si se siente particularmente masoquista, puede consultar BCEL.

0

Si desea Java y metaprogramación, use Groovy.

+0

Hola Stefan, así Groovy puede ayudar a compilar en tiempo de ejecución una clase Java sobre la marcha e instanciarla? ¿Tiene algún puntero sobre cómo hacer esto? – Sergio

0

ASM es la biblioteca de código de bytes de nivel más bajo para Java, supongo. Eso lo hace muy difícil pero también muy poderoso.Recomiendo leer la documentación de ASM (PDF) para comprender realmente cómo funciona la generación de códigos byte en Java. Esa documentación también explica cómo cargar el bytecode en el cargador de clases (otro tema difícil de hacer a la derecha).

Después de eso, puede usar una de las bibliotecas de nivel superior, si hace su vida más fácil, y entender lo que hacen. En muchos casos, como la generación de proxies, el CGLIB es útil y fácil de usar. Para obtener más poder, muchos han mencionado Javassist (no lo he usado, CGLIB y ASM han sido buenos para mí).

1

Tal vez la solución más simple (en términos de que no requieren bibliotecas adicionales) sería utilizar el Java compiler API que viene con Java 6. Sólo acaba de ser capaz de generar el .java, compilar y luego realizar una Class.forName().

+0

que funcionaría solo si el jdk está instalado, ¿verdad? – Sergio

0

Hubo una pregunta reciente aquí con respecto a in-memory compilation que debería darle algunas pistas sobre qué hacer después de haber logrado generar el código fuente.

Cuestiones relacionadas