World Map
Java Service Wrapper is the easiest way to make your product more reliable.
  • Free Trial
  • Buy Now
Ejecución del Wrapper Nativo

Descripción de la Ejecución del Wrapper Nativo

Descripción

La funcción WrapperManager.exec() es una alternativa a Java-Runtime.exec() o Java-ProcessBuilder, que tiene la desventaja de usar el método fork(), que por su vez puede consumir demasiada memoria al crear un nuevo proceso en algunas plataformas. El problema en esas plataformas es que, en el Proceso Padre que quiere iniciar el proceso adicional, fork() hace que el heap de memoria se clone del padre para el hijo. Esto hará con que la memoria usada se duplique por un corto periodo. Con una aplicación relativamente grande que tiene una cuota de memoria similar a la del sistema, se puede fallar al crear una aplicación pequeña como ls, o la memoria será intercambiada en el disco duro (HD), lo que hará que el rendimiento caiga drasticamente.

Otro problema es facilitar la vinculación o separación del proceso hijo del padre mientras se inicia. Si el proceso Java se termina esperada o inesperadamente, el Wrapper limpiará todos los procesos vinculados que aún no se han terminado.

Para mejor consistencia, la funcción WrapperManager.exec() fue implementada lo más as parecido posible a la funcción Runtime.exec() en Java.

Ejecución

Inicio

Esta sección le mostrará inmediatamente como ejecutar un comando. (Más detalles serán explicados paso a paso por la página)

WrapperProcess p = WrapperManager.exec("ls -lisa");

La línea anterior ejecutará un comando ls con los parámetros -l, -i, -s, y -a, y asignar un objecto WrapperProcess representando el proceso.

Si no se ha pasado la ruta completa del archivo binario (o script), el directorio de trabajo actual, así como los directorios PATH del sistema serán verificados, y la primera opción encontrada será ejecutada. También se permite el direccionamiento relativo a partir del directorio de trabajo actual.

NOTA

El comando exec acepta el comando como una Cadena Única (String) o como una Matriz de Cadenas (StringArray). En el caso de un StringArray, cada parámetro es ubicado en un solo campo de matriz.

I/O del Proceso

El proceso hijo creado se ejecuta en segundo plano en el sistema operativo y normalmente no es visible, siempre que no sea una aplicación de GUI (Interfaz gráfica de usuario). Para comunicarse con el proceso, la clase WrapperProcess provee 3 metodos para acceder a la entrada (Input) del processo, así como a la salida (Output) y los mensages de error (ErrorMessages) del proceso.

Se recomienda envolver el StreamObject devuelto con un BufferedReader. Para abrir el lector (Reader), por favor proceda como se describe.

BufferedReader br = new BufferedReader( new InputStreamReader(p.getWrapperProcessInputStream()));

Esto establece el Reader del InputStream en el cual el hijo escribe su salida de datos. Para leer los datos del ErrorStream o escribir datos para el Hijo, por favor proceda como el siguiente ejemplo.

Una vez que el Reader/Writer se ha establecido, podemos leer/escribir de la siguiente forma:

String line;
while ((line = br.readLine()) != null)
{
    System.out.println(line);
}
br.close();

NOTA

Recuerde que al seguir el ejemplo, todos los datos se leerán hasta que el proceso hijo cierre la transmisión de su lado.

Configuración del Proceso Hijo

Al ejecutar un comando, el WrapperManager también le da la posibilidad de configurar el proceso hijo. Esto se hace pasando un objecto WrapperProcessConfig a la funcción exec(). La siguiente sección explicará las configuraciones que pueden ser hechas por WrapperProcessConfiguration.

Proceso Desvinculado

Este campo especifica si el subproceso se ejecutará "desvinculado" del Wrapper. Si se marca el proceso como "desvinculado", el proceso no necesitará terminar quando el Wrapper esté terminando. Si no está marcado, el Wrapper hará un seguimiento del proceso hijo y tratará de finalizar el proceso si el proceso padre debe terminar.

NOTA

Por defecto, los procesos no se iniciarán desvinculados de sus procesos padres.

Tipo de Inicio (Start)

Este campo especifica el tipo de inicio que usará el sistema operativo para iniciar los subprocesos.

ADVERTENCIA

