¿Cómo puedo reiniciar una aplicación Java AWT? Tengo un botón al que he adjuntado un controlador de eventos. ¿Qué código debo usar para reiniciar la aplicación?
Quiero hacer lo mismo que Application.Restart()
en una aplicación C #.
java
restart
application-restart
Azfar Niaz
fuente
fuente
Respuestas:
Por supuesto, es posible reiniciar una aplicación Java.
El siguiente método muestra una forma de reiniciar una aplicación Java:
Básicamente hace lo siguiente:
MyClassInTheJar
clase para encontrar la ubicación del jar)fuente
System.exit(0)
termina el proceso hijo tiene la misma respuesta que si esta respuesta realmente funciona y por qué. Si no puede proporcionar una explicación sensata junto con su respuesta, hizo un mal trabajo. La respuesta que proporciona más preguntas de las que responde no es un ejemplo de una respuesta completa. Las buenas respuestas no solo muestran el código, sino que también explican cómo y por qué funcionan, cuáles son los inconvenientes y cuáles son las alternativas. Ni siquiera trataste de cubrir estas cosas.Dedicado a todos los que dicen que es imposible.
Este programa recopila toda la información disponible para reconstruir la línea de comandos original. Luego, lo lanza y dado que es el mismo comando, tu aplicación se inicia por segunda vez. Luego salimos del programa original, el programa hijo permanece ejecutándose (incluso bajo Linux) y hace exactamente lo mismo.
ADVERTENCIA : Si ejecuta esto, tenga en cuenta que nunca termina creando nuevos procesos, similar a una bomba de horquilla .
fuente
ManagementFactory.getRuntimeMXBean().getInputArguments()
solo le dará los argumentos de entrada pasados a la JVM. Falta los parámetros pasados a su aplicación. ejjava -jar start.jar -MISSED_PARAM=true
. En un jvm de Oracle, puede recuperar esos parámetros usandoSystem.getProperty("sun.java.command")
.ProcessBuilder
yinheritIO()
, la VM secundaria se puede iniciar de una manera que la VM principal terminaría.Básicamente, no puedes. Al menos no de forma fiable. Sin embargo, no debería ser necesario.
El no puede separarse
Para reiniciar un programa Java, debe reiniciar la JVM. Para reiniciar la JVM necesita
Localice el
java
lanzador que se utilizó. Puede intentarlo,System.getProperty("java.home")
pero no hay garantía de que apunte al lanzador que se utilizó para iniciar su aplicación. (Es posible que el valor devuelto no apunte al JRE utilizado para iniciar la aplicación o podría haber sido anulado-Djava.home
).Se podría suponer que quieren honrar la memoria original configuración etc (
-Xmx
,-Xms
, ...) por lo que necesita para averiguar qué entornos en los que se utilizan para iniciar la primera JVM. Puede intentar usarlo,ManagementFactory.getRuntimeMXBean().getInputArguments()
pero no hay garantía de que refleje la configuración utilizada. Esto incluso se detalla en la documentación de ese método:Si su programa lee la entrada del
Standard.in
stdin original, se perderá en el reinicio.Muchos de estos trucos y trucos fallarán en presencia de un
SecurityManager
.No debería necesitar parte
Le recomiendo que diseñe su aplicación para que sea fácil de limpiar todo y luego cree una nueva instancia de su clase "principal".
Muchas aplicaciones están diseñadas para no hacer nada más que crear una instancia en el método principal:
Al usar este patrón, debería ser bastante fácil hacer algo como:
y dejar que
launch()
devolver verdadero si y sólo si la aplicación se cierra de una manera que tiene que ser reiniciado.fuente
java
! Olvidas que Java es una especificación de lenguaje, no un programa. ¿Qué pasa si ejecuto su programa usando algún otro jvm, como kaffe, por ejemplo?Estrictamente hablando, un programa Java no puede reiniciarse por sí mismo, ya que para hacerlo debe eliminar la JVM en la que se está ejecutando y luego iniciarla de nuevo, pero una vez que la JVM ya no se ejecuta (se elimina), no se puede realizar ninguna acción.
Puede hacer algunos trucos con cargadores de clases personalizados para cargar, empaquetar e iniciar los componentes AWT nuevamente, pero esto probablemente causará muchos dolores de cabeza con respecto al bucle de eventos de la GUI.
Dependiendo de cómo se inicie la aplicación, puede iniciar la JVM en un script de envoltura que contiene un bucle do / while, que continúa mientras la JVM sale con un código en particular, entonces la aplicación AWT tendría que llamar
System.exit(RESTART_CODE)
. Por ejemplo, en la secuencia de comandos de pseudocódigo:La aplicación AWT debe salir de la JVM con algo distinto al RESTART_CODE en la terminación "normal" que no requiere reinicio.
fuente
JavaApplicationStub
... No estoy seguro de si hay una manera fácil de evitar eso.Eclipse normalmente se reinicia después de que se instala un complemento. Lo hacen utilizando un contenedor eclipse.exe (aplicación de inicio) para Windows. Esta aplicación ejecuta el jar del corredor principal de eclipse y si la aplicación java de eclipse termina con un código de relanzamiento, eclipse.exe reinicia el banco de trabajo. Puede crear un código nativo similar, un script de shell u otro contenedor de código Java para lograr el reinicio.
fuente
Ventanas
/ min para iniciar el script en la ventana minimizada
^ & salir para cerrar la ventana de cmd después de terminar
un script cmd de muestra podría ser
dormir 10 dormir durante 10 segundos
fuente
Si realmente necesita reiniciar su aplicación, puede escribir una aplicación separada e iniciarla ...
Esta página proporciona muchos ejemplos diferentes para diferentes escenarios:
http://www.rgagnon.com/javadetails/java-0014.html
fuente
Aunque esta pregunta es antigua y está respondida, me encontré con un problema con algunas de las soluciones y decidí agregar mi sugerencia a la mezcla.
El problema con algunas de las soluciones es que crean una única cadena de comandos. Esto crea problemas cuando algunos parámetros contienen espacios, especialmente java.home .
Por ejemplo, en Windows, la línea
Podría devolver algo como esto:
C:\Program Files\Java\jre7\bin\java
Esta cadena debe estar entre comillas o escaparse debido al espacio en
Program Files
. No es un gran problema, pero algo molesto y propenso a errores, especialmente en aplicaciones multiplataforma.Por lo tanto, mi solución crea el comando como una matriz de comandos:
fuente
Yo mismo estaba investigando el tema cuando me encontré con esta pregunta.
Independientemente del hecho de que la respuesta ya está aceptada, me gustaría ofrecer un enfoque alternativo para completar. Específicamente, Apache Ant sirvió como una solución muy flexible.
Básicamente, todo se reduce a un archivo de script Ant con una única tarea de ejecución de Java (consulte aquí y aquí ) invocada desde un código Java (consulte aquí ). Este código Java, que puede ser el inicio de un método , podría ser parte de la aplicación que debe reiniciarse. La aplicación debe tener una dependencia de la biblioteca Apache Ant (jar).
Siempre que la aplicación deba reiniciarse, debe llamar al lanzamiento del método y salir de la VM. La tarea Ant java debe tener las opciones fork y spawn configuradas en true.
Aquí hay un ejemplo de un script Ant:
El código para el método de lanzamiento puede verse así:
}
Una cosa muy conveniente aquí es que se usa el mismo script para el inicio inicial de la aplicación así como para los reinicios.
fuente
Simplemente agregando información que no está presente en otras respuestas.
Si procfs
/proc/self/cmdline
está disponibleSi está ejecutando en un entorno que proporciona procfs y, por lo tanto, tiene el
/proc
sistema de archivos disponible (lo que significa que esta no es una solución portátil), puede hacer que Java lea/proc/self/cmdline
para reiniciarse, así:En sistemas con
/proc/self/cmdline
disponibilidad, esta es probablemente la forma más elegante de cómo "reiniciar" el proceso actual de Java desde Java. No hay JNI involucrado, y no se requiere adivinar caminos y cosas. Esto también se encargará de todas las opciones de JVM pasadas aljava
binario. La línea de comando será exactamente idéntica a la del proceso actual de JVM.Muchos sistemas UNIX, incluido GNU / Linux (incluido Android) actualmente tienen procfs. Sin embargo, en algunos como FreeBSD, está obsoleto y se está eliminando gradualmente. Mac OS X es una excepción en el sentido de que no tiene procfs . Windows tampoco tiene procfs . Cygwin tiene procfs pero es invisible para Java porque solo es visible para las aplicaciones que usan las DLL de Cygwin en lugar de las llamadas al sistema de Windows, y Java no conoce Cygwin.
No olvides usar
ProcessBuilder.inheritIO()
El valor predeterminado es que
stdin
/stdout
/stderr
(en Java llamadoSystem.in
/System.out
/System.err
) del proceso iniciado se configuran en conductos que permiten que el proceso en ejecución se comunique con el proceso recién iniciado. Si desea reiniciar el proceso actual, lo más probable es que esto no sea lo que desea . En su lugar, querrá questdin
/stdout
/stderr
sean los mismos que los de la VM actual. Esto se llama heredado . Puede hacerlo llamandoinheritIO()
a suProcessBuilder
instancia.Escollo en Windows
Un caso de uso frecuente de una
restart()
función es reiniciar la aplicación después de una actualización. La última vez que probé esto en Windows fue problemático. Cuando sobrescribió el.jar
archivo de la aplicación con la nueva versión, la aplicación comenzó a comportarse mal y a dar excepciones sobre el.jar
archivo. Solo digo, en caso de que este sea su caso de uso. En ese entonces, resolví el problema envolviendo la aplicación en un archivo por lotes y usando un valor de retorno mágico delSystem.exit()
que consulté en el archivo por lotes e hice que el archivo por lotes reiniciara la aplicación en su lugar.fuente
Vieja pregunta y todo eso. Pero esta es otra forma que ofrece algunas ventajas.
En Windows, puede pedirle al programador de tareas que vuelva a iniciar su aplicación. Esto tiene la ventaja de esperar un tiempo específico antes de reiniciar la aplicación. Puede ir al administrador de tareas y eliminar la tarea y deja de repetirse.
fuente
Similar a la respuesta ' mejorada ' de Yoda , pero con más mejoras (tanto funcionales como de legibilidad y de prueba). Ahora es seguro de ejecutar y se reinicia tantas veces como la cantidad de argumentos de programa proporcionados.
JAVA_TOOL_OPTIONS
opciones.V1.1 Bugfix: puntero nulo si JAVA_TOOL_OPTIONS no está configurado
Ejemplo:
fuente
Supongo que no quieres detener la aplicación, sino "Reiniciarla". Para eso, puede usar esto y agregar su "Reset" antes del sueño y después de la ventana invisible.
fuente