鬆散應用程式
鬆散應用程式是指由多個實體位置組成的應用程式,會透過 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> 元素之下的巢狀 <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 屬性值是一個絕對位置。您可以使用會正確解析的 Liberty 變數,例如 ${example.dir}。
- 下列程式碼是位於 C:/devFolder/myApplication.zip 的檔案範例,鬆散應用程式配置會以 /apps/webApplication.war 來呈現它:
<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>