Solución de Problemas: Problemas

Solución de Problemas: Soluciones

Mi programa no se está ejecutando tan rápido como esperado.

En general, una aplicación monitoreada con el Wrapper debe ejecutarse tan rápido como lo hace cuando se ejecuta independiente. A continuación le damos algunos lugares para empezar a buscar.

Salida de Datos de la Consola

En algunas plataformas, incluyendo Windows, el envío de grandes cantidades de texto a System.out o System.err hará que el programa reduzca su velocidad. Esto es porque toda la salida de datos está siendo enviada a la pantalla en un entorno gráfico GUI. Esto es en realidad el sistema operativo que está consumiendo el CPU en lugar del Wrapper o su aplicación, pero el resultado final es el mismo.

Para reducir significativamente este efecto, utilice una herramienta de registro de datos que generará la salida a un archivo en lugar de stdout. De este modo, la salida de datos no es enviada nunca al Wrapper o a la consola del usuario, dando como resultado la reducción de dicha carga.

Otra opción que es igual de afectiva es configurar el nivel de registro de datos del Wrapper, usando la propiedad wrapper.console.loglevel, de modo que la salida de datos sólo se envíe al archivo de registros del Wrapper. La salida de datos de la consola está desactivada por defecto cuando se ejecuta como un servicio de Windows y la consola no ha sido activada.

Memoria

Asegúrese de que su sistema tiene suficiente memoria física para que la máquina JVM pueda ser ejecutada sin hacer ningún cambio de disco (memoria virtual en el disco duro). Debido a la forma en que Java maneja la memoria, la velocidad que se llegue a generar será normal, simplemente porque Java se ve obligado a almacenar y recuperar datos en grandes cantidades de su memoria, al tratar de realizar una recolección de elementos no utilizados (garbage collection).

Documentación de Oracle

Otro buen lugar para buscar es en la página Performance Documentation for the Java HotSpot VM (Documentación de rendimiento para Java HotSpot VM, en inglés) en el sitio web de Oracle. También recomendamos que visite este enlace sobre JDC Tech Tip talking about "Garbage Collection" (JDC Tech Tip hablando de Garbage Collection, en inglés).

Estoy recibiendo una advertencia de que el Wrapper no puede cargar su librería nativa.

Algunos usuarios han preguntado sobre el siguiente mensaje que aparece en su archivo wrapper.log:

WrapperManager: ERROR - Unable to load the Wrapper's native library because none of the
WrapperManager:         following files:
WrapperManager:           wrapper-windows-x86-64.dll
WrapperManager:           wrapper.dll
WrapperManager:         could be located on the following java.library.path:
WrapperManager:           E:\myworkspace\tortoise\wrapper\wrapper_3.5.x\professional\bin\..\lib
WrapperManager:         Please see the documentation for the wrapper.java.library.path
WrapperManager:         configuration property.
Este mensaje se muestra porque el componente Java del Wrapper no pudo cargar sus librerías nativas durante la inicialización. Si visita su archivo wrapper.conf, podrá ver la propiedad wrapper.java.library.path. Esta propiedad se utiliza para especificar el directorio en el que el Wrapper buscará para encontrar su librería nativa (Windows: wrapper.dll, Linux/UNIX: libwrapper.so). Usted debe colocar el archivo de la librería en el directorio especificado o cambiar la propiedad para especificar el directorio en donde se encuentra la librería.

Si usted está usando el Delta Pack, asegúrese que la librería correspondente a su plataforma está localizada en el directorio especificado.

Mi aplicación no inicia. ¿Qué puedo hacer para reducir el problema?

La salida de datos describiendo el problema se debe mostrar en la consola, así como el archivo de registro de valores registrado. Para una salida de datos más detallada, edite su archivo wrapper.conf y habilite la depuración descomentando la propiedad wrapper.debug. Al hacer esto, se mostrará una salida de datos más detallada de cada paso en el proceso de ejecución y monitoreo de su aplicación.

Si la aplicación funciona cuando no utiliza el Wrapper, pero falla con el Wrapper, es muy probable que exista un problema en la forma en la que ha configurado el archivo wrapper.conf. Por favor revise cuidadosamente el comando utilizado para iniciar Java y analize la salida de datos generada al ejecutar el proceso de depuración. Es posible que haya un error en el classpath.

