Ejecutar aplicación Java como servicio – Integración básica
En esta entrada abordaremos un tema bastante interesante: cómo correr un programa en Java como servicio en Windows o demonio en UNIX/Linux. Puesto que el API de Java no proporciona nada para estos casos, utiliza
remos una librería llamada Java Service Wrapper. Dicha librería nos ofrece una serie de scripts y binarios preparados para diferentes sistemas operativos y arquitecturas, que nos permitirán correr nuestros programas como un servicio; además ofrece diferentes versiones: Profesional, Estándar y Comunity. En este caso usaremos la versión Comunity que es libre y gratuita.
La mejor manera de aprender a usar dicha librería es con un pequeño laboratorio, así que he preparado uno en donde explico la integración más simple que existe con Java Service Wrapper (existen 4 métodos; unos más avanzados que otros). La integración sencilla que he escogido nos permitirá ejecutar como servicio una aplicación que ya esté creada (probablemente ya empaquetada en un .jar) y a la que no podemos o es difícil hacerle modificaciones. Esta es la manera más sencilla de hacerlo, sin embargo tiene una desventaja: al detener el servicio se envía directamente un System.exit() a la JVM por lo que la aplicación no se cerrará limpiamente.
Si quieres integrar tu aplicación de una manera más segura y estás en la capacidad de prepararla para ello, podrías intentar la integración avanzada en la que utilizas el API de Java Service Wrapper para implementar métodos de inicio, pausa y detención del servicio [Para este caso utilizaremos una aplicación de ejemplo que recibe un archivo como parámetro y escribe en él información sobre la memoria del sistema, cada 60 segundos. He escogido este ejemplo porque posee varios aspectos interesantes: requiere de librerías externas (tanto JARs como librerías nativas [.so, dll, etc.]) y recibe parámetros.
Puedes descargar la aplicación de ejemplo de haciendo clic aquí. Si la ejecutáramos de manera convencional veríamos algo de este tipo:
^C
gentookde@larry bin % cat /tmp/log
======Mon Oct 05 09:42:05 COT 2009=======
Cantidad de memoria RAM: 3952MB
Total: 4042664
Usada: 3509516
Disponible: 533148
Memoria SWAP total: 1052248
Memoria SWAP usada: 0
Memoria SWAP libre: 1052248
Como puedes ver se trata de una aplicación de consola común y corriente. La aplicación consta básicamente de:
- El ejecutable servicio.jar ubicado en el directorio bin/
- La librería sigar.jar en el directorio lib/
- Las librerías específicas de cada arquitectura de sigar en lib/
Pasos para la integración
Lo primero es descargar el paquete de Java Service Wrapper y descomprimirlo. Supondremos que el directorio donde se encuentra Java Service Wrapper es $RUTA_JSW y que el directorio de la aplicación que vamos a convertir en servicio es $RUTA_APP.
1. Copiamos los siguentes archivos al directorio bin de nuestra aplicación de ejemplo…
UNIX/Linux
cp $RUTA_JSW/src/bin/sh.script.in $RUTA_APP/bin/
cp $RUTA_JSW/lib/* $RUTA_APP/bin/
El archivo $RUTA_JSW/bin/wrapper podría no existir; por lo tanto lo que debes copiar es el archivo wrapper-xxx específico para tu plataforma. Por ejemplo, en este caso estoy usando Gentoo Linux de 64bits por lo tanto copiaré el archivo $RUTA_JSW/bin/wrapper-linux-x86-64.
Windows
copy $RUTA_JSW/src/bin/ App.bat.in $RUTA_APP/bin/
copy $RUTA_JSW/src/bin/ InstallApp-NT.bat.in $RUTA_APP/bin/
copy $RUTA_JSW/src/bin/ UninstallApp-NT.bat.in $RUTA_APP/bin/
copy $RUTA_JSW/lib/* $RUTA_APP/bin/
2. Renombramos algunos archivos…
UNIX/Linux…
Ahora debes renombrar el script sh.script.in con el nombre de la aplicación con la que haremos la integración y darle privilegios de ejecución. En este casó se llama simplemente “servicio”:
mv sh.script.in servicio
chmod a+x servicio
Windows
Ahora debes renombrar los archivos .bat para que concuerden con el nombre de la aplicación con la que haremos la integración. En este casó se llama simplemente “servicio” (lo puedes hacer usando el explorador si no te gusta usar la consola, pero a mi me daría pena):
move App.bat.in servicio.bat
move InstallApp-NT.bat.in InstallServicio-NT.bat
move UninstallApp-NT.bat.in UninstallServicio-NT.bat
3. editar archivo de configuración
Editamos el archivo wrapper.conf y lo dejamos en el directorio $RUTA_APP/conf/. El archivo para este ejemplo tendrá el siguiente contenido (importante! lee la explicación si usas Windows):
# Comando de Java wrapper.java.command=java # Clase que ejecutara el Wrapper wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp # Librerias necesarias para ejecutar el programa wrapper.java.classpath.1=../lib/wrapper.jar wrapper.java.classpath.2=servicio.jar # Java Library Path (ubicacion de las librerias wrapper.dll o wrapper.so) wrapper.java.library.path.1=../lib # Java Bits. On applicable platforms, tells the JVM to run in 32 or 64-bit mode. wrapper.java.additional.auto_bits=TRUE # Parametros del programa wrapper.app.parameter.1=net.casidiablo.servicio.Servicio wrapper.app.parameter.2=/tmp/log #******************************************************************** # Wrapper General Properties #******************************************************************** # Allow for the use of non-contiguous numbered properties wrapper.ignore_sequence_gaps=TRUE # Title to use when running as a console wrapper.console.title=servicio #******************************************************************** # Wrapper Windows NT/2000/XP Service Properties #******************************************************************** # Name of the service wrapper.name=jgossip # Display name of the service wrapper.displayname=Servicio # Description of the service wrapper.description=Monitor de memoria # Mode in which the service is installed. AUTO_START or DEMAND_START wrapper.ntservice.starttype=AUTO_START # Allow the service to interact with the desktop. wrapper.ntservice.interactive=false
Explicación del archivo de configuración:
wrapper.java.command=javaes el comando para ejecutar java. En este caso es simplemente java porque estoy en Linux y además tengo configurado correctamente el path. En Windows podría ser algo como: c:\archivos de programa\java\jdk1.6\bin\java.exewrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleAppindica el archivo a ejecutar es la clase WrapperSimpleApp que se usa en la integración sencilla. Esta clase envoltorio es la que permite ejecutar la aplicación como servicio.wrapper.java.classpath.1=../lib/wrapper.jarindican las rutas o archivos del classpath.
wrapper.java.classpath.2=servicio.jarwrapper.java.library.path.1=../libindica el directorio donde se encuentran las librerías a usar.wrapper.app.parameter.1=net.casidiablo.servicio.Servicioestos son los parámetros que se pasarán al programa. Importante: como estamos haciendo la integración simple, el primer parámetro debe ser la clase que contiene el método main de nuestra aplicación.
wrapper.app.parameter.2=/tmp/logwrapper.name=jgossipesta opción es para Windows y define el nombre del servicio en el sistema.wrapper.ntservice.starttype=AUTO_STARTsi estás en windows, define si el servicio quedará configurado para iniciar automáticamente.
4. Probar/Instalar el servicio…
Ahora veremos cómo podemos probar la aplicación para asegurarnos que ha quedado bien configurada antes de proceder con la instalación.
UNIX/Linux
Ejecutamos el script ‘servicio’ que configuramos en el paso 1 y 2 con el parámetro console:
Deberías ver algo como:
wrapper | –> Wrapper Started as Console
wrapper | Java Service Wrapper Community Edition 64-bit 3.3.6
wrapper | Copyright (C) 1999-2009 Tanuki Software, Ltd. All Rights Reserved.
wrapper | http://wrapper.tanukisoftware.org
wrapper |
wrapper | Launching a JVM…
jvm 1 | WrapperManager: Initializing…
Lo detienes presionando Ctrl+C. Ahora, si queremos probarlo como demonio basta con ejecutar los comandos típicos de un demonio en UNIX/Linux:
Starting un servicio que escribe cosas…
$ ./servicio stop
Stopping un servicio que escribe cosas…
Stopped un servicio que escribe cosas.
Para instalarlo basta con crear un enlace simbólico del script en el directorio /etc/init.d y añadirlo al listado de servicios a iniciar; por ejemplo:
sudo rc-update add servicio default
Windows
Para instalarlo en Windows basta con ejecutar el archivo InstallServicio-NT.bat. Puedes verificar que fue instalado correctamente accediendo a la consola de administración de servicios de NT (ejecutas el comando services.msc):
Fuentes y descargas
Aunque en esta entrada no explico cómo hacer la integración avanzada, he preparado un ejemplo completo que puedes descargar en el listado de abajo.
- Puedes encontrar más documentación en la página oficial del proyecto
- Descargar el laboratorio de esta entrada
- Descargar el código fuente del laboratorio
- Descargar código fuente y laboratorio de la integración avanzada
34 Comentarios | deja el tuyo






bueno mi recomendacion es que revices el jar para ver si el main.class esta en el paquete que describiste en las siguientes lineas de wrapper.conf
# Parametros del programa
wrapper.app.parameter.1=paqueteX.Main
pedro el main class si esta en esa ruta porque estoy usando el jar de tu ejemplo incluso lo he decompilado y si figura en la ruta, me parece que el tema va por esta linea en el wrapper.conf:
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
pues se cae luego de levantar el JVM
pero viendo el jar : wrapper.jar si ubico esa clase en esa ruta, este jar porsia esta en mi carpeta: D:\RUTA_APP\bin
donde debo colocar el servicio.jar? yo lo estoy colocando en esa ruta tb
Hola, me parece muy interesante tu post, pero tengo un problemita, descargue el archivo con el laboratorio y el código de ejemplo para la integración avanzada, y viene el código fuente en java, pero no tengo idea de como configurarlo en linux para que funcione, si pudieras ayudarme te lo agradecería.
Saludos
hola
Soy nuevo en el mundo de la programacion en Java, quisiera que si alguien tuviera un tutorial o algo que explicara lo de servicios en Java se lo agradeceria, gracias de antemano.
Un servicio en win es un programa que se ejecuta siempre, la idea de un servicio es que no es necerario que se inicie la sesión en para que el programa parta estos tipo de programas en lo generar se dejan con un loop infinito para que no finalice en ningú momento, o con temporizador para valide cada cierto tiempo.
Si necesitas mas ayuda mandame un correo a pedroinformatico@gmail.com
buenas, fíjate que estuve usando tu tutorial para un trabajo que estoy haciendo, quiero correr mi propio servicio de un programita que tengo en java y seguí todos los pasos, y el servicio si se instala pero al darle start se detiene, y creo que mi problema esta en el archivo conf donde tengo esto:
wrapper.java.command=”C:\\Program Files (x86)\\Java\\jdk1.6.0_21\\bin\\java.exe”
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.java.classpath.1=”C:\\wrapper-windows-x86-64-3.5.4-st\\lib\\wrapper.jar”
wrapper.java.classpath.2=”C:\\testwrapper\\test.jar”
wrapper.java.library.path.1=”C:\\wrapper-windows-x86-64-3.5.4-st\\lib”
wrapper.java.additional.auto_bits=TRUE
#********************************************************************
# Wrapper General Properties
#********************************************************************
wrapper.ignore_sequence_gaps=TRUE
wrapper.console.title=testservice
wrapper.name=jtestservice
wrapper.displayname=ktestservice
wrapper.description=la onda por la cual me van a pagar
wrapper.ntservice.starttype=AUTO_START
wrapper.ntservice.interactive=false
no se si alguien podría ayudarme, se lo agradecería mucho.
saludos. kotaro
Hola Kotaro pero que error envia?
tienes que fijarte que el programa que colocas como como servicio debe estar dentro de un ciclo infinito para que no termine nunca ya que si termina no va a hacer nada mas, estos sistemas se utilizan generalmente para monitoriar algo cada cierto periodo de tiempo.
muchas gracias por contestar, si el programa es un ciclo infinito que crea un archivo de texto, y lo lelna de datos cada 5 segundos, si ejecuto el test.jar funciona perfecto, pero con el servicio al darle start me dice:
the ktestservice service on local computer started and stopped. some services stop automatically if they are not in use by other services or programs.
El problema puede ser que no tienes permiso para ejecutar, verifica que el servicio que montas este seleccionado la opocion “inisiar sesion–>permitir que el servicio interactue con el escritorio”
si si esta activada esa opción, fíjate que probé arruinando ese código de conf, para ver si me daba alguna error de configuración, así como como para saber que tanto depende el servicio de ese archivo, peor el error me lo sigue tirando igual.
estoy utilizando windows 7 de 64-bit y tengo un programa que lo que hace es que cada 10 segundos actualiza un archivo de texto, el programa es infinito, si corro el .jar el programa funciona perfecto, el problema es como hacerlo un servicio…
no se que puede ser intenta probar en otro SO por que no lo he probado en un de 64bit si lo he probado en uno de 32 y funciona perfecto quizas sea eso
ok, muchísimas gracias por la ayuda. intentare en uno de 32-bit. saludos
Buenas, fíjate que tengo una pregunta, de donde obtengo este parámetro?
wrapper.app.parameter.1=net.casidiablo.servicio.Servicio
ya que creo que ese es mi problema, por cierto la versión de 32 bits me dio el mismo error, que hasta ahora el error esta solucionado pero ahora me tira otro que solo me dice que hay errores en la configuración.
Hola mira hay puede que tengas un problema ya que en:
wrapper.app.parameter.1=
tienes que colocar la clase principal osea la que tiene el metodo main incluyendo todos los paquetes que tienes para llegar a esa clase.
ejemplo si tienes el paquete logica y dentro de ese paquete esta el main.
esa linea debe quedar de la sig forma:
wrapper.app.parameter.1=logica.main
cualquier duda puedes enviarme un correo
pedroinformatico@gmail.com
Ola. Muchas gracias por tu aporte me ha servido mucho. Tengo una duda, ¿es posible tener mas de una aplicación corriendo como demonio en un mismo servidor ?
Sí, es posible
Me puedes decir que debo hacer para correr 2 o más app. o si existe algún tutorial que pueda seguir. gracias
ya configure todo y parece estar bien me corre el servivio pero no me aparece la aplicacion que hice ya verifiquie todo en el archivo de conf pero no sale la aplicacion al ejecutarce el servicio
ayuda por que realmente me interesa
ES UNA LASTIMA QUE ESTE TUTORIAL ESTE TAAAN MAL EXPLICADO E IMCOMPLETO