Pregunta

Tengo un programa en Java que se carga a terceros, a los archivos de clase (las clases no he escrito) y las ejecuta.Estas clases utilizan a menudo java.util.Random, que por defecto genera al azar a partir de la semilla de los valores cada vez que este se ejecute.Por razones de reproducibilidad, quiero dar estas clases de la misma a partir de la semilla de cada momento, cambiando sólo en mi discreción.

Aquí están algunas de las soluciones más obvias, y por qué no funcionan:

  1. Utilizar una diferente clase al Azar en el tercero classfiles.El problema aquí es que sólo carga los archivos de clase, y no puede modificar el código fuente.

  2. Usar un cargador de clases para cargar nuestra propia clase al Azar en lugar de la JVM de la versión.Este enfoque no funcionará debido a que Java no permite que los cargadores de clases para anular las clases en el java paquete.

  3. Cambiar el rt.jar's java.util.Random la aplicación para nuestro propio, o poner los archivos en las ubicaciones de confianza para la JVM.Estos enfoques requieren que el usuario de la aplicación de jugar con la JVM instalar en su máquina, y no son buenas.

  4. La adición de una costumbre java.util.Random clase a bootclasspath.Mientras que esto podría funcionar técnicamente, para esta aplicación en particular, es poco práctico debido a que esta aplicación está destinada a los usuarios finales para que se ejecute desde un IDE.Quiero hacer correr la aplicación conveniente para los usuarios, lo que significa que les obliga a establecer sus bootclasspath es un dolor.Yo no puedo ocultar esto en un script, ya que está diseñada para ejecutarse desde un IDE como Eclipse (para facilitar la depuración.)

Entonces, ¿cómo puedo hacer esto?

¿Fue útil?

Solución

Considere la posibilidad de modificar las bibliotecas de terceros para usar visto por sus instancias Aleatorias.A pesar de que usted no tiene el código fuente, usted probablemente puede editar el código de bytes para hacerlo.Un útil conjunto de herramientas para hacer tal es ASM.

Otros consejos

Su opción 2 en realidad obra, con las instrucciones siguientes.

Usted va a necesitar ( como anjab dijo ) para cambiar la secuencia de arranque ruta de clase .

En la línea de comandos del programa que usted necesita para agregar la siguiente:

en java Xbootclasspath/p:C:\your andom_impl.jar YourProgram

Suponiendo que estás en Windown de la máquina o la ruta de acceso para que la materia, en cualquier sistema operativo.

Que opción añade las clases en archivos jar antes de la rt.jar se cargan.Por lo que su Azar será cargado antes de la rt.jar al Azar de la clase no.

El uso es mostrar escribiendo :

java -X

Muestra todas las X(tra) características de JVM.Puede que por no disponible en otros VM implementaciones como JRockit o de otros, pero es allí, en la JVM de Sun.

-Xbootclasspath/p:anteponer en frente de bootstrap ruta de clase

He de utilizar este método en una aplicación en la que el valor predeterminado del ORBE de la clase deben ser sustituidos por otros del ORBE de la aplicación.ORBE de la clase es parte de la Java Core y nunca he tenido ningún problema.

La buena suerte.

Usted podría utilizar AOP para interceptar las llamadas al Azar y juguetear con el arg a lo que usted desea.

Sam

Aunque usted no puede cambiar el cargador de clases trivialmente para "java.x" y "sol.x" de paquetes, hay una manera de contar la carga de clases (y de instalar un "después de la clase fue bytecoded y cargado" el que escucha) de la tesis de clases, por lo que se podría establecer algo así como la semilla después de cargar las clases de estos paquetes.Sugerencia:El uso de la reflexión.

De todos modos, mientras no tengo información adicional qué es exactamente lo que quieres lograr, es bastante duro para ayudar a usted aquí.

P. S.:Ser conscientes de que "static {}" - bloques pueden obstaculizar el cachondeo con semillas, de nuevo.

"Usar un cargador de clases para cargar nuestra propia clase al Azar en lugar de la JVM de la versión.Este enfoque no funcionará debido a que Java no permite que los cargadores de clases para anular las clases en el paquete java."

¿sobre el cambio de bootclasspath para el uso personalizado de clase al Azar ?

BR, ~Un

Sí a la opción 2 está trabajando:creó dos clases para el propósito de pruebas llamado ThirdPartyClass.java y Random.java

creado frasco de ThirdPartyClass.class

jar -cvf tpc.jar ThirdPartyClass.class

creado frasco de Random.class

jar -cvf rt123.jar Random.class

después de que se ejecutan con el siguiente comando:

java  -Xbootclasspath/p:tcp.jar:rt123.jar -cp . -verbose ThirdPartyClass

La salida será: seed value for ThirdPartyClass-> 1

código fuente ThirdPartyClass.java----->

import java.util.Random;

public class ThirdPartyClass {
    ThirdPartyClass(long seed ) {
        System.out.println("seed value for ThirdPartyClass-> "+seed);
    }   

    public static void main(String [] args) {
        ThirdPartyClass tpc=new ThirdPartyClass(new Random().nextLong());
    }
}

código fuente Random.java------->

package java.util;

import java.io.Serializable;

public class Random extends Object implements Serializable
{
    public Random() {
    }

    public Random(long seed) {
    }

    public long nextLong() {
        return 1;
    }
}

Gracias Mahaveer Prasad Malí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top