Aplicaciones dinámicas

Las aplicaciones dinámicas son aplicaciones que se componen a partir de varias ubicaciones físicas, que se proporcionan al entorno de ejecución mediante un archivo XML. Las aplicaciones sueltas están soportadas para aplicaciones Java™ EE y OSGi y son especialmente beneficiosas en un entorno de desarrollo.

Aplicación normal

Normalmente, una aplicación está contenida en un directorio (o en un archivo de archivado), con su contenido, módulos, recursos, datos de clase y metadatos en ubicaciones conocidas dentro de ese directorio. Por ejemplo: la ubicación de los recursos para una aplicación web es la siguiente:
  • Los archivos JAR (Java Archive) de biblioteca se almacenan en WEB-INF/lib
  • Las clases se encuentran en archivos JAR de biblioteca o en WEB-INF/classes
  • El descriptor de despliegue está en WEB-INF/web.xml
  • El contenido que debe servirse está ubicado en la raíz del directorio

Aplicación dinámica

Una aplicación dinámica se describe como un directorio virtual que representa la aplicación, donde la información puede estar en cualquier ubicación. Permite a las herramientas de desarrollo, como por ejemplo WebSphere® Application Server Developer Tools, ejecutar aplicaciones donde los archivos asociados se cargan directamente desde el espacio de trabajo, en lugar de exportarse. Algunos ejemplos de archivos asociados son clases Java, páginas JavaServer o imágenes. Si carga los archivos asociados directamente desde el espacio de trabajo, da como resultado un ciclo de creación-ejecución-depuración más rápido. El contenido no se encuentra bajo un directorio, sino que puede provenir de otras ubicaciones. Estas ubicaciones se especifican en un archivo de configuración XML.

Hay dos formas de proporcionar el archivo XML al tiempo de ejecución:
  1. Colocando el archivo XML en el atributo location de un elemento de configuración de aplicación con el sufijo .xml añadido
  2. Colocando el archivo XML directamente en la carpeta dropins de la aplicación
Por ejemplo, si especifica <application location="myapp.war" />, el tiempo de ejecución busca un archivo denominado myapp.war.xml. Las reglas de búsqueda son las mismas que para un directorio o archivo de archivado de aplicación. Si se encuentran tanto los archivos de aplicación como los archivos de configuración de la aplicación dinámica .xml, el archivo de configuración de la aplicación dinámica se ignora. Por ejemplo, si tiene myapp.war y myapp.war.xml, el servidor Liberty utiliza myapp.war para ejecutar la aplicación. También puede desplegar aplicaciones dinámicas directamente en la carpeta dropins. Para utilizar la carpeta dropins, siga las convenciones de denominación definidos para la carpeta y añada .xml al final del nombre de archivo.
Evitar problemas: Al ejecutar el mandato server package con un archivo my_app.war.xml de aplicación dinámica que utiliza la sustitución de variables de servidor, las partes de la aplicación dinámica que tienen sustitución de variables no se empaquetan. El servidor no se inicia en el momento de crear el paquete y no hay forma de acceder a la información necesaria sobre variables. La sustitución de variables no tiene lugar cuando se utiliza el mandato server package .

Archivo de configuración de la aplicación dinámica

El servidor de Liberty utiliza el archivo de configuración de aplicación dinámica para obtener el contenido de la aplicación, en lugar de ubicarlo desde un directorio raíz o un único archivo. Utilizando el XML adecuado, puede realizar las acciones siguientes:
  • Correlacionar cualquier directorio físico con cualquier ubicación dentro de la aplicación
  • Correlacionar cualquier archivo físico con cualquier ubicación dentro de la aplicación
  • Correlacionar cualquier archivo o directorio JAR físico con cualquier ubicación como archivo de archivado anidado
  • Correlacionar varios orígenes físicos con una única ubicación de destino (fusión)
Por ejemplo:
  1. Correlacionar la raíz del archivo de archivado con una ubicación de disco, por ejemplo una carpeta de un proyecto de Eclipse.
  2. Correlacione una carpeta Java bin/output que no esté en la ubicación habitual en la carpeta WEB-INF/classes . Esta ubicación puede estar en una carpeta diferente debido a las preferencias de espacio de trabajo, directrices corporativas, directrices de diseño del proyecto de control de origen, etc. Es posible que tenga varias ubicaciones de origen y salida Java en el mismo proyecto y que desee correlacionarlas con WEB-INF/classes.
  3. Correlacionar un archivo JAR externo con la aplicación. Este archivo JAR externo puede ser uno de los siguientes:
    • Un proyecto Java independiente que desea tratar como un archivo JAR en WEB-INF/lib
    • Un archivo JAR de programa de utilidad en otro lugar de la unidad de disco duro donde ha creado el archivo .war y que debe incluir en WEB-INF/lib en tiempo de ejecución

Ejemplos del archivo de configuración de aplicación dinámica

