Como posso reiniciar um aplicativo Java AWT? Tenho um botão ao qual anexei um manipulador de eventos. Qual código devo usar para reiniciar o aplicativo?
Quero fazer a mesma coisa que Application.Restart()
faço em um aplicativo C #.
java
restart
application-restart
Azfar Niaz
fonte
fonte
Respostas:
Claro, é possível reiniciar um aplicativo Java.
O método a seguir mostra uma maneira de reiniciar um aplicativo Java:
Basicamente, ele faz o seguinte:
MyClassInTheJar
classe para encontrar o próprio local do jar)fonte
System.exit(0)
termina o processo filho tem a mesma resposta que se essa resposta realmente funciona e por quê. Se você não puder fornecer uma explicação sensata junto com sua resposta, você fez um péssimo trabalho. Uma resposta que fornece mais perguntas do que respostas não é um exemplo de resposta completa. Boas respostas não apenas mostram o código, mas também explicam como e por que funcionam, quais são as desvantagens e quais são as alternativas. Você nem tentou cobrir essas coisas.Dedicado a todos aqueles que dizem que é impossível.
Este programa coleta todas as informações disponíveis para reconstruir a linha de comando original. Em seguida, ele o inicia e, como é o mesmo comando, seu aplicativo inicia uma segunda vez. Então, saímos do programa original, o programa filho continua em execução (mesmo no Linux) e faz exatamente a mesma coisa.
AVISO : Se você executar isso, lembre-se de que nunca termina criando novos processos, semelhante a uma bomba fork .
fonte
ManagementFactory.getRuntimeMXBean().getInputArguments()
fornecerá apenas os argumentos de entrada passados para a JVM. Ele perde parâmetros passados para seu aplicativo. por exemplo,java -jar start.jar -MISSED_PARAM=true
. Em um oracle jvm, você pode recuperar esses parâmetros usandoSystem.getProperty("sun.java.command")
.ProcessBuilder
einheritIO()
, a VM filha pode ser iniciada de forma que a VM pai seja encerrada.Basicamente, você não pode. Pelo menos não de maneira confiável. No entanto, você não deve precisar.
A não pode parte
Para reiniciar um programa Java, você precisa reiniciar o JVM. Para reiniciar o JVM você precisa
Localize o
java
lançador que foi usado. Você pode tentar,System.getProperty("java.home")
mas não há garantia de que isso realmente apontará para o inicializador que foi usado para iniciar seu aplicativo. (O valor retornado pode não apontar para o JRE usado para iniciar o aplicativo ou pode ter sido substituído por-Djava.home
.)Você presumivelmente quer honrar a memória original configurações etc (
-Xmx
,-Xms
...) então você precisa descobrir quais configurações onde usado para iniciar a primeira JVM. Você pode tentar usar,ManagementFactory.getRuntimeMXBean().getInputArguments()
mas não há garantia de que isso refletirá as configurações usadas. Isso está até mesmo explicitado na documentação desse método:Se o seu programa lê a entrada do
Standard.in
stdin original, ele será perdido na reinicialização.Muitos desses truques e hacks falharão na presença de um
SecurityManager
.A parte não deve precisar
Eu recomendo que você projete seu aplicativo de forma que seja fácil limpar tudo e depois crie uma nova instância de sua classe "principal".
Muitos aplicativos são projetados para fazer nada além de criar uma instância no método principal:
Usando esse padrão, deve ser fácil fazer algo como:
e deixe
launch()
retornar verdadeiro se e somente se o aplicativo foi encerrado de uma forma que precisa ser reiniciado.fonte
java
! Você está esquecendo que Java é uma especificação de linguagem, não um programa. E se eu executar seu programa usando algum outro jvm, como o kaffe, por exemplo?Estritamente falando, um programa Java não pode reiniciar a si mesmo, pois para isso ele deve matar a JVM na qual está sendo executado e reiniciá-la, mas uma vez que a JVM não está mais em execução (morta), nenhuma ação pode ser realizada.
Você poderia fazer alguns truques com carregadores de classe personalizados para carregar, empacotar e iniciar os componentes AWT novamente, mas isso provavelmente causará muitas dores de cabeça em relação ao loop de eventos da GUI.
Dependendo de como o aplicativo é iniciado, você pode iniciar a JVM em um script de wrapper que contém um loop do / while, que continua enquanto a JVM sai com um código específico, então o aplicativo AWT teria que chamar
System.exit(RESTART_CODE)
. Por exemplo, em pseudocódigo de script:O aplicativo AWT deve sair da JVM com algo diferente de RESTART_CODE na terminação "normal" que não requer reinicialização.
fonte
JavaApplicationStub
... Não tenho certeza se existe uma maneira fácil de contornar isso.O Eclipse normalmente reinicia após a instalação de um plug-in. Eles fazem isso usando um wrapper eclipse.exe (aplicativo inicializador) para janelas. Este aplicativo executa o jar do executor eclipse principal e se o aplicativo eclipse java terminar com um código de reinicialização, eclipse.exe reinicia o ambiente de trabalho. Você pode construir um bit semelhante de código nativo, script de shell ou outro wrapper de código Java para conseguir a reinicialização.
fonte
janelas
/ min para iniciar o script na janela minimizada
^ & saia para fechar a janela cmd após terminar
um script cmd de amostra pode ser
dormir 10 dormir por 10 segundos
fonte
Se você realmente precisa reiniciar seu aplicativo, pode escrever um aplicativo separado para iniciá-lo ...
Esta página fornece muitos exemplos diferentes para cenários diferentes:
http://www.rgagnon.com/javadetails/java-0014.html
fonte
Embora essa pergunta seja antiga e respondida, me deparei com um problema com algumas das soluções e decidi adicionar minha sugestão à mistura.
O problema com algumas das soluções é que elas criam uma única string de comando. Isso cria problemas quando alguns parâmetros contêm espaços, especialmente java.home .
Por exemplo, no Windows, a linha
Pode retornar algo assim:
C:\Program Files\Java\jre7\bin\java
Esta string deve ser colocada entre aspas ou escapada devido ao espaço em
Program Files
. Não é um grande problema, mas um tanto chato e sujeito a erros, especialmente em aplicativos de plataforma cruzada.Portanto, minha solução cria o comando como uma matriz de comandos:
fonte
Eu mesmo estava pesquisando o assunto quando me deparei com essa pergunta.
Apesar do fato de que a resposta já foi aceita, eu ainda gostaria de oferecer uma abordagem alternativa para completude. Especificamente, o Apache Ant serviu como uma solução muito flexível.
Basicamente, tudo se resume a um arquivo de script Ant com uma única tarefa de execução Java (consulte aqui e aqui ) invocada a partir de um código Java (consulte aqui ). Este código Java, que pode ser um lançamento de método , pode ser uma parte do aplicativo que precisa ser reiniciado. O aplicativo precisa ter uma dependência da biblioteca Apache Ant (jar).
Sempre que o aplicativo precisa ser reiniciado, ele deve chamar o lançamento do método e sair da VM. A tarefa Ant java deve ter as opções fork e spawn definidas como true.
Aqui está um exemplo de um script Ant:
O código para o método de inicialização pode ser parecido com este:
}
Uma coisa muito conveniente aqui é que o mesmo script é usado para a inicialização do aplicativo inicial, bem como para reinicializações.
fonte
Apenas adicionando informações que não estão presentes em outras respostas.
Se procfs
/proc/self/cmdline
estiver disponívelSe você estiver executando em um ambiente que fornece procfs e, portanto, tem o
/proc
sistema de arquivos disponível (o que significa que esta não é uma solução portátil), você pode fazer a leitura do Java/proc/self/cmdline
para reiniciar a si mesmo, assim:Em sistemas com
/proc/self/cmdline
disponível, esta provavelmente é a maneira mais elegante de como "reiniciar" o processo Java atual do Java. Nenhum JNI envolvido e nenhuma suposição de caminhos e outras coisas necessárias. Isso também cuidará de todas as opções JVM passadas para ojava
binário. A linha de comando será exatamente idêntica àquela do processo JVM atual.Muitos sistemas UNIX incluindo GNU / Linux (incluindo Android) hoje em dia têm procfs. No entanto, em alguns como o FreeBSD, ele está obsoleto e está sendo descontinuado. O Mac OS X é uma exceção no sentido de que não possui procfs . O Windows também não tem procfs . O Cygwin tem procfs, mas é invisível para Java porque só é visível para aplicativos que usam DLLs do Cygwin em vez de chamadas de sistema do Windows, e o Java não conhece o Cygwin.
Não se esqueça de usar
ProcessBuilder.inheritIO()
O padrão é que
stdin
/stdout
/stderr
(em Java chamadoSystem.in
/System.out
/System.err
) do processo iniciado seja definido como canais que permitem que o processo atualmente em execução se comunique com o processo recém-iniciado. Se você deseja reiniciar o processo atual, provavelmente não é isso que você deseja . Em vez disso, você deseja questdin
/stdout
/stderr
sejam iguais aos da VM atual. Isso é chamado de herdado . Você pode fazer isso chamandoinheritIO()
suaProcessBuilder
instância.Pitfall no Windows
Um caso de uso frequente de uma
restart()
função é reiniciar o aplicativo após uma atualização. A última vez que tentei isso no Windows, isso foi problemático. Ao sobrescrever o.jar
arquivo do aplicativo com a nova versão, o aplicativo passou a apresentar mau funcionamento e.jar
abrir exceções sobre o arquivo. Estou apenas dizendo, caso este seja o seu caso de uso. Naquela época, resolvi o problema envolvendo o aplicativo em um arquivo em lote e usando um valor de retorno mágicoSystem.exit()
daquele que consultei no arquivo em lote e fiz com que o arquivo em lote reiniciasse o aplicativo.fonte
Pergunta antiga e tudo isso. Mas esta é mais uma forma que oferece algumas vantagens.
No Windows, você pode pedir ao agendador de tarefas para iniciar seu aplicativo novamente para você. Isso tem a vantagem de esperar um determinado período de tempo antes que o aplicativo seja reiniciado. Você pode ir para o gerenciador de tarefas e excluir a tarefa e ela para de se repetir.
fonte
Semelhante à resposta ' melhorada ' de Yoda , mas com outras melhorias (tanto funcional, legibilidade e testabilidade). Agora é seguro executar e reiniciar tantas vezes quanto a quantidade de argumentos de programa fornecidos.
JAVA_TOOL_OPTIONS
opções.V1.1 Bugfix: ponteiro nulo se JAVA_TOOL_OPTIONS não estiver definido
Exemplo:
fonte
Eu acho que você realmente não quer parar o aplicativo, mas sim "Reiniciá-lo". Para isso, você pode usar isso e adicionar o seu "Reset" antes de dormir e depois da janela invisível.
fonte