No estoy recibiendo salida de datos en el archivo de registro configurado.

Es posible que el Wrapper no sea capaz de localizar el archivo de configuración del Wrapper especificado o que por alguna razón no sea capaz de abrir el archivo de registro de datos configurado. En cualquier caso, el Wrapper registrará la salida de datos a un archivo llamado wrapper.log en el directorio de trabajo actual. Lo más probable es que el directorio de trabajo actual sea el directorio que contiene el Wrapper binario. Sin embargo, en algunos casos cuando se ejecuta como un Servicio de Windows, el archivo wrapper.log puede ser colocado en el directorio del sistema (WinNT\System32).

Mi aplicación deja de funcionar mientras se está apagando.

Al invocar System.exit() en su aplicación, el Wrapper lo detectará y tratará de apagar la aplicación limpiamente. Si durante el proceso de apagado, la aplicación invoca una vez más System.exit(), dicha invocación se bloqueará indefinidamente, causando que su aplicación se congele. También surgirán problemas al invocar al método destroy() en un frame de AWT (del inglés Abstract Window Toolkit, en español Kit de Herramientas de Ventana Abstracta) o ventana desde el interior de un Shutdown Hook en secuencia. Para obtener más información sobre cómo evitar este problema, por favor eche un vistazo a la propiedad wrapper.disable_shutdown_hook en Descripción de Configuraciones.

Mi JVM se cuelga cuando se apaga después de hacer un volcado de subprocesos.

El problema puede ser generado al configurar la propiedad wrapper.java.command a un archivo batch en lugar de hacerlo directamente en java.exe. Al solicitar un volcado de subprocesos, la señal de "BREAK" es enviada al proceso command.exe/shell en lugar de ser enviado al proceso Java. Entonces, envia la señal a la máquina JVM configurando un indicador interno informando que se ha presionado CTRL-C. Cuando el proceso hijo Java termina, inmediatamente se le pregunta al usuario si desea detener o continuar el batch script.

INFO   | jvm 1    | 2009/10/23 14:30:35 | WrapperManager Debug: Sent a packet STOPPED : 0
INFO   | jvm 1    | 2009/10/23 14:30:36 | Terminate batch job (Y/N)?
ERROR  | Wrapper  | 2009/10/23 14:30:56 | Shutdown failed: Timed out waiting for the JVM to terminate.
ERROR  | Wrapper  | 2009/10/23 14:30:56 | JVM did not exit on request, terminated
STATUS | Wrapper  | 2009/10/23 14:30:57 | <-- Wrapper Stopped

Si necesita efectuar procesos adicionales antes o después de que la máquina JVM sea iniciada, la edición Profesional del Java Service Wrapper tiene la capacidad de hacer exactamente eso: Configuración de Eventos.

No puedo usar la llamada API WrapperManager.requestThreadDump (Error 0x57)

Este problema es similar y causado por la misma razón que se mencionó anteriormente.

INFO   | jvm 1    | 2009/10/23 14:35:48 |  WrapperJNI Error: Unable to send BREAK event to JVM process: The parameter is incorrect. (0x57)

Si necesita efectuar procesos adicionales antes o después de que la máquina JVM sea iniciada, la edición Profesional del Java Service Wrapper tiene la capacidad de hacer exactamente eso: Configuración de Eventos

JBoss 6.* está generando una gran cantidad de errores "ERROR: Error installing to..." al iniciar y ejecutar mi aplicación con el Wrapper

INFO   | jvm 1    | 2011/01/06 17:23:05 | ERROR: Error installing to Configured: name=ServiceBindingManager state=Configured
INFO   | jvm 1    | 2011/01/06 17:23:05 | java.lang.Exception: Error calling callback JMXRegistrationAdvice for target context ServiceBindingManager
...

La versión 6 de JBoss utiliza internamente una MBeanServer Factory basada en org.jboss.system.server.jmx.MBeanServerBuilderImpl. Sin embargo, esta no es compatible con la máquina predeterminada JVM MBeanServerBuilder (javax.management.MBeanServerBuilder).

