Pergunta

Eu tenho um programa Java que carrega de terceiros arquivos de classe (classes Eu não escrevi) e os executa. Essas classes costumam usar java.util.Random, que por padrão gera valores de semente de partida aleatório cada vez que ele é instanciado. Por razões de reprodutibilidade, eu quero dar essas aulas a mesma semente de partida de cada vez, mudando-se apenas com a minha discrição.

Aqui estão algumas das soluções óbvias, e por que não fazer o trabalho:

  1. Use uma classe diferente aleatória nas classfiles de terceiros. O problema aqui é só carregar os arquivos de classe, e não pode modificar a fonte.

  2. Use um carregador de classe personalizada para carregar a nossa própria classe Random em vez da versão do JVM. Esta abordagem não vai funcionar porque Java não permite que os carregadores de classe para substituir classes no pacote java.

  3. Trocar implementação java.util.Random do rt.jar para o nosso próprio, ou colocar arquivos em locais confiáveis ??para a JVM. Estas abordagens requerem que o usuário do Messing aplicativo com a JVM instalar em sua máquina, e não são boas.

  4. Adicionando uma classe java.util.Random personalizado ao bootclasspath. Embora este trabalho seria tecnicamente, para esta aplicação particular, é impraticável, porque esta aplicação é destinada a usuários finais para executar a partir de uma IDE. Eu quero fazer executar o aplicativo conveniente para os usuários, o que significa forçando-os a definir sua bootclasspath é uma dor. Eu não posso esconder isso em um script, porque está destinado a ser executado a partir de uma IDE como o Eclipse (para facilitar a depuração.)

Então, como posso fazer isso?

Foi útil?

Solução

Considere modificar as bibliotecas de terceiros para tê-los usar um visto para os seus casos aleatórios. Embora você não tem o código-fonte, você provavelmente pode editar o bytecode para fazê-lo. Um kit de ferramentas úteis para fazer tal é ASM .

Outras dicas

A sua opção 2 irá realmente funcionar, com as seguintes direções.

Você vai precisar (como disse anjab) para alterar o caminho de classe de bootstrap.

Na linha do programa de comando que você precisa adicionar o seguinte:

java -Xbootclasspath / p: C: \ o \ random_impl.jar YourProgram

Assumindo que você está na máquina Windown ou o caminho para que o assunto em qualquer OS.

Essa opção adiciona as classes em arquivos jar antes do rt.jar são carregados. Portanto, o seu aleatória será carregado antes do rt.jar classe Random faz.

O uso é exibido, digitando:

java -X

Ele exibe todas as X (tra) apresenta de JVM tem. Pode por não disponível em outras implementações de VM como JRockit ou outro, mas ele está lá em Sun JVM.

-Xbootclasspath / p: prepend na frente do caminho de classe de bootstrap

Eu tenho usar essa abordagem em um aplicativo onde a classe ORB padrão deve ser substituído por outros ORB implementação. classe ORB faz parte do Java Core e nunca tive qualquer problema.

Boa sorte.

Você pode usar AOP para interceptar as chamadas para Aleatório e giro o arg para o que quiser.

Sam

Embora você não pode mudar o carregador de classe trivialmente para "java.x" e pacotes "sun.x", há uma maneira de carregamento de classe reckon (e instalar um "depois da aula foi bytecoded e carregado" ouvinte) de classes de teses , então você pode definir algo como a semente depois de carregar as classes a partir desses pacotes. Dica:. Use reflexão

De qualquer forma, desde que eu não tenho mais informações que exatamente você quer alcançar, é muito difícil para ajudá-lo aqui.

P.S .: Esteja ciente de que "static {}." - blocos podem impedi-lo brincando com sementes, novamente

"Use um carregador de classe personalizada para carregar a nossa própria classe Random em vez da versão do JVM. Esta abordagem não vai funcionar porque Java não permite que os carregadores de classe para classes de substituição no pacote java."

como sobre a mudança do bootclasspath usar seu personalizado classe Random?

BR, ~ A

Sim opção 2 está funcionando: criou duas classes para testar propósito chamado ThirdPartyClass.java e Random.java

criado frasco de ThirdPartyClass.class

jar -cvf tpc.jar ThirdPartyClass.class

criado frasco de Random.class

jar -cvf rt123.jar Random.class

depois que executar com comando a seguir:

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

A saída será: seed value for ThirdPartyClass-> 1

código fonte 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 fonte 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;
    }
}

Graças Mahaveer Prasad Mali

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top