Windows permite asignar unidades de servidores de red a letras de unidad locales para que los usuarios puedan acceder a ellas como si se tratara de una unidad local. Se trata de una función muy potente de Windows, de la que se aprovechan muchas aplicaciones.

El problema, sin embargo, es que Windows no es muy consistente acerca de cómo maneja dichas unidades asignadas cuando se accede desde un servicio de Windows. Cuando el servicio se inicia manualmente, las unidades estarán disponibles, pero cuando se reinicie el sistema, el servicio ya no podrá acceder a ellas.

El Java Service Wrapper proporciona una forma sencilla de indicarle al servicio que asigne unidades de red cuando no estén disponibles. De este modo, se puede acceder a ellas de forma fiable en cualquier momento.

Solución

La solución es permitir que el servicio asigne sus propias unidades. El Java Service Wrapper proporciona un conjunto flexible de propiedades que hacen posible asignar unidades de red e impresoras al inicio. De este modo, las aplicaciones Java podrán hacer uso de estos recursos compartidos de forma fiable, independientemente del momento en que se inicie el servicio.

En Windows, los recursos compartidos de red se pueden asignar a letras de unidad para que se pueda acceder a ellos como si fueran unidades locales. Muchas aplicaciones hacen uso de esta capacidad para acceder sin problemas a los archivos que se comparten en la red.

Sin embargo, cuando una aplicación de este tipo se convierte en un servicio, el acceso a las unidades asignadas dejará de ser fiable porque la asignación sólo se realiza potencialmente en la sesión del usuario. Están disponibles en algunos casos pero no en otros, dependiendo de cuándo se inicia el servicio y quién estaba conectado/a a la máquina en ese momento.

Descripción Técnica

Compatibilidad :3.5.0
Ediciones :Edición ProfesionaEdición EstándarEdición de la Comunidad (No Compatible)
Plataformas :WindowsMac OSX (No Compatible)Linux (No Compatible)IBM AIX (No Compatible)FreeBSD (No Compatible)HP-UX (No Compatible)Solaris (No Compatible)IBM z/Linux (No Compatible)

Es posible configurar un Servicio de Windows para que se ejecute como una cuenta específica. Sin embargo, las unidades asignadas que se configuren en esa cuenta no estarán disponibles cuando el sistema se inicie por primera vez y, por lo tanto, no estarán disponibles para el servicio. Si un usuario se conecta con la misma cuenta, las unidades se configurarán, pero aún no estarán disponibles para el servicio a menos que se reinicie por completo.

Tradicionalmente, esto significaba que era necesario tener acceso a archivos en la red usando UNC (Convención de nomenclatura uniforme):

\\myfileserver\commonshare\myfiles\data.txt

Esta sintaxis UNC funciona con algunas aplicaciones, pero no es tan conveniente ni portátil como una unidad asignada:

S:\myfiles\data.txt

Muchas aplicaciones que originalmente no fueron diseñadas para ejecutarse como un servicio de Windows, o que acceden a unidades de red, fallarán cuando encuentren una ruta UNC en un archivo de configuración.

El Java Service Wrapper facilita el acceso de los servicios a los recursos compartidos. Con solo un conjunto de propiedades "share" (de recursos compartidos), puede configurar fácilmente asignaciones a ubicaciones o impresoras remotas y ponerlas a disposición de la cuenta en ejecución antes de que se inicie la aplicación Java.

Asignación Simple de Recursos Compartidos Públicos

Muchas organizaciones disponen de unidades compartidas comunes que pueden ser utilizadas por cualquier persona con acceso a la red a través de una cuenta de invitado. Estos son, con diferencia, los más fáciles de configurar, ya que sólo requieren una ubicación a la que asignar, y la letra de la unidad (alfabeto que indica una unidad) a la que asignarla.

Ejemplo de Configuración:
wrapper.share.1.location=\\myfileserver\commonshare
wrapper.share.1.target=S:
wrapper.share.1.type=DISK
Ejemplo de Registro de Asignación a la Unidad "S":
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  | Mapped "S:".