Hay dos opciones disponibles para solucionar esto. La primera opción es inhabilitar el registro de los MBeans del Wrapper. Para usar esta opción, por favor visite Método de Integración 1. La segunda opción es informar a la máquina JVM que use la MBeanServer Factory que JBoss está usando. Puede encontrar mas información visitando la página JMX.

El Wrapper está reportando un error/advertencia de validación al iniciar.

wrapper  | A signature was found in "C:\wrapper-windows-x86-64-3.5.54-pro\bin\wra
pper.exe", but checksum failed: (Errorcode: 0x800b010a) 
A certificate chain could not be built to a trusted root authority. (0x800b010a)
wrapper  |   Signer Certificate:
wrapper  |     Serial Number:
wrapper  |       00 bf de 76 64 f1 1a d5 f3 dd af a7 e4 d7 c7 0f 5e
wrapper  |     Issuer Name: Sectigo RSA Code Signing CA
wrapper  |     Subject Name: Tanuki Software Ltd.
wrapper  |   TimeStamp Certificate:
wrapper  |     Serial Number:
wrapper  |       39 4c 25 e1 7c a0 6d 27 a8 65 e2 3b d9 1d 22 d4
wrapper  |     Issuer Name: Sectigo RSA Time Stamping CA
wrapper  |     Subject Name: Sectigo RSA Time Stamping Signer #4
wrapper  |     Date of TimeStamp: 2023/05/12 06:24:23
wrapper  | The Wrapper will shutdown!

A partir de la versión Wrapper 3.5.7, todos los binarios de Windows (por ejemplo wrapper.exe, wrapperW.exe y wrapper.dll) de todas las ediciones del Wrapper (Comunidad, Estándard y Profesional) están firmados para verificar que el archivo provenga de Tanuki Software.

A partir de la versión Wrapper 3.5.28, el Wrapper está firmado con un certificado SHA-2, que provee más seguridad que el algoritmo SHA-1 usado anteriormente. La decisión de cambiar el certificado se hizo de acuerdo con el plan de depreciación de SHA-1 de Microsoft, el cual establece que Windows 7 y posteriores no soportarán a SHA-1 después del 1er de enero de 2016.

El error anterior ocurre cuando los certificados de nuestro contrafirmante 'Sectigo' no están instalados correctamente.

Los certificados deben ser instalados en un almacén accesible a la cuenta en la cual el Wrapper está siendo ejecutado. Si el Wrapper se ejecuta como una aplicación de consola, esta puede ser el usuario actual. Cuándo es ejecutado como un servicio de Windows, debe ser accesible por la cuenta de servicio que utiliza. Una alternativa a esto es instalar el certificado en la máquina local para que esté accesible en ambos modos.

Los certificados instalados pueden ser investigados desde el Administrador de Certificaciones de Windows (Windows Certificate Manager) certmgr.msc (para el usuario actual) or mmc (para cualquier usuario).

Para administrar los certificados de una cuenta específica, inicie 'mmc' desde el cuadro de búsqueda y ejecución de Windows. En el menu Archivo, elija 'Agregar o quitar complemento' (Add/Remove Snap-in), y haga doble clic en 'Certificados'. Usted puede elejir administrar los certificados del usuario actual (current user), de una cuenta de servicio (service account) o la cuenta de equipo (computer account). Para a cuenta de servicio, una lista aparecerá con todos los servicios instalados en la computadora. Por favor seleccione el nombre usado al instalar el Wrapper como servicio.


Puede descargar los certificados en la siguiente página:

https://www.sectigo.com/knowledge-base/detail/Sectigo-Intermediate-Certificates/kA01N000000rfBO

Los enlaces para descargar los certificados se encuentran bajo la sección "Code Signing - Intermediate". Por favor, use los certificados estándar (Standard).

Para las versiones 3.5.46 y más recientes del Wrapper, puede utilizar los enlaces 'Standard' bajo 'For Code Signing Certificates, issued on or after June 1, 2021' para descargar.