Puede configurar tres elementos diferentes en el archivo de configuración de la aplicación dinámica:
  • <archive> para archivos de archivado
  • <file> para archivos
  • <dir> para directorios
Archivadores
El elemento <archive> siempre se utiliza como la raíz del archivo de configuración de la aplicación dinámica. Es también la raíz del sistema de archivos virtual que se representa en el XML. Puede anidar cualquiera de los tres elementos bajo el elemento <archive> raíz. El elemento <archive> raíz no tiene atributos.
Los elementos de archivado se pueden anidar de forma recursiva. Para los elementos <archive> anidados bajo el elemento <archive> raíz, puede establecer el atributo targetInArchive. El atributo targetInArchive define la vía de acceso donde figura el archivo de archivado dentro del archivo de archivado contenedor definido por la aplicación dinámica. No se puede correlacionar un archivo de archivado del sistema de archivos como un archivo de archivado de la aplicación con un elemento <archive>. Para utilizar la configuración de la aplicación dinámica para correlacionar un archivo de archivado en disco, utilice un elemento <file> en su lugar.
Nota: El valor del atributo targetInArchive es una vía de acceso absoluta con una barra inclinada inicial (/).
El código siguiente es un ejemplo del elemento <archive> raíz con otro elemento <archive> anidado bajo él:
<archive>
    <archive targetInArchive="/jarName.jar">
        <!-- more objects can be embedded here-->
    </archive>
</archive>
Archivos
Puede utilizar el elemento <file> para correlacionar un archivo del disco duro con un archivo de la configuración de la aplicación dinámica. Puede definir los atributos siguientes en el elemento <file>:
  • targetInArchive define la vía de acceso donde figura el archivo de archivado dentro del archivo de archivado contenedor definido por la aplicación dinámica.
  • sourceOnDisk define la ubicación real del archivo en el sistema de archivos.
    Nota: El valor del atributo sourceOnDisk es una ubicación absoluta. Puede utilizar variables de Liberty como, por ejemplo, ${example.dir}, que se resuelven correctamente.
El código siguientes es un ejemplo de un archivo de C:/devFolder/myApplication.zip que se representa como /apps/webApplication.war en la configuración de la aplicación dinámica:
<file targetInArchive="/apps/webApplication.war" 
        sourceOnDisk="C:/devFolder/myApplication.zip" />
El código siguiente es un ejemplo de un archivo de archivado contenedor que define un archivo de archivado en la vía de acceso /apps/webApplication.war. Dentro del archivo de archivado, webApplication.war define un archivo, jarName.jar en la vía de acceso /applications/myApplications. La ubicación del archivo real es c:\devFolder\myApplication.zip:
<archive targetInArchive="/apps/webApplication.war">
    <file targetInArchive="/applications/myApplications/jarName.jar" 
            sourceOnDisk="C:/devFolder/myApplication.zip" />
</archive>
Directorios
Puede utilizar el elemento <dir> para correlacionar un directorio y todo su contenido en disco con una ubicación de directorio de la configuración de la aplicación dinámica. El elemento tiene los mismos atributos que el elemento <file> y se utiliza de forma similar.
El código ejemplo es un ejemplo de un directorio que muestra la configuración de la aplicación dinámica como que está en /META-INF y en el sistema de archivos en ${example.dir}/applicationData/myApplication:
<dir targetInArchive="/META-INF" 
       sourceOnDisk="${example.dir}/applicationData/myApplication" />
Para añadir el directorio a un archivo de archivado para que figure en /apps/jarName.jar/META-INF, incorpore el elemento <dir> como se indica a continuación:
<archive targetInArchive="/apps/jarName.jar">
    <dir targetInArchive="/META-INF" 
           sourceOnDisk="${example.dir}/applicationData/myApplication" />
</archive>
En ambos de los ejemplos anteriores, todos los archivos que están en ${example.dir}/applicationData/myApplication están correlacionados y son visibles en la configuración de la aplicación dinámica bajo el directorio que está correlacionado mediante el atributo targetInArchive.

Vías de acceso virtuales y nombres de archivo

Si añade elementos <file> o <dir> a un archivo de archivado, el nombre del archivo o directorio del archivo de archivado de la aplicación dinámica no tiene que ser necesariamente el mismo que el nombre real en disco.

El código ejemplo es un ejemplo de cómo puede configurar ${example.dir}/applicationFiles/newfile.txt para que aparezca en el archivado como /application.txt:
<archive>
    <file targetInArchive="/application.txt"
            sourceOnDisk="${example.dir}/applicationFiles/newfile.txt"/>
</archive>

Se aplica el mismo concepto a la vía de acceso de cualquier archivo o directorio añadido. No es necesario que el recurso físico del disco esté en una jerarquía de directorios que corresponda a la que se declara.