Una vez que esto esté configurado, la aplicación podrá acceder a la Unidad S: del mismo modo que a cualquier otra unidad local. Este es un ejemplo muy sencillo que no proporciona credenciales de autenticación, no maneja fallos de conexión ni especifica qué hacer con la unidad asignada cuando el servicio se detiene.

Asignación de Recursos Compartidos Públicos con Autenticación

Es común que las unidades de red estén protegidas por una contraseña y que solo se permita el acceso a cuentas específicas. El Wrapper permite especificar una cuenta específica para conectarse y, opcionalmente, asignar una contraseña para la cuenta.

Ejemplo de Configuración:
wrapper.share.1.location=\\myfileserver\commonshare
wrapper.share.1.target=S:
wrapper.share.1.type=DISK
wrapper.share.1.account=domain\user
wrapper.share.1.password=password

Si la cuenta de usuario que ejecuta el Wrapper tiene acceso a la red compartida, es posible que no sea necesario especificar una cuenta y una contraseña aunque el acceso a la red esté restringido. Esto es posible porque Windows puede reutilizar la información de autenticación de la cuenta actual cuando se conecta a la red compartida.

Ejemplo Asignando la Unidad de Red "S":
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  | Mapped "S:".

Windows asigna letras únicas a las unidades para asignar recursos y servicios. Si por alguna razón una letra de unidad ya está en uso, el Wrapper reacciona automáticamente apagando (SHUTDOWN) o continuando (CONTINUE) el inicio de la JVM y asignando una letra 'Y:' de unidad de red diferente.

Por defecto, el Wrapper intentará conectarse varias veces a una Unidad de Red. Si esto no es posible debido a errores desconocidos o similares, las opciones a seguir son desasignar (UNMAP) la Unidad o apagar (SHUTDOWN). Por otro lado, el Wrapper se asegura de que no haya archivos abiertos en ese momento antes de desconectarse y luego continuar.

Manejar un Fallo de Asignación

Siempre que haya más de un servidor o una red involucrados, existe la posibilidad de que algo salga mal. Si se trata de un problema temporal, el Wrapper por defecto intentará conectarse hasta 5 veces antes de continuar.

Ejemplo de Registro de Salida:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Attempt #1 (The network name cannot be found. (0x43))
...
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Trying to continue. (The network name cannot be found. (0x43))

Pero si el recurso compartido de red es crítico para el funcionamiento del servicio, lo mejor es que el Wrapper no se inicie.

Ejemplo de Configuración:
wrapper.share.1.startup.failure=SHUTDOWN
Ejemplo de Registro de Salida:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Attempt #1 (The network name cannot be found. (0x43))
...
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Shutting down. (The network name cannot be found. (0x43))
wrapper  | <-- Wrapper Stopped

Es posible controlar cuántas veces el Wrapper reintenta el mapeo, así como cuánto tiempo debe esperar entre cada intento. Es posible controlar cuántas veces el Wrapper vuelve a intentar la asignación, así como cuánto tiempo esperar entre cada intento. Tenga en cuenta que no se realizarán reintentos para problemas que sean permanentes.

Ejemplo de Configuración:
wrapper.share.1.startup.max_retries=2
wrapper.share.1.startup.retry_interval=10

Manejar un Recurso Compartido Preasignado

Es bastante común que un recurso compartido de red se asigne con el Wrapper a una unidad que normalmente es asignada por un usuario conectado. Cuando esto sucede, es posible que el servicio se inicie con la unidad ya asignada.

Ejemplo de Registro de Salida:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   "S:" is already defined.  Trying to continue

El problema con esto es que no se puede estar 100% seguro de que la unidad esté asignada al servidor correcto. Si esto le preocupa, la mejor opción es cancelar el inicio del servicio.

Ejemplo de Configuración:
wrapper.share.1.startup.premapped=SHUTDOWN
wrapper.share.1.startup.max_retries=2
wrapper.share.1.startup.retry_interval=10
Ejemplo de Registro de Salida:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   "S:" is already defined.  Shutting down.
wrapper  | Leave "S:" mapped.
wrapper  | <-- Wrapper Stopped

Desasignación Durante el Apagado