Ambos los certificados 'Sectigo Public Code Signing CA R36' y 'SectigoPublicCodeSigningRootR46_AAA [ Cross Signed ]' se pueden usar con el Wrapper. Puede encontrar una descripción detallada de lo que son los certificados raíz, intermedios y cross-firmados en la siguiente página en el sitio de Sectigo (en inglés):

https://support.sectigo.com/articles/Knowledge/Sectigo-Chain-Hierarchy-and-Intermediate-Roots

Para instalar los certificados para el usuario actual, es posible con somente ejecutar el archivo .crt y seguir los pasos de instalación. Para importarlos a un usuario de servicio, use 'mmc' y adicione el snap-In como se describe anteriormente. Seleccione cualquier almacén (con el ícono de carpeta) abajo de este snap-In en el panel izquierdo y haga clic el menú 'Acción > Todas las tareas > Importar' (Elija la opción "Seleccionar automáticamente el almacén de certificados según el tipo de certificado").


Si el error persiste, esto puede significar que la Política de Seguridad Local es muy estricta para permitir que la certificación sea verificada. Esta configuración se puede encontrar en la Política de Seguridad Local del servidor. Inicie 'secpol.msc' desde el cuadro de búsqueda y ejecución de Windows, haga clic en "Directiva de Clave Pública", después en "Configuración de validación de rutas de certificados". En la pestaña 'Almacenes', asegúrese que "CA raíz de terceros y CA raíz de empresa" está marcada si la configuración de directiva está definida. Si eso no está activado/no se puede activar, una otra opción seria mover el "UTN-USERFirst-Object Certificate" desde la carpeta "Entidades de certificación raíz de terceros" a la carpeta "Entidades de certificación raíz de confianza".


Desde la versión Wrapper 3.5.34, los binarios del Wrapper son doblemente firmados con algoritmos hash SHA-1 y SHA-2 para permitir una verificación más robusta a nivel del sistema operativo. Para verificar los algoritmos y las marcas de tiempo, haga clic derecho en los binarios y abra la ventana "Propiedades" de la ventana del menú contextual y seleccione la pestaña "Firmas digitales":

Tenga en cuenta que el algoritmo hash SHA-256 no aparecerá en las versiones antiguas de Windows en que este algoritmo no es compatible. Microsoft publicó una actualización para Windows 7 y Windows Server 2008 R2 para añadir el soporte a SHA-2. Si esta actualización está presente, podrá verificar el hash SHA-2, pero si no se encuentra, solamente podrá verificar el hash SHA-1. Versiones más recientes de Windows no necesitan esta actualización, ya que ya soportan SHA-256, pero versiones más antiguas (Windows XP, Vista, Windows Server 2008) solamente pueden verificar hashes SHA-1.

Se puede confirmar que una firma digital es válida haciendo clic en la lista de firmas:

¿Por qué el Wrapper está intentando acceder a un servidor Sectigo externo?

El Wrapper en si no intenta acceder al servidor Sectigo o a otros servidores, pero a partir de la versión Wrapper 3.5.7, los binarios de Wrapper ahora son firmados con un certificado Sectigo. Esto es importante para ayudar al sistema operativo a verificar que los binarios son realmente de Tanuki Software.

Cuando Windows intenta iniciar un binario con firma, primero comprobará el binario para comprobar que coincide con la firma y asegurarse de que el binario no haya sido alterado. Normalmente, el certificado Sectigo necesita verificar que el binario existe en una máquina Windows, pero en algunos casos, es necesario conectarse a internet y bajarlo desde una ubicación conocida. La conección parece ocorrer mientras el Wrapper se inicia, pero en verdad eso ocurre antes de que el Wrapper realmente inicie. Sin embargo, puede parecer que el Wrapper es el que está haciendo la conexión. Hemos tenido informes de los siguientes servidores a los que se accede de esta manera: ocsp.comodoca.com, a125-56.204-123.deploy.akamaitechnologies.com (La porción IP de los servidores akamai varían según la solicitud).

Si esto causa alguna preocupación con los clientes, entonces una opción en las ediciones Estándar y Profesional es Personalizar el binario de su Wrapper, ya que este proceso remueve la firma. Sin embargo, al hacerlo, eliminará la capacidad del sistema operativo de verificar la autenticidad del binario.

Solo puedo ejecutar -N- servicios en Windows.

