Causas del fracaso escolar en la Facultad de Informática
Fuente: El balrog con alas
10 Comentarios | deja el tuyo
Fuente: El balrog con alas
10 Comentarios | deja el tuyo
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:
Como puedes ver se trata de una aplicación de consola común y corriente. La aplicación consta básicamente de:
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.
UNIX/Linux
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
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”:
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):
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=java es 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.WrapperSimpleApp indica 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.jar
wrapper.java.classpath.2=servicio.jar indican las rutas o archivos del classpath.wrapper.java.library.path.1=../lib indica el directorio donde se encuentran las librerías a usar.wrapper.app.parameter.1=net.casidiablo.servicio.Servicio
wrapper.app.parameter.2=/tmp/log estos 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.name=jgossip esta opción es para Windows y define el nombre del servicio en el sistema.wrapper.ntservice.starttype=AUTO_START si estás en windows, define si el servicio quedará configurado para iniciar automáticamente.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:
Lo detienes presionando Ctrl+C. Ahora, si queremos probarlo como demonio basta con ejecutar los comandos típicos de un demonio en UNIX/Linux:
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:
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):
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.
14 Comentarios | deja el tuyo
Este es un pequeño ejemplo de cómo enviar correos desde Java usando el API de Java Mail. Lo único que necesitaremos es descargar la librería mail.jar de la página de Java Mail y crear un programa de este estilo:
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
public class EnviarMail {
public static void main(String[] args) {
try {
// Se debe crear un archivo de propiedades que
// contenga el nombre del servidor SMTP
Properties props = new Properties();
props.put("mail.host", "mail.servidorcorreo.com");
// se crea un objeto de sesion
Session conexionCorreo = Session.getInstance(props, null);
// este objeto representa el mensaje a enviar
Message mensaje = new MimeMessage(conexionCorreo);
// los objetos Adress contienen informacion de recipientes de correo
Address desde = new InternetAddress("tucorreo@servidorcorreo.biz",
"Pepito Perez");
Address para = new InternetAddress("destinatario@otroservidor.com");
// asignamos el contenido. En este caso usamos 'text/plain' pero
// es posible usar 'text/html' para enviar correos con contenido
// HTML
mensaje.setContent("Este es un mensaje de texto plano!",
"text/plain");
// asignar el origen del correo
mensaje.setFrom(desde);
// asignar un destinatario
mensaje.setRecipient(Message.RecipientType.TO, para);
// asignar el asunto del correo
mensaje.setSubject("Hola, Java Mail!");
Transport.send(mensaje);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Para compilarlo y ejecutarlo desde la consola:
Si estás usando Eclipse, debes añadir la librería mail.jar al classpath. En este artículo explico cómo hacerlo.
15 Comentarios | deja el tuyo