Por defecto, el Wrapper dejará los recursos compartidos de red asignados cuando se apague. Esta suele ser la mejor opción, ya que otros usuarios o aplicaciones pueden utilizar los recursos compartidos.

Ejemplo de Registro de Salida:
wrapper  | Leave "S:" mapped.
wrapper  | <-- Wrapper Stopped

A veces, es posible que desee asegurarse de que la unidad no esté asignada al apagar.

Ejemplo de Configuración:
wrapper.share.1.shutdown.unmap=TRUE
Ejemplo de Registro de Salida:
wrapper  | Unmapped "S:".
wrapper  | <-- Wrapper Stopped

Si el recurso compartido no ha sido asignado por la instancia del Wrapper actual, éste se mantendrá asignado.

Ejemplo de Registro de Salida:
wrapper  | Leave "S:" mapped.
wrapper  | <-- Wrapper Stopped

Si existen archivos abiertos en el recurso compartido, es posible que la desasignación también falle. Si se desea, se puede forzar la desasignación. Tenga en cuenta que el Wrapper aún dejará el recurso compartido si éste no fue asignado por la instancia actual del Wrapper.

Ejemplo de Configuración:
wrapper.share.1.shutdown.unmap=TRUE

Asignación de una Impresora de Red

Las impresoras que están ubicadas en una máquina remota también se pueden asignar del mismo modo que una unidad. La diferencia es que se especifica un puerto de impresora en lugar de una letra de unidad.

Ejemplo de Configuración:
wrapper.share.1.location=\\myserver\printer
wrapper.share.1.target=LPT2:
wrapper.share.1.type=PRINTER
Ejemplo de Registro de Salida:
wrapper  | Attempting to map the "\\myserver\printer" share to "LPT2:"...
wrapper  |   Mapped "LPT2:".

Posibles Problemas

Hay una serie de problemas bastante comunes que es probable que encuentre al asignar recursos compartidos de red.

Servidor no encontrado.

Si el servidor está fuera de servicio o hay problemas de red, es posible queel intento de conexión falle.

Ejemplo de Registro de Salida de Error de Asignación:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Attempt #1 (The network name cannot be found. (0x43))
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Trying to continue. (The network name cannot be found. (0x43))

Si no especifica específicamente el tipo de recurso compartido como "DISCO" (DISK), Windows no podrá distinguir si está intentando conectarse a un Disco o a una Impresora, y el mensaje de error tendrá este aspecto:

Ejemplo de Registro de Salida de Error de Asignación:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Trying to continue. (The network resource type is not correct. (0x42))

Acceso Denegado

Si la cuenta configurada o código de acceso son incorrectos, entonces la asignación de unidad no será posible y recibirá un mensaje como el que a continuación se presenta. Verifique con su administrador de sistema para asegurarse de que la información de conexión es correcta.

Ejemplo de Registro de Salida de Error de Asignación:
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Trying to continue. (Access is denied. (0x5))

Depuración

Si la asignación no funciona como se espera, intente habilitar la depuración de salida de datos.

Ejemplo de Configuración:
wrapper.debug=TRUE

La salida de depuración incluirá la confirmación de la configuración y proporcionará información adicional sobre lo que el Wrapper está tratando de hacer.

Ejemplo de Registro de Salida de Error de Asignación:
wrapper  | Network Mapping Details:
wrapper  |   Location:         \\myfileserver\commonshare
wrapper  |   Target:           S:
wrapper  |   Account:          domain\user (Password: password)
wrapper  |   Type:             ANY
wrapper  |   Startup:
wrapper  |     On Failure:     CONTINUE
wrapper  |     On Premapped:   CONTINUE
wrapper  |     Max Retries:    5
wrapper  |     Retry Interval: 10
wrapper  |   Shutdown:
wrapper  |     Unmap:          FALSE (Force: FALSE)
wrapper  | Attempting to map the "\\myfileserver\commonshare" share to "S:"...
wrapper  |   Unable to map "S:".  Trying to continue. (Access is denied. (0x5))

Referencia: Propiedades wrapper.share.<n>.*

Estas propiedades se utilizan para configurar la asignación de recursos de red a unidades locales.