Esta propiedad no es válida en Windows.

  • FORK_EXEC:

    Este es el método más comun de iniciar un proceso hijo en Linux/UNIX. Sin embargo, en algunos sistemas operativos (especialmente Solaris), esta llamada hará que la memoria del padre sea duplicada para el hijo inicialmente. En z/OS, este tipo de inicio no es compatible desde la versión inicial. En sistemas HP-UX, el Wrapper automáticamente usará vfork() en vez de fork().

  • VFORK_EXEC:

    La funcción vfork() solamente es diferente de fork() cuando el proceso hijo puede compartir código y datos con el proceso padre. Esto accelera la actividad de cloneo significantemente, con riesgo a a integridad del proceso padre si vfork() es usado equivocadamente. En algunos sistemas, vfork es igual a fork. En z/OS, este tipo de inicio no es compatible desde la versión inicial.

  • POSIX_SPAWN:

    El proceso se generará y no causará ninguna duplicación de memoria POSIX_SPAWN API. Esto solo está disponible en Linux, Solaris (10+), AIX, z/OS y MacOS.

  • DYNAMIC:

    El tipo de inicio óptimo se seleccionará automáticamente conforme el sistema operativo que se ejecuta el Wrapper. Por favor tenga en cuenta que esta propiedad también implica que no se podrá cambiar el directorio de trabajo porque cambiar el directorio de trabajo no es compatible cuando se usa POSIX_SPAWN. Hay una propiedad experimental wrapper.child.allowCWDOnSpawn que podría ser usada para cambiar el directorio de trabajo.

NOTA

Por defecto, los procesos se iniciarán usando el tipo de inicio DYNAMIC.

Directorio de Trabajo

Este campo especifica el directorio de trabajo de los subprocesos, o "NULL" si el subproceso debe heredar el directorio de trabajo del proceso actual.

Por favor tenga en nota que, al usar POSIX_SPAWN, no es posible configurar el directorio de trabajo directamente. Una solución alternativa sugerida sería ajustar el comando que desee para ejecutarse en un script y ejecutar un cámbio de directorio antes de qye el comando sea ejecutado.

#!/bin/sh

chdir $1
shift
$*

NOTA

Si no se configura esta propiedad, el subproceso heredará el directorio de trabajo de su proceso padre.

wrapper.child.allowCWDOnSpawn

La propiedad wrapper.child.allowCWDOnSpawn controla si el Wrapper intentará cambiar el directorio de trabajo para el tipo de inicio de POSIX_SPAWN y DYNAMIC.

Esta propiedad es experimental y podría generar problemas si el proceso envuelto está usando un Código de Interfaz Nativo de Java e intentaría crear un proceso hijo usando POSIX_SPAWN.

Por defecto, esta propiedad está configurada en FALSE.

Wrapper.child.allowCWDOnSpawn=TRUE

Configurando el Entorno

Este campo especifica el entorno del subproceso creado.

Es campo es una matriz de cadenas, con cada elemento tiendo sus configuraciones de las variables del entorno establecidas en el formato "nombre=valor" (name=value).

NOTA

Si no se configura esta propiedad, el subproceso heredará el entorno de su proceso padre.

Especificando un soft timeout para terminar un proceso hijo

Desde la versión Wrapper 3.5.5, también es posible especificar un soft timeout para cada proceso individualmente. El Wrapper le dará al proceso hijo la oportunidad de terminar por sí mismo con gracia, mientras que por ejemplo, el método java.lang.Process.destroy() siempre causará un cierre forzado, no le dando al proceso ninguna posibilidad de cerrar por sí mismo. Antes de la versión Wrapper 3.5.5, el timeout siempre era de 5 segundos, y para mantener la funccionalidad consistente, el valor por defecto es 5 segundos.

The timeout can be specified during the child process creation with the WrapperProcessConfig class.

WrapperProcessConfig wpConfig = new WrapperProcessConfig().setSoftShutdownTimeout(10);

La configuración del ejemplo anterior le dirá al Wrapper que espere hasta 10 segundos por cualquier proceso hijo que fue creado con esa configuración. Si los procesos hijos no terminen después de 10 segundos, el Wrapper los cerrará a la fuerza.

Los valores siguientes son acceptables para timeout:

  • >0:

    El número de segundos que el Wrapper espera para que el proceso hijo termine espera a que el proceso secundario salga graciosamente antes de la terminación forzada.

  • 0:

    El Wrapper forzará instantáneamente la terminación del proceso hijo.

  • -1:

    El Wrapper nunca forzará la terminación del proceso hijo, pero aguardará indefinidamente que el proceso hijo termine por si solo.

Creando un Proceso Hijo para el Usuario Activo

En Windows, WrapperProcessConfig.setCreateForActiveUser(boolean) puede ser usado para especificar si los procesos hijos deben ser iniciados en la sesión activa actual, en vez de la sesión en que el servicio se está ejecutando (una sesión en la cual el usuario tiene el privilegio SE_TCB_NAME en el sistema operativo). En plataformas diferentes de Windows, o cuando iniciado en modo Consola, la configuración será ignorada silenciosamente.

El valor está configurado en FALSE por defecto.