El código siguiente es un ejemplo de cómo puede hacer que aparezca ${example.dir}/applicationFiles/newfile.txt en el archivado como /only/available/in/application.txt:
<archive>
    <file targetInArchive="/only/available/in/application.txt" 
            sourceOnDisk=""${example.dir}/applicationFiles/newfile.txt"/>
</archive>
En cada caso, el servidor de Liberty ve el recurso por el nombre y la vía de acceso declarados por el atributo targetInArchive . El servidor de Liberty puede navegar por la jerarquía de directorios declarada, incluso si la jerarquía contiene sólo elementos virtuales, como en el ejemplo anterior.
<archive>
    <file targetInArchive="/only/available/in/red.txt" 
            sourceOnDisk="${example.dir}/applicationFiles/newfile.txt" />
    <archive targetInArchive="/apps/jarName.jar">
        <dir targetInArchive="/META-INF" 
               sourceOnDisk="${example.dir}/applicationData/myApplication" />
    </arhive>
</archive>

Carpetas y archivos con el mismo nombre

Si tiene dos carpetas con el mismo nombre en la misma ubicación virtual en la configuración de la aplicación dinámica, las carpetas se fusionarán y el contenido de ambas carpetas estará disponible. Si tiene dos archivos con la misma ubicación de destino en el archivo de archivo de la aplicación dinámica, se utilizará la primera aparición del archivo. La primera aparición se basa en un enfoque descendente para leer los elementos del archivo de configuración de la aplicación dinámica.

Si el primer archivo encontrado es erróneo, reordene el XML de modo que el elemento que contiene la versión del archivo que desea se procese en primer lugar. La primera aparición se aplica a los archivos definidos en los elementos <dir> y a los archivos definidos en elementos <file>. La primera aparición de un archivo con el mismo nombre y ubicación virtual es el que se devuelve desde el sistema de archivos virtual.

Consideraciones para las aplicaciones dinámicas

En todas las aplicaciones dinámicas configuradas, los archivos no están en el disco en la jerarquía en la que están declarados. Si las aplicaciones acceden directamente a sus propios recursos, y se espera que se organizan en disco al igual que en un diseño de war o ear expandido, podrían mostrar un comportamiento inesperado.

Puede utilizar ServletContext.getRealPath en las aplicaciones para descubrir vías de recurso físico. ServletContext.getRealPath puede descubrir vías de acceso de archivo que deben abrirse para leer o grabar datos y obtener los directorios. Sin embargo, si utiliza ServletContext.getRealPath en aplicaciones web para obtener una vía de acceso para /, no puede utilizar esta vía de acceso para navegar por la aplicación en el disco.

ServletContext.getRealPath sólo permite devolver una única vía de acceso física, y la aplicación dinámica puede haber fusionado varios directorios para formar una vía de acceso visible para la aplicación.

Considere la configuración siguiente:
<archive>
    <dir targetInArchive="/" 
           sourceOnDisk="c:\myapplication" />
    <dir targetInArchive="/web/pages" 
           sourceOnDisk="c:\webpagesforapplication" />
</archive>

Una aplicación que accede directamente a /web/pages y luego navega por la jerarquía de directorios detecta que el padre de la vía de acceso física de /web/pages es c:\ y no /web. c:\ no tiene ningún directorio pages ni ningún directorio padre.

Estas consideraciones sólo se aplican si las aplicaciones intentan acceder directamente al contenido del disco y realizan su propia navegación por las vías de acceso en función de una hipótesis de un diseño jerárquico correspondiente en el disco. Las mismas aplicaciones también encuentran problemas si se despliegan como un archivo de archivado. Estas aplicaciones suelen experimentar problemas con la portabilidad.

Ejemplo complejo

El código siguiente es un ejemplo más complejo de configuración de una aplicación dinámica. Este ejemplo utiliza todos los elementos y crea una correlación compleja de archivos y directorios:
<archive>
    <dir targetInArchive="/appResources" 
           sourceOnDisk="${example.dir}/applicationFiles" />
    <archive targetInArchive="application.jar">
        <dir targetInArchive="/src" 
               sourceOnDisk="${example.dir}/applicationCode/src" />
    </archive>
    <archive targetInArchive="webApp.war">
        <dir targetInArchive="/META-INF" 
               sourceOnDisk="${example.dir}/manifestFiles/" />
        <dir targetInArchive="/WEB-INF" 
               sourceOnDisk="c:/myWorkspace/webAppProject/web-inf" />
        <archive targetInArchive="/WEB-INF/lib/myUtility.jar">
            <dir targetInArchive="/" 
                   sourceOnDisk="c:/myWorkspace/myUtilityProject/src" />
            <file targetInArchive="/someJar.jar" 
                    sourceOnDisk="c:/myWorkspace/myUtilityProject/aJar.jar" />
        </archive>
    </archive>
    <file targetInArchive="/myjar.jar" 
            sourceOnDisk="${example.dir}/apps/application.zip" />
</archive>