2011-03-30 12 views
7

¿Es posible de alguna manera 'importar' una nueva clase Java en un programa en ejecución y hacer uso de ella?Escribir e implementar nuevos archivos de clase Java durante el tiempo de ejecución

¿Podría hacer que un programa cree un nuevo archivo de tipo '.java' y luego incluirlo en los archivos del proyecto y hacer referencia a él sin tener que reiniciar el programa?

El siguiente es un ejemplo de lo que quiero decir:

import java.io.*; 

public class Program { 

File JClass = new File("JClass.java"); 
public static BufferedWriter out = null; 

    public static void main(String[] args) { 
     try { 
      out = new BufferedWriter(new FileWriter("JClass.java")); 
      out.write("public abstract class JClass {"); 
      out.newLine(); 
      out.newLine(); 
      out.write(" public void printSomething(String a) {"); 
      out.newLine(); 
      out.write("  System.out.println(a);"); 
      out.newLine(); 
      out.write(" }"); 
      out.newLine(); 
      out.write("}"); 
      out.close(); 
     } catch (IOException e) 
     { 
      System.exit(-1); 
     } 

     //Somehow import JClass.java as a class here 

     JClass.printSomething("Yay! It worked!"); 
    } 

} 

resultante archivo 'JClass.java':

public abstract class JClass { 

    public void printSomething(String a) { 
     System.out.println(a); 
    } 
} 

Del mismo modo, sería posible crear una copia de una de las los archivos fuente del proyecto, edite el código en el archivo y luego fuerce de algún modo los cambios sobre el programa en ejecución?

No me importa tanto la aplicación práctica en este momento. Simplemente estoy explorando diferentes ideas que he tenido relacionadas con la programación. También entiendo que este es el potencial para todo tipo de desastres. La edición de código en ejecución y la inclusión de clases sobre la marcha (que no creo que se verifiquen los errores al igual que las otras clases cuando se construye el proyecto) podría tener resultados muy impredecibles. Simplemente quiero jugar con la idea.

Dicho esto, si alguien tiene advertencias ÚNICAS o cosas que debe tener en cuenta, las agradecería. De lo contrario, agradecería que la gente no respondiera "Esta es una mala idea" o "hay formas más fáciles y mejores de resolver problemas". NO estoy tratando de resolver un problema con esto. Solo estoy explorando la idea.

Entonces, ¿es esto posible?

Respuesta

5

Javassist le permitirá modificar las clases existentes y crear nuevas clases en tiempo de ejecución. http://www.csg.is.titech.ac.jp/~chiba/javassist/

En el Javassist tutorial hay una sección para definir una nueva clase desde cero. Consulte API para ver cómo agregar nuevos métodos, etc. Consulte CtNewMethod.make en la API de Javassist.

Javassist es lo que utiliza JBoss para implementar programación orientada a aspectos.

También puede consultar EATS (el método del instrumento será de interés) que hace uso de Javassist para agregar un nuevo código a los métodos existentes en tiempo de ejecución. Eats no está en una versión de lanzamiento, pero funciona: o

JPDA proporciona algunos mecanismos para modificar las clases que ya están cargadas y ejecutándose en la JVM.

+0

ASM y CGLIB son bibliotecas similares. Este enfoque es ampliamente utilizado y, probablemente, la "mejor" forma de crear código sobre la marcha. – erickson

+0

Eww, EATS utiliza la notación húngara. :-( – corsiKa

0

que realmente desea un Compilador - vistazo a java.lang.Compiler:

http://download.oracle.com/javase/6/docs/api/java/lang/Compiler.html

que es posible cargar una clase diferente de esta manera mediante la compilación de un nuevo archivo .class.

Esto no le permite cambiar una clase cargada. Para hacerlo, también necesita un java.lang.instrument.ClassFileTransformer y eso debe especificarse en la línea de comandos en tiempo de ejecución.

responder a algunas de sus otras preguntas:

  • Si un archivo se compila a partir .java que pasará a través de los mismos controles que uno compilados en otro lugar.
  • Si crea el código de bytes con las herramientas adecuadas (BCEL o ASM, por ejemplo), sigue realizando múltiples comprobaciones para comprobar que es internamente coherente.
  • Si cambia una clase en ejecución, está limitado en lo que puede cambiar.
0

Lanzando uno más: Eclipse Java Compiler. A diferencia de BCEL, ASM o Jasmin, no necesita saber ensamblaje. ECJ es solo un compilador de Java escrito en Java.

Cuestiones relacionadas