En sistemas Windows aplicaciones Java son ejecutadas en el símbolo del sistema (command prompt). Esto requiere que el usuario de la cuenta este conectado en el sistema todo el tiempo, y que el símbolo del sistema este abierto y en ejecución en una computadora de escritorio.

Esto tiene desventajas, como problemas de seguridad por el hecho de que un usuario este en sesión, el rendimiento del sistema o simplemente tener el riesgo de que un usuario pulse la tecla equivocada en el símbolo del sistema y elimine la aplicación Java.

Java App Server

¿Qué es un Servicio?

Windows tiene la capacidad de ejecutar aplicaciones en segundo plano como un Servicio y resolver estos problemas. Servicios son implementados al iniciar el sistema y no requieren que un usuario este en sesión. Esto aumenta significativamente seguridad y la estabilidad general del sistema, porque no es posible que un usuario pueda detener, iniciar o alterar aplicaciones Java a menos que sea el administrador.

El problema es que Java no se puede ejecutarse como un Servicio por su propia cuenta. Muchas herramientas simples como el comando de Windows sc se puede utilizar para ejecutar Java como un servicio, pero el usuario haciendo algo tan sencillo como cerrar la sesión de la máquina causará que Java sea apagada.

El Java Service Wrapper no solo hace posible pero más fácil de ejecutar cualquier aplicación Java como un Servicio de Windows. También agrega tolerancias a fallos avanzadas (failover), recuperación de errores y funciones de análisis y asegurarse de que su aplicación tenga el tiempo máximo de actividad posible.

Clase Simple de Java HelloWorldServer

En este ejemplo, haremos uso de una aplicación simple HelloWorldServer que nos dejará ejecutarla en segundo plano y conectarse a un cliente usando telnet. Por favor visite la descripción completa de la aplicación para aprender como crear y construir HelloWorldServer para este ejemplo.

A menos que usted realmente desee ejecutar el ejemplo, basta decir que se puede ejecutar con la siguiente línea de comando Java.

Ejecutar el ejemplo:
java -classpath lib\classes HelloWorldServer

Configurando la clase HelloWorldServer

El primer paso es cambiar nuestra clase HelloWorldServer en un Servicio y configurar el Java Service Wrapper para ejecutar nuestra aplicación. Esto se puede hacer con la mayoría de las aplicaciones sin la necesidad de escribir códigos Java.

Estructura del Directorio

El Wrapper es muy flexible y se puede configurar para que funcione con cualquier estructura de un directorio. Para este ejemplo recomendamos una estructura de directorio nueva y que pueda ser reutilizado con aplicaciones que puedan ser complicadas. Reutilizar la siguiente estructura de directorio bajo un directorio arbitrario de su elección. Lo llamaremos directorio raíz %EXAMPLE_HOME%. Este es una extensión de la estructura del directorio que se encuentra en la sección descripción de HelloWorldServer.

Estructura del Directorio:
%EXAMPLE_HOME%\
%EXAMPLE_HOME%\bin\
%EXAMPLE_HOME%\conf\
%EXAMPLE_HOME%\lang\
%EXAMPLE_HOME%\lib\
%EXAMPLE_HOME%\lib\classes\
%EXAMPLE_HOME%\logs\

Descargue el Java Service Wrapper

Por favor descargue la última versión del Java Service Wrapper. Extraer los archivos y guardarlos en el directorio de su elección. Nosotros lo llamaremos %EXAMPLE_HOME%.

Copiar los Archivos del Wrapper

El Java Service Wrapper consiste de tres principales componentes, el Wrapper binario, un archivo jar y una librería nativa la cual es usada por el archivo jar. Es necesario copiar estos tres archivos como se muestra a continuación:

Archivos:
%WRAPPER_HOME%\bin\wrapper.exe -> %EXAMPLE_HOME%\bin\wrapper.exe
%WRAPPER_HOME%\lib\wrapper.jar -> %EXAMPLE_HOME%\lib\wrapper.jar
%WRAPPER_HOME%\lib\wrapper.dll -> %EXAMPLE_HOME%\lib\wrapper.dll

El Wrapper se puede controlar directamente o puede usar los archivos (batch). Estos son explicados en detalle en la siguiente página Implementar en Windows. En este ejemplo vamos a ejecutar el Wrapper directamente.

Internacionalización / Localización:

