Java - Programa que se automodifica en tiempo de ejecució

   
Vista:

Programa que se automodifica en tiempo de ejecució

Publicado por Dani (6 intervenciones) el 05/03/2009 21:04:17
Hola!

Tengo el siguiente problema...que es un poco lioso de explicar.

1. Tengo dos clases
1.1 "ImprimeHola", que simplemente tiene un método("getTexto()") que lo que hace es println("hola"). Nada más
1.2 Otra, llamemosla "Principal", que se dedica a llamar a este método de forma iterada, de la siguiente forma (pseudocódigo):
________________________________________
ImprimeHola imprimeHola = new ImprimeHola();
for (int i=0;i<2;i++) {
imprimeHola.getTexto();
Thread.sleep(1000);
}

// * Aqui pasarán cosas luego. *

ImprimeHola imprimeHola2 = new ImprimeHola();
for (int i=0;i<2;i++) {
imprimeHola2.getTexto();
Thread.sleep(1000);
}
________________________________________

Lo cual produce la siguiente salida
hola
hola
hola
hola.

2. Entre medias de los dos for, ---y mientras se está ejecutando el programa--- se cambia el código de ImprimeHola.java, para que en vez de println("hola") tenga print("hola"), es decir, sin el salto de linea.

3. El nuevo código es compilado en tiempo de ejecución mediante

int compileReturncode=com.sun.tools.javac.Main.compile(textoConLosParametros);

Esto obtiene un nuevo ImprimeHola.class que se guarda en el sitio correspondiente, sobreescribiendo el aterior .class

Es decir, el código de antes queda así:

____________________________________________________________________
ImprimeHola imprimeHola = new ImprimeHola();
for (int i=0;i<2;i++) {
imprimeHola.getTexto();
Thread.sleep(1000);
}

// esta es la única diferencia con lo de antes
int compileReturncode=com.sun.tools.javac.Main.compile(textoConLosParametros);
//textConLosParametros tiene el directorio donde estan las clases, e ImprimeHola.java

ImprimeHola imprimeHola2 = new ImprimeHola();
for (int i=0;i<2;i++) {
imprimeHola2.getTexto();
Thread.sleep(1000);
}
____________________________________________________________________

Obteniendo, en teoría, la siguiente salida:
hola
hola
holahola

Cosa que no sucede... El nuevo .class veo que ha sido modificado, mediante fecha de modificación, pero no funciona.

¿Hay alguien que haya llegado hasta aqui? jajaja, madre, que largo...pero es que me parece complicadillo de explicar, espero haber transmitido la idea.

¿alguna sugerencia?

Estoy trabajando con programas que crean programas.

Muchas gracias de ante mano!

Un cordial saludo.


Dani.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Programa que se automodifica en tiempo de ejecu

Publicado por Danilo Juvinao (278 intervenciones) el 05/03/2009 23:21:57
Esto sucede, considero yo (opinion personal), porque cuando ejecutas el programa, los objetos se instancian en memoria como los tenías y al recompilar yna vezc se está ejecutando no toma el cambio porque ya el objeto se encuentra instanciado, eso es lo que creo que te sucede.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Programa que se automodifica en tiempo de ejecu

Publicado por Dani (6 intervenciones) el 05/03/2009 23:28:06
Hmmm....sip, estoy de acuerdo!

No sé cómo apañarlo... :-)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Programa que se automodifica en tiempo de ejecu

Publicado por Dani (6 intervenciones) el 05/03/2009 23:30:19
upsss!! ¿dónde están mis modales? (Perdona, ha sido un dia largo)

Gracias por tu respuesta Danilo ;)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Programa que se automodifica en tiempo de ejecu

Publicado por javierfiis (1 intervención) el 17/04/2009 16:40:35
Holas.

bueno yo estoy en un caso similar, para crear clases en tiempo de ejecucion.

y me he tocado con el mismo problema que indicas. que logro crear el archivo. java
luego para compilar en vez de usar el <b>com.sun.tools.javac.Main.compile</b>
uso el Runtime invocando al <b>JAVAC.exe</b> (esto lo hice por desconocimiento de que existia el <b>com.sun.tools.javac.Main.compile</b>) que al final logro el <b>.Class</b> como tu pero al instanciar de nuevo la clase no se ve los cambios hechos
como indicaba la respuesta anterior supongo que se debe que al inicio se cargan todos los <b>.Class</b> que se tiene hasta ese momento en la maquina virtual, por eso al cambiar el <b>.Class</b> solo se logro en el disco mas no en la maquina virtual(CLASSPATH).

para ello he hecho una solucion media ortodoxa, que se trata de que cada vez que modifique la clase, cree una nueva clase me refiero a crear MiClase0.java
MiClase1.java , MiClase2.java .. etc el correlativo por cada modificacion, cosa que cada vez tendre un nuevo <b>.Class</b>

ahora queda cargar dichas nuevas clases a la maquina virtual.
he encontrado para ello un metodo media ortodoxa tambien que se trata de los siguiente .

Para cargar un jar o clase en tiempo de ejecución tienes que agregar el URL del archivo al ClassLoader de la máquina virtual, para hacer esto debes obtener la instancia del URLClassLoader de la siguiente manera:

URLClassLoader cargadorJVM = (URLClassLoader)ClassLoader.getSystemClassLoader();

La idea es llamar al método protegido de esa instancia de nombre 'addURL'. Debido a que es protegido debemos hacer un llamado indirecto de forma dinámica (en ésta sección 'ruta' es una cadena con la ubicación del archivo jar que deseas agregar):

Class claseJVM = URLClassLoader.class;
Class params[] = new Class[]{ URL.class };

try{
File objFile = new File(ruta);
Method metodo = claseJVM.getDeclaredMethod("addURL", params);

//esta linea es para volver accesible el método
metodo.setAccessible(true);
URL objUrl = objFile.toURL();

metodo.invoke(cargadorJVM, new Object[]{ objUrl });

}catch(Throwable th){
throw new IOException("Error");
}

De esa forma ya puedes acceder a los contenidos del jar o clase nuevo agregado. Saludos.

LUEGO de COMPILAR y CARGAR la nueva CLASE al CLASSPATH en TIEMPO DE EJECUCION.

solo queda instanciar un nuevo objeto de dicha Clase mediante Reflexion.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Programa que se automodifica en tiempo de ejecu

Publicado por Daniel (6 intervenciones) el 17/04/2009 19:13:28
Wow....muchísimas gracias Javierfiis por tan magnífica respuesta.

Un cordial saludo!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar