松散应用程序
松散应用程序是来自多个物理位置的应用程序,这些应用程序通过 XML 文件提供给运行时。Java™ EE 和 OSGi 应用程序支持松散应用程序,并且松散应用程序在开发环境中特别有益。
正常应用程序
- 库 Java 归档 (JAR) 文件存储在 WEB-INF/lib 中
- 类在库 JAR 文件或 WEB-INF/classes 中
- 部署描述符在 WEB-INF/web.xml 中
- 要处理的内容位于该目录的根目录
松散应用程序
松散应用程序被描述为“一个表示应用程序的虚拟目录,信息可能在任意位置”。它允许开发工具(例如,WebSphere® Application Server Developer Tools)运行应用程序,在这些应用程序中,关联文件直接从工作空间装入而不是被导出。关联文件的示例包括 Java 类、JavaServer Pages 或图像。如果直接从工作空间装入关联文件,那么构建 - 运行 - 调试循环的运行速度更快。内容不在一个目录下,而是可能来自其他位置。这些位置是在 XML 配置文件中指定的。
- 通过将该 XML 文件放置在应用程序配置元素的 location 属性中,并附加 .xml 后缀
- 通过将该 XML 文件直接放置在应用程序 dropins 文件夹中
松散应用程序配置文件
- 将任何物理目录映射至该应用程序内的任何位置
- 将任何物理文件映射至该应用程序内的任何位置
- 将任何物理 JAR 文件或目录以嵌套归档形式映射至任何位置
- 将多个物理源映射至单个目标位置(合并)
- 将归档的根目录映射至磁盘上的某个位置,例如,Eclipse 项目中的某个文件夹。
- 将不在“通常”位置的 Java bin/output 文件夹映射至 WEB-INF/classes 文件夹。由于工作空间首选项、公司准则、源控制项目布局准则等等,此位置可能在另一文件夹中。同一项目中可能有多个 Java 源位置和输出位置,您可能想要将它们都映射至 WEB-INF/classes。
- 将“外部”JAR 文件映射至该应用程序。此“外部”JAR 文件可能为下列其中一项:
- 一个独立 Java 项目,您想要将其视为 WEB-INF/lib 中的 JAR 文件
- 硬盘驱动器上其他位置的一个实用程序 JAR 文件,您针对其构建了 .war 文件,并且需要在运行时包含在 WEB-INF/lib 中
松散应用程序配置文件示例
- <archive>,用于归档
- <file>,用于文件
- <dir>,用于目录
- 归档
- <archive> 元素始终用作松散应用程序配置文件的根。它也是 XML 中表示的虚拟文件系统的根目录。可在根 <archive> 元素下嵌套这三个元素中的任何一个元素。根 <archive> 元素没有任何属性。
- 归档元素可递归嵌套。对于根 <archive> 元素下嵌套的 <archive> 元素,可设置 targetInArchive 属性。targetInArchive
属性定义该归档出现在松散定义的封闭归档内的路径。不能使用 <archive> 元素将文件系统上的归档映射为应用程序中的归档。要使用松散应用程序配置映射磁盘上的归档,请改用 <file> 元素。注: targetInArchive 属性值是带有前导正斜杠 (/) 的绝对路径。
- 以下代码是根 <archive> 元素(其下嵌套了另一 <archive> 元素)的示例:
<archive> <archive targetInArchive="/jarName.jar"> <!-- more objects can be embedded here--> </archive> </archive>
- 文件
- 可使用 <file> 元素将硬盘上的文件映射至松散应用程序配置中的文件。可对 <file> 元素设置以下属性:
- targetInArchive 定义该归档出现在松散定义的封闭归档内的路径。
- sourceOnDisk 定义文件在文件系统上的实际位置。注: sourceOnDisk 属性值是绝对位置。可使用 ${example.dir} 之类已正确解析的 Liberty 变量。
- 以下代码是被松散应用程序配置表示为 /apps/webApplication.war 的 C:/devFolder/myApplication.zip 中的文件的示例:
<file targetInArchive="/apps/webApplication.war" sourceOnDisk="C:/devFolder/myApplication.zip" />
- 以下代码是在路径 /apps/webApplication.war 上定义归档的封闭归档的示例。在此归档内,webApplication.war
在路径 /applications/myApplications 上定义文件 jarName.jar。实际文件位置为
c:\devFolder\myApplication.zip:
<archive targetInArchive="/apps/webApplication.war"> <file targetInArchive="/applications/myApplications/jarName.jar" sourceOnDisk="C:/devFolder/myApplication.zip" /> </archive>
- 目录
- 可使用 <dir> 元素将磁盘上的目录及其所有内容映射至松散应用程序配置中的目录位置。该元素具有与 <file> 元素相同的属性,您可通过类似方式使用该元素。
- 以下代码是松散应用程序配置显示的目录的示例(就像在 /META-INF 中及文件系统的
${example.dir}/applicationData/myApplication 中显示的那样):
<dir targetInArchive="/META-INF" sourceOnDisk="${example.dir}/applicationData/myApplication" />
- 要将该目录添加至归档以使它出现在 /apps/jarName.jar/META-INF 中,请按如下所示嵌入 <dir> 元素:
<archive targetInArchive="/apps/jarName.jar"> <dir targetInArchive="/META-INF" sourceOnDisk="${example.dir}/applicationData/myApplication" /> </archive>
- 在以上两个示例中,${example.dir}/applicationData/myApplication 中的所有文件已映射并显示在松散应用程序配置中由 targetInArchive 属性映射的目录下。
虚拟路径和文件名
如果将 <file> 或 <dir> 元素添加至归档,那么松散归档中的文件或目录的名称不必与磁盘上的实际名称相同。
<archive>
<file targetInArchive="/application.txt"
sourceOnDisk="${example.dir}/applicationFiles/newfile.txt"/>
</archive>
同一概念对任何已添加文件或目录的路径也适用。磁盘上的物理资源不必位于与要声明的对象对应的目录层次结构中。
<archive>
<file targetInArchive="/only/available/in/application.txt"
sourceOnDisk=""${example.dir}/applicationFiles/newfile.txt"/>
</archive>
<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>
同名的文件夹和文件
如果在松散应用程序配置的同一虚拟位置中有两个同名文件夹,那么这些文件夹会合并,并且这两个文件夹的内容可用。如果有两个文件在松散归档中具有相同目标位置,那么系统使用第一次出现的文件。第一次出现以按自顶向下方法读取松散应用程序配置文件的元素时遇到的文件为准。
如果发现的第一个文件是错误文件,请对 XML 重新排序以便首先处理包含您需要的文件版本的元素。第一次出现适用于 <dir> 元素中定义的文件及 <file> 元素中定义的文件。具有相同名称和虚拟位置的文件的第一次出现是从虚拟文件系统返回的文件。
松散应用程序的注意事项
对于所有松散配置的应用程序,这些文件不在磁盘上它们被声明为应该位于其中的层次结构中。如果应用程序直接访问它们自己的资源,并期望这些资源在磁盘上按预期方式排列(具有扩展 war 或 ear 布局),那么它们可能展示意外行为。
可在应用程序中使用 ServletContext.getRealPath 来发现物理资源路径。ServletContext.getRealPath 可发现要打开以读/写入数据的文件路径并获取目录。但是,如果在 Web 应用程序中使用 ServletContext.getRealPath 以获取“/”的路径,那么不能使用此路径在磁盘上浏览该应用程序。
ServletContext.getRealPath 仅允许返回单个物理路径,松散应用程序可能已合并多个目录以形成对该应用程序可视的一个路径。
<archive>
<dir targetInArchive="/"
sourceOnDisk="c:\myapplication" />
<dir targetInArchive="/web/pages"
sourceOnDisk="c:\webpagesforapplication" />
</archive>
直接访问 /web/pages 然后向上浏览目录层次结构的应用程序发现物理路径 /web/pages 的父代为 c:\ 而不是 /web。c:\ 没有 pages 目录,也没有父目录。
仅当应用程序尝试直接访问磁盘上的内容并根据磁盘上对应分层布局的假定执行它们自己的路径浏览时,这些注意事项才适用。相同应用程序部署为归档时也会遇到问题。这些应用程序通常会遇到可移植性问题。
复杂示例
<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>