Si usted desea usar el Wrapper en otro idioma diferente al Inglés necesita copiar los recursos de localización y el directorio lang en su totalidad.

Copiar Archivo:
%WRAPPER_HOME%\lang -> %EXAMPLE_HOME%\lang

Clave de la Licencia:

Las ediciones Estándar y Profesional del Java Service Wrapper requieren una Clave de la Licencia para poder ser ejecutadas. El Wrapper incluye una clave que le dará la oportunidad de ejecutar el Wrapper por solo 15 minutos. Por favor haga uso de esta clave por ahora. Si desea obtener un período de prueba más largo, solo presione el botón Versión de Prueba Gratuita en la parte superior de esta página.

Copiar Archivo:
%WRAPPER_HOME%\src\conf\wrapper-license-time.conf -> %EXAMPLE_HOME%\conf\wrapper-license.conf

Archivo de Configuraciones del Wrapper:

Finalmente copiar el archivo de configuraciones del Wrapper el cual será editado en la siguiente sección.

Copiar Archivo:
%WRAPPER_HOME%\src\conf\wrapper.conf.in -> %EXAMPLE_HOME%\conf\wrapper.conf

Configuración del Archivo del Wrapper

Abrir el archivo %EXAMPLE_HOME%\conf\wrapper.conf en un editor de texto, Notepad es una buena opción. Es necesario localizar y modificar las siguientes propiedades.

Archivo de Configuraciones
wrapper.java.command=java
wrapper.java.command.loglevel=INFO

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=HelloWorldServer

wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../lib/classes

wrapper.java.library.path.1=../lib

wrapper.logfile=../logs/wrapper.log

wrapper.console.title=Hello World Server
wrapper.name=helloworldserver
wrapper.displayname=Hello World Server
wrapper.description=Hello World Server
  • La propiedad wrapper.java.command se usa para especificar la ubicación del comando Java que será usado. El valor que hemos especificado será ubicado en la ruta del sistema, también es posible especificar una ruta absoluta.

  • La propiedad wrapper.java.command.loglevel es opcional, pero es de gran ayuda como método de depuración para la línea de comandos Java que genere el Wrapper. Le recomendamos que incluya esta propiedad cuando inicie su aplicación. Sin embargo, puede inhabilitarla una vez que su aplicación este funcionando sin problemas.

  • La propiedad wrapper.java.mainclass se usa para especificar la clase principal que se pasa a Java cuando es implementada. Este es un punto de confusión para nuevos usuarios, pero en la mayoría de los casos esta clase principal ayuda al Wrapper, en lugar de la clase principal de su aplicación. El Wrapper tiene diferentes métodos de integración para este ejemplo usaremos el método más simple llamado Método de Integración #1 (WrapperSimpleApp). Este método usa la clase org.tanukisoftware.wrapper.WrapperSimpleApp para administrar el ciclo de vida de la máquina JVM y la comunicación externa con el Wrapper. Pero por ahora no se preocupe por este punto.

  • La clase principal de nuestra aplicación HelloWorldServer se pasa como primer parámetro usando la propiedad wrapper.app.parameter.1. Es posible pasar parámetros adicionales a la aplicación HelloWorldServer al agregar propiedades adicionales incrementando índices, por ejemplo: wrapper.app.parameter.2=P1.

    Aunque no se muestra aquí, es posible agregar parámetros Java adicionales usando la propiedad wrapper.java.additional.<n>.

  • El siguiente paso es especificar la ruta de la clase. Esto se puede hacer usando la propiedad wrapper.java.classpath.<n>. Necesitamos dos entradas de la ruta de la clase para nuestra aplicación. La primera es incluir el archivo wrapper.jar el cual incluye las clases auxiliares del Wrapper. La segunda entrada incluye el directorio lib/classes donde la clase HelloWorldServer esta ublicada.

  • El Wrapper usa una librería nativa, wrapper.dll, para implementar algunas de sus funciones. Librerías nativas no son usadas por muchas aplicaciones Java, lo más probable es que aún no haya experimentado esto antes. Las propiedades wrapper.java.library.path.<n> se usan para especificar la ubicación de las librerías. Por ahora no tenemos que preocuparemos por este punto.

De esta manera le hemos dicho al Wrapper que ejecute nuestra aplicación Java. Solo hay un par de propiedades que se necesitan para tener todo listo.

