Evitar que un programa Java se cargue dos veces

22/feb/2012 Java , , 12 Comentarios
java

Algunos de vosotros nos habéis preguntado sobre cómo controlar que un programa Java se cargue dos veces. Es decir, que si ya lo hemos lanzado, evitemos que se vuelva a lanzar.

Existen formas desde Java Web Start y el modo SingleInstanceService para evitar que un programa se cargue dos veces. Pero en nuestro caso vamos a realizarlo de una forma "más manual" en Java, pero muy efectiva.

El truco es que el programa Java cree un objeto que esté escuchando a un puerto específico del ordenador. Para ello utilizamos un ServerSocket, objeto que nos permite crear un objeto escuchando a un determinado puerto.

  1. private static ServerSocket SERVER_SOCKET;
  2. SERVER_SOCKET = new ServerSocket(1334);

Escoge un puerto que no sea el estándar de los protocolos: 80 para el http, 21 para el ftp,... Vamos elige un número de puerto "raro".

Además vemos que el objeto ServerSocket que hemos instanciado es un objeto estático dentro de nuestro programa. Así, nuestro programa tendrá un listener sobre un puerto, al que nadie dirá nada, pero que lo dejará como reservado.

Lo que sucede es que si intentamos volver a crear un escuchador sobre ese puerto, saldrá una excepción indicando que el puerto ya está en uso. Esto nos permite controlar que ya hay una instancia de nuestro programa ejecutándose.

  1. try {
  2. SERVER_SOCKET = new ServerSocket(1334);
  3. System.out.println("Es la primera instancia de la aplicación...");
  4. System.out.println("Pulsa OK para terminar");
  5. System.in.read();
  6. } catch (IOException x) {
  7. System.out.println("Otra instancia de la aplicación se está ejecutando...");
  8. }

Con este simple código podemos evitar que un programa Java se ejecute dos veces.

Vídeos sobre Java

Difunde el Conocimiento

Si te ha gustado el artículo o te ha sido de utilidad, no dejes de compartirlo con tus amigos en las redes sociales... Te estaremos muy agradecidos. :-D

12 comentarios en “Evitar que un programa Java se cargue dos veces”

Víctor Cuervo

Marcos Medina

y que pasa si la aplicacion se cierra inesperadamente. El socket aun quedara abierto no es cierto? y cuando quiera correr la aplicacion me dira que ya esta en ejecucion (porque el socket esta abierto)….. eso pasaria?

Víctor Cuervo

Víctor Cuervo

@HMBLive, yo no lo conocía. Gracias por el aporte. Seguro que a la gente le es de utilidad.

Víctor Cuervo

HMBLive

Hola referente a este tema luego de investigar bastante y solo encontre 2 soluciones atraves del puerto y mediante un fichero pero se me ocurio otra cosa la verdad soy nuevo programando en java, pero habia hecho algo similar en C# claro de manera mucho mas facil entonces lo q hice fue seguir la idea q tenia, de C# la cual consistia en conocer si el proceso ya se estaba ejecutando para abreviar lo q hago es conocer el id del proceso q se esta comenzando a ejecutar mediante:
ManagementFactory.getRuntimeMXBean().getName();
con esto utilizando el comando del sistema
jps -l Ojo este comando
me devuelve las app java q se estan ejecitando con una informaicon adicional entre ella el pakete y el pid o id de proceso
con esto y como conozco el id del proceso ya se si hay mas de 1 app java q tiene un pkt o clase ejecutandose y si es asi ya cierro la app y no la ejecuto agrandes rasgos fue lo q hice hasta ahora me ha funcionado perfectamente claro no he hecho las pruebas del todo profundas, ojo es necesario q la ruta del jdk se encuentre en el path del sistema para q se pueda ejecutar el comando jps, lo q hice verifica todo esto e informa al usuario para q haga lo correspondiente es una alternativa creo espero les peuda servir la idea

Víctor Cuervo

resalpa

Al final resulta y me gusta eso, pero falta algo; que no muestre ese mensaje advirtiendo que la aplicación ya esta en ejecución, más bien que la maximice.

Víctor Cuervo

Juan

Muchas gracias por tu pronta respuesta :)

Me diste una gran idea, Gracias y Saludos!!!

Víctor Cuervo

Héctor

Que tal Juan, lo que puedes hacer es poner un JOptionPane informando al usuario de que ya esta abierto, yo lo tengo así:
private void validaapertura(){

try {
SERVER_SOCKETE = new ServerSocket(1779);
System.out.println(“Es la primera instancia de la aplicación…”);

} catch (IOException x) {

System.out.println(“Otra instancia de la aplicación se está ejecutando…”);

//Informo al usuario
JOptionPane.showMessageDialog(null, “EL SISTEMA YA SE ENCUENTRA EN EJECUCIÓN !!!”,”PRECAUCIÓN”,JOptionPane.WARNING_MESSAGE);

//En esta parte cierro la segunda instancia de la aplicación que se intenta abrir
System.exit(0);

}

}//fin de mi método valida apertura

Espero y te sirva este ejemplo…
Saludos

Víctor Cuervo

Juan

Hola, muy buen aporte, pero quisiera saber si me pudieras decir como hacer que cuando se ejecute por segunda vez te muestre el que ya esta abierto? de antemano muchas gracias por tu ayuda!

Víctor Cuervo

Héctor

Hola Víctor, otra ves aquí molestando, una ves que implemente el código me funciono de maravilla pero con las modificaciones que me piden(que nunca van a terminar)implemente un reloj en tiempo real en donde hago uso de un Thread, el problema es de cuando ejecuto la aplicación me vota la excepción de que mi aplicación ya esta en proceso, creo que es a consecuencia del uso del Thread hay otra forma de poder validar si el programa se carga otra ves?. ya intente cambiando de puerto y nombre al socket pero no funciona alguna idea que me puedas dar para solucionar esto, de antemano muchas gracias.

Víctor Cuervo

Víctor Cuervo

@Jhonatan, muchas gracias por el comentario. :-D

Víctor Cuervo

Jhonatan

Hola Víctor, excelente tutorial, funciona de maravilla, los java consumen muchos recursos y nos ralentizan la web, de esta forma evitamos que se cargue el java varia veces, y el usuario tendrá una navegación más placentera. Saludos

Víctor Cuervo

Víctor Cuervo

@Héctor,
Me alegro enormemente que te haya servido. :-D

Víctor Cuervo

Héctor

Mil gracias amigo !!!!!!!!!!!!

Me sirvió perfectamente, te lo agradezco.

¿Algo que nos quieras comentar?

Déjanos tu comentario, no te preocupes que tu email no será publicado

*


*