El Wrapper en sí no pone ninguna restricción sobre el número de instancias que se ejecuten en Windows al mismo tiempo, pero como el Wrapper y especialmente Java consumen varios recursos, esto puede poner límites a las instancias que pueden ejecutarse en un dado sistema. El recurso más común que causa problemas es el Desktop Heap (heap de escritorio). Para más información, por favor visite la página ¿Cómo investigar y solucionar problemas de Windows Desktop Heap?.

¿Cómo puedo especificar las nuevas opciones de Java 9 que requieren argumentos (como las usadas para especificar módulos)?

Java 9 introduce varias opciones (como --module-path o --add-modules) que requieren ser especificadas con un argumento. Normalmente, se separa el argumento del nombre de la opción con un espacio, pero cualquier espacio dentro de los valores de las propiedades wrapper.java.additional.<n> son interpretados como parte del valor del argumento, y no como un delimitador. Una solución es separar el nombre de la opción y el argumento usando un símbolo de igual (=) en lugar del espacio.

wrapper.java.additional.1=--add-modules=MODULE1,MODULE2

Tenga en cuenta que esto solo será posible con las opciones largas (que empiezan con '--') y no con sus equivalentes opciones cortas. Por ejemplo, '-p=<PATH>' no es permitido ('-p' siendo un alias corto de '--module-path').

Otra solución que le permite usar ambos espacios y alias cortos es usar la variable de entorno JDK_JAVA_OPTIONS. El contenido de esta variable es añadido a las opciones de la línea de comando por la máquina JVM. Usted puede configurar usando la siguiente sintaxis en el archivo de configuración del Wrapper:

set.JDK_JAVA_OPTIONS=--add-modules MODULE1,MODULE2

Recuerde que, sin embargo, no será posible visualizar el contenido de JDK_JAVA_OPTIONS al imprimir la salida de la línea de comando Java (usando la propriedad wrapper.java.command.loglevel), ya que solamente es analizado por la máquina JVM cuando ésta es lanzada.

Para más información sobre las opciones largas y la variable JDK_JAVA_OPTIONS, visite el sitio web de Oracle.

¿Cómo puedo resolver inicios lentos en Linux debido al generador de números aleatorios?

Las aplicaciones Java que hacen llamadas a java.util.Random.nextLong() u otros métodos aleatorios pueden ser muy, muy lentas la primera vez que son llamadas. Esto se debe a una falta de entropía en el sistema. La llamada se bloqueará hasta que dicha entropía se haya acumulado lo suficiente como para regresar un buen número. Desafortunadamente, en el inicio cuando nada más está sucediendo, esto puede llevar mucho tiempo, durante el cual su aplicación parecerá estar congelada.

La única manera de detectar si esto está sucediendo o no es emitir una solicitud de volcado de subprocesos mientras se espera. Si esta es la causa, debería ser capaz de verlo fácilmente.

Una vez que se haya identificado el problema, una solución que encontramos es añadir la propiedad siguiente a su configuración. Esto cambia la forma en que Java genera datos aleatorios a un método que siempre es rápido. No hacemos afirmaciones sobre cómo esto afecta a la seguridad, así que por favor investigue esto y háganos saber si tiene una solución mejor. Asegúrese de usar un número que no se superponga con su configuración existente:

# Solve slow random initialization on Linux
wrapper.java.additional.20=-Djava.security.egd=file:/dev/./urandom

Esta es una solución específica para la plataforma. Si necesita tener una configuración independiente de la plataforma, entonces por favor cree un segundo archivo wrapper-linux.conf:

#encoding=UTF-8
# Solve slow random initialization on Linux
wrapper.java.additional.20=-Djava.security.egd=file:/dev/./urandom

Entonces, incluya eso basado en la plataforma de su archivo de configuración principal. En tales casos, sugerimos que se añada un comentario en el archivo de configuración principal para asegurarse de que la propiedad numerada no se reutilize por error.

#encoding=UTF-8
#include ../conf/wrapper-%WRAPPER_OS%.conf
...
# Solve slow random initialization on Linux
#wrapper.java.additional.20= # Reserved for use in wrapper-linux.conf