Algo muy importante es tener en mente que todos los valores de las propiedades son especificadas con valores de rutas que son relativos a la ubicación del binario wrapper.exe.

Además de las propiedades que estamos configurando, hay algunos otros elementos claves del archivo de configuración que debemos tener en cuenta.

Ejecutando HelloWorldServer en una Consola

El Wrapper finalmente ha sido configurado, empecemos a probar nuestras funciones en el Símbolo del Sistema de Windows. Por favor abra el Símbolo del Sistema y visite nuestro directorio %EXAMPLE_HOME% con el comando cd. El Wrapper y nuestra aplicación ha sido configurada exitosamente para poder iniciarla como se muestra a continuación:

bin\wrapper.exe -c ..\conf\wrapper.conf

Note que la ubicación del archivo configurado es relativo a la ubicación de la versión binaria del Wrapper. Esta claro que dependiendo de sus necesidades hara uso del Wrapper, pero en realidad incrementa la confiabilidad del mismo al lanzarlo usando diferentes Métodos de Integración.

Cuando el Wrapper inicia verá algo como lo que a continuación se presenta:

wrapper  | --> El Wrapper Inició como Consola
wrapper  | Java Service Wrapper Professional Edition 64-bit {version}
wrapper  |   Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved.
wrapper  |     https://wrapper.tanukisoftware.com
wrapper  |
wrapper  | --------------------------------------------------------------------
wrapper  | Muchas gracias por su interés en el Java Service Wrapper.
wrapper  |
wrapper  | Usted esta ejecutando una Clave de Licencia con todas las funciones
wrapper  | la cual le permitirá ejecutar o reiniciar el Java Service Wrapper
wrapper  | cuantas veces lo necesite. Cada invocación del Wrapper se apagará
wrapper  | automáticamente después de 15 minutos.
wrapper  | 
wrapper  | Esta Clave de Licencia de prueba versión limitada es de gran
wrapper  | ayuda para la configuración rápida de sus pruebas que
wrapper  | se pueden aplicar en diferentes máquinas sin la necesidad de
wrapper  | solicitar una licencia de prueba. Si necesita hacer más pruebas
wrapper  | y desea más tiempo, puede solicitar una extensión e
wrapper  | inmediatamente obtendrá una licencia Gratis hasta por un mes:  
wrapper  |   https://wrapper.tanukisoftware.com/trial
wrapper  |
wrapper  | El Java Service Wrapper requiere una Clave de Licencia para activar
wrapper  | el software. Las Claves de Licencias se pueden comprar en el sitio
wrapper  | web del Java Service Wrapper:
wrapper  |   https://wrapper.tanukisoftware.com/purchase
wrapper  |
wrapper  | Esta Clave de Licencia de prueba tiene como propósito ser usada para
wrapper  | pruebas y desarrollo por lo tanto no debería ser usada como parte de
wrapper  | un entorno de producción. 
wrapper  | --------------------------------------------------------------------
wrapper  |
wrapper  |
wrapper  | Iniciando JVM...
wrapper  | Command: "C:\Sun\jdk1.6.0_10_x64\bin\java.exe" -Djava.library.path="../lib" \
                     -classpath "../lib/wrapper.jar;../lib/classes" -Dwrapper.key="BBXKL6wk_SGpOV-i1z3E6yTeW1NQr62T" \
                     -Dwrapper.port=32000 -Dwrapper.jvm.port.min=31000 -Dwrapper.jvm.port.max=31999 -Dwrapper.pid=464 \
                     -Dwrapper.version="x.y.z" -Dwrapper.native_library="wrapper" -Dwrapper.cpu.timeout="10" \
                     -Dwrapper.jvmid=1 org.tanukisoftware.wrapper.WrapperSimpleApp HelloWorldServer
jvm 1    | WrapperManager: Initializing...
jvm 1    | Accepting connections on port: 9000

El mensaje generado en la parte superior del archivo de registro de valores es porque estamos usando una licencia de prueba temporal. Este le indica donde puede adquirir una licencia temporal con un plazo más largo y también como comprar una licencia, si así lo desea.

La línea larga del Command: es un mensaje de depuración y la salida de datos se podrá ver en la línea de comandos Java, el cual es generada por el Wrapper. Esto es de gran ayuda para resolver problemas, una vez que este haciendo uso del Wrapper inhabilite la propiedad wrapper.java.command.loglevel. El resto de este ejemplo asumirá que ya lo ha hecho.

Si ha adquirido una licencia, esto es lo que observará:

wrapper  | --> El Wrapper Inició como Consola
wrapper  | Java Service Wrapper Professional Edition 64-bit {version}
wrapper  |   Copyright (C) 1999-2013 Tanuki Software, Ltd. All Rights Reserved.
wrapper  |     https://wrapper.tanukisoftware.com
wrapper  |   Licencia concedida a {licensee}
wrapper  |
wrapper  | Iniciando JVM...
jvm 1    | WrapperManager: Initializing...
jvm 1    | Accepting connections on port: 9000

Puede detener su aplicación en cualquier momento presionando CTRL-C. El Wrapper siempre mantiene un registro mostrando por qué una aplicación se detuvo de esta manera verá en su archivo de registro de valores algo como esto:

wrapper  | CTRL-C detectado.  Apagando.
wrapper  | <-- El Wrapper se detuvo

Simulación de un bloqueo (Crash)

Ahora para ver una ejemplo simple de como el Wrapper puede recuperarse de un gran número de errores. Por favor inicie el Wrapper una vez más, abra el Administrador de Tareas Windows, esto se puede hacer presionando simultáneamente CTRL-ALT-DEL.

Observe la pestaña de Procesos y localize el proceso java.exe seleccione y presione Terminar Proceso. Esto le informará a Windows que elimine el proceso Java sin darle una oportunidad de que se apague limpiamente.

Cuando el proceso de Java literalmente muere, usted verá en el archivo de registro de valores del Wrapper algo como lo que a continuación se muestra. Note como el Wrapper detecta que la máquina JVM muere y lanza un reemplazo en segundos.

wrapper  | JVM salió inesperadamente.
wrapper  | Iniciando JVM...
jvm 2    | WrapperManager: Initializing...
jvm 2    | Accepting connections on port: 9000

El archivo de registro de valores se mantiene informado de cuantas veces la máquina JVM ha sido reiniciada. Esto es de gran ayuda para administradores de sistemas y puedan ver de una manera más fácil donde hay problemas simplemente al observar los registros de valores al final del archivo.

Ejecutando HelloWorldServer como un Servicio

Una vez que la configuración del Wrapper ha sido verificada y esta correcta, estamos listos para instalar el Wrapper como un Servicio.

Instalando el Servicio

Esto se puede hacer usando el comando -i de la siguiente manera:

NOTA

Tenga en cuenta que tiene que ser el administrador del sistema para poder hacerlo. En las versiones de Windows 7 y Windows 2008 se necesita que se ejecuten desde la consola con privilegios elevados.

bin\wrapper.exe -i ..\conf\wrapper.conf

Usted verá algo como lo que a continuación se presenta, confirmando que el Servicio ha sido instalado.

wrapper  | Hello World Server service installed.

Iniciando el Servicio

Ahora puede iniciar su Servicio como cualquier otro Servicio de Windows. Se puede llevar a cabo desde el Panel de Control de Servicios [Panel de Control] - [Administrador de Herramientas] - [Servicio]

El Comando de Windows net start también se puede usar:

net start helloworld

Es posible iniciar el Wrapper usando la versión binaria de la siguiente manera:

bin\wrapper.exe -t ..\conf\wrapper.conf

En este caso verá:

wrapper  | Iniciando el servicio Hello World Server...
wrapper  | Hello World Server inició.

Puede cerciorarse que el Servicio este funcionando observando el Panel de Control de Servicios [Panel de Control] - [Administrador de Herramientas] - [Servicio], Administrador de Tareas y el archivo WRAPPER_HOME\logs\wrapper.log.

Detener el Servicio

Cuando desee detener el Servicio, lo puede hacer de la misma manera que se presento anteriormente o también puede hacer uso del Wrapper:

bin\wrapper.exe -p ..\conf\wrapper.conf

Desinstalar el Servicio

El Wrapper esta configurado para iniciar cada vez que el sistema sea reiniciado. En esta ocasión esta es una prueba, tal vez desee remover el Servicio como se presenta a continuación:

bin\wrapper.exe -r ..\conf\wrapper.conf

Referencia: Iniciar su Aplicación con el Wrapper