隔離開放程式碼軟體套件
您可以使用數種方法,從「開放程式碼軟體 (OSS)」套件中隔離 Java™ Platform, Enterprise Edition (Java EE) 應用程式及其他 Java EE 可部署構件。 套用這些方法可解決類別載入錯誤,以及使用 WebSphere® Application Server 隨附 OSS 套件時可能發生的非預期執行時期行為。
開放程式碼軟體 API 主題列出 WebSphere Application Server 所提供的 OSS 套件 (預期用於導向應用程式) ,並提供關於其使用的說明文件參照。
如果 Java EE 應用程式遇到想要直接使用 OSS 套件的問題,請參閱對應的用法文件,以驗證應用程式和伺服器是否正確配置。 例如,如果應用程式遇到涉及 Apache Commons Logging 的類別載入問題,請參閱 Jakarta Commons Logging 主題。
當應用程式遇到 OSS 套件並非預期用於直接應用程式的問題時,請參閱本主題所包含的 將 Java EE 應用程式與 OSS 套件隔離的最佳作法 小節,以瞭解如何在鏈結至 WebSphere Application Server所提供的相同套件時保護為應用程式提供的 OSS 套件。
隔離其他 Java EE 構件的方式較少。 獨立式資源配接器和資源提供者具有啟用隔離的配置選項。 對於遇到 WebSphere Application Server隨附 OSS 套件問題的獨立式資源,請參閱 隔離資源提供者的考量 主題,以判定隔離資源是否可行。 如果是的話,請設定選項。 當伺服器重新啟動時,執行時期會使用配置了 parent_last 委派和資源類別路徑的個別類別載入器來載入資源。
當資源隔離不可行,或失敗的 Java EE 構件不是資源時,請使用本文件的 配置一律保護 (隔離) 套件 小節中說明的方法,將構件與有問題的 OSS 套件隔離。
將 Java EE 應用程式與 OSS 套件隔離的最佳作法
請使用共用程式庫、 parent_last 類別載入器委派,或必要的話,一律受保護的套件,來保護應用程式免受 WebSphere Application Server隨附的 OSS 套件所影響。
隔離的共用程式庫
將應用程式與 WebSphere Application Server 隨附的 OSS 套件隔離的理想方法是將套件部署為隔離的共用程式庫,並將它與所有相依應用程式及 Web 應用程式保存檔 (WAR) 模組相關聯。 此方法只會讓與程式庫相關聯的應用程式和 WAR 模組使用 OSS 套件。 在執行時期,隔離共用程式庫的類別會從其自己的類別載入器實例載入,確保程式庫載入器會立即載入 OSS 類別,且程式庫類別會在共用程式庫的所有應用程式上定義一次。
myAppCL) 的委派模式設為 Classes
loaded with the parent class loader first (Parent_first)時,方法 myAppCL.loadClass(clsName) 會以下列順序尋找 clsName :- 在 JVM 類別快取中搜尋已定義的類別
<myAppCL, clsName> - 在每一個相關聯隔離程式庫類別載入器的類別路徑中搜尋
clsName - 將
loadClass(clsName)委派給myAppCL的母類別載入器 - 在
myAppCL的類別路徑中搜尋clsName
myAppCL.loadClass(clsName) 會依下列順序尋找 clsName :- 在 JVM 類別快取中搜尋已定義的類別
<myAppCL, clsName> - 在
myAppCL的類別路徑中搜尋clsName - 在每一個相關聯隔離程式庫類別載入器的類別路徑中搜尋
clsName - 將
loadClass(clsName)委派給myAppCL的母類別載入器
由於在模組類別載入器委派給母項之前,一律會先搜尋相關聯的共用程式庫,不論 myAppCL 是配置成 Parent_first 或 Parent_last,這個方法都會運作。
伺服器共用程式庫
將 OSS 套件與應用程式隔離的另一種方法是將共用程式庫與伺服器配置中定義的類別載入器相關聯。 伺服器定義類別載入器的委派模式必須設為 Parent_last。 這個方法不如使用隔離的共用程式庫,因為所有應用程式和 WAR 模組類別載入器都必須將 loadClass() 委派給至少一個母項,才能載入程式庫中的類別。
如需如何建立及配置共用程式庫的相關資訊,請閱讀 管理共用程式庫 主題。
類別載入器委派
當共用程式庫不可行時,請將 OSS 套件組合成應用程式內的相依關係 JAR。 安裝應用程式之後,針對載入 OSS 套件的每一個應用程式和 WAR 模組類別載入器,將類別載入 (委派) 模式設為 Parent_last 。 這個方法比使用隔離式共用程式庫更適合,因為當隔離式共用程式庫類別載入器定義類別,且 JVM 載入使用相同類別載入器的相依類別時,在任何其他應用程式、WAR 模組或伺服器定義的類別載入器中都找不到相依類別。
類別載入 主題說明如何設定應用程式和 WAR 模組類別載入器的委派模式。
如果上述方法都不可行,請依照下一節的說明來嘗試 配置一律保護 (隔離) 套件 。
配置一律保護 (隔離) 套件
WebSphere Application Server 會維護 一律受保護 (或 隔離) 套件名稱清單,在 WebSphere Application Server 類別載入器階層中,它會對 OSGi 閘道之下的所有類別載入器隱藏這些套件名稱。 配置一律受保護的套件,以將所有 Java EE 已部署的構件與 WebSphere Application Server隨附的 OSS 套件隔離。
一律受保護的套件會控制「 WebSphere 延伸類別載入器 (ExtClassLoader)」(應用程式和共用程式庫類別載入器的邏輯母項) 是否將載入作業委派給 OSGi 閘道。 因為 OSGi 閘道可看見 OSS 套件,所以防止委派至閘道可有效地防止 Java EE 應用程式和共用程式庫非預期地鏈結至宣告為一律受保護的 OSS 套件。 這項特性也支援直接從 ExtClassLoader 類別路徑載入的已部署構件,包括獨立式資源配接器和配置成非隔離的自訂服務和自訂鑑別模組的提供者。
使用一律受保護的套件,您無法指定會干擾 WebSphere Application Server 功能的套件。 禁止的套件包括 {"java.", "com.", "com.ibm."}。 雖然不太可能,但您也可以配置一律受保護的資源路徑。 禁止的資源名稱包括 {"java/", "com/",
"com/ibm/", "META-INF/services/"}。 伺服器會忽略這些輸入,以及語法或語意無效的任何輸入。
當應用程式和其他構件提供相同的 OSS 套件時,下列程序可能無法運作。 如果應用程式和獨立式資源配接器 (配置為非隔離) 兩者都提供 OSS 套件,則資源配接器所提供之套件的鏈結有可能都在 ExtClassLoader 類別路徑上可見。 在這類部署中,您必須將獨立式資源配接器重新配置成隔離的,或將先前提及的建議套用至應用程式部署 (例如,將應用程式類別載入器委派模式設為 Parent_last ,或將隔離的共用程式庫關聯於應用程式)。 依預設會啟用一律受保護的套件,且無法停用。 您一律可以新增至一律受保護的套件清單。
- 判定有問題 OSS 架構的根套件名稱。 例如, Apache HTTP 元件的根套件名稱是 org.apache.http.。 Apache HTTP 元件中的所有類別都以這個根套件名稱作為字首。 如需相關資訊,請參閱 開放程式碼軟體 API 主題。
- 在管理主控台中伺服器設定頁面的「伺服器基礎架構」之下,按一下 。
- 選取 Java 虛擬機器。
- 在 JVM 通用引數區段中定義下列系統內容,如下所示:
- 定義系統內容 -Dws.ext.debug=true。
- 在 JVM 一般引數中定義系統內容 -Dcom.ibm.ws.classloader.server.alwaysProtectedPackages=<pkg1>,...,<pkgN> ,以 <pkg1>...<pkgN> 針對已部署的 Java EE 構件隱藏 OSS 套件。 僅此設定應該隱藏有問題的 OSS 套件。
- 一律受保護的套件 :com.ibm.ws.classloader.server.alwaysProtectedPackages
以逗點 (
',') 區隔的套件名稱字串, WebSphere Application Server 會隔離 (保護) 所有已部署的構件。 一律受保護的套件名稱必須以'.'結尾,且不能是任何禁止的套件名稱的子套件。 WebSphere Application Server 會忽略無效的一律保護套件名稱。設定此內容時,每當
clsName包含一律保護的套件名稱作為字首時,ExtClassLoader資源 APIgetResource(rscName)就不會委派給「OSGi 閘道」。 僅當clsName在ExtClassLoader的本端類別路徑上可見時,此方法才會傳回類別。 同樣地,每當資源名稱以 .class 結尾且位於路徑中,ExtClassLoader資源 API 就不會委派給「OSGi 閘道」。 轉換成套件名稱之後,它會包含一律受保護的套件名稱作為字首。比方說,如果套件名稱 org.oss.pkg. 一律受到保護,
ExtClassLoader.loadClass(org.oss.pkg.Unexpected)不會委派給「OSGi 閘道」,且實際上會防止任何 JEE 應用程式、共用程式庫、自訂鑑別模組、獨立式資源或自訂服務非預期地鏈結至套件 org.oss.pkg.中的類別。同樣地,方法
ExtClassLoader.getResource(org/oss/pkg/Unexpected.class)不會委派給 OSGi 閘道,進一步確保已部署的構件無法在 WebSphere Application Server所提供的 org.oss.pkg. 套件中探索類別檔。預設值為 unset。
- 如果已部署的構件非預期地載入 WebSphere Application Server隨附的 OSS 套件所提供的資源,請定義系統內容 -Dcom.ibm.ws.classloader.server.alwaysProtectedResources=<rsc>,...,<rscN> 來隱藏 OSS 資源路徑 <rsc>...<rscN> ,使其不適用於已部署的構件。
- 一律受保護資源 :com.ibm.ws.classloader.server.alwaysProtectedResources
以
','區隔的資源名稱字串, WebSphere Application Server 會將所有已部署的構件隔離 (保護)。 一律受保護資源名稱不得以'/'開頭 (必須是相對名稱) ,可以'/'結尾,且不得是任何禁止資源名稱的子字串。 WebSphere Application Server 會忽略無效的一律受保護資源名稱。設定此內容時,每當
rscName包含一律保護的資源名稱作為字首時,ExtClassLoader資源 API (getResource (rscName)) 不會委派給「OSGi 閘道」。例如,如果資源名稱 org/oss/pkg/ 一律受保護, org/oss/pkgs/unexpected
ExtClassLoader.getResource()不會將作業委派給「OSGi 閘道」,實際上會阻止任何已部署的構件在 WebSphere Application Server所提供的 org/oss/pkg/ 路徑中探索資源。在 always-protected 套件中,不需要為 .class 檔指定 always-protected 資源名稱,因為它們是受保護的。
預設值為 unset。
- 如果已部署的構件相依於一律受保護套件中的子套件或類別,請在 JVM 一般引數中定義系統內容 -Dcom.ibm.ws.classloader.server.alwaysAllowedPackages=<pkgOrClass1>,...
,<pkgOrClassN> ,讓 OSS 套件 <pkgOrClass1>...<pkgOrClassN> 可供已部署的 Java EE 構件存取。 當已部署的構件只需要一律保護的 OSS 套件內的介面時,最有可能使用此設定。
- Always-Allowed Packages: com.ibm.ws.classloader.server.alwaysAllowedPackages
以
','區隔的子套件字串或「一律保護」套件的完整類別名稱, WebSphere Application Server 可讓所有已部署的構件看見這些套件。 WebSphere Application Server 會忽略無效且一律受保護的資源名稱,包括絕對名稱 (以'/'開頭的名稱)。 WebSphere Application Server 會忽略無效的一律容許套件名稱。例如,如果套件名稱 org.oss.pkg. 一律受保護,且 org.oss.pkg.api. 一律容許, 然後
ExtClassLoader. loadClass (org.oss.pkg.api.PkgFactory)會委派給「OSGi 閘道」,並容許已部署的類別與 WebSphere Application Server所提供的org.oss.pkg.api.PkgFactory鏈結; 但會阻止它鏈結至 WebSphere Application Server所提供的套件 org.oss.pkgor 或 org.oss.pkg.impl中的類別。預設值為 unset。
- 如果已部署的構件必須在一律受保護資源路徑的子路徑中載入資源,請在 JVM 一般引數中定義系統內容 -Dcom.ibm.ws.classloader.server.alwaysAllowedResources=<rsc1>...<rscN> ,讓 OSS 資源 <rsc1>...<rscN> 可供已部署的 Java EE 構件存取。
- Always-Allowed Resources: com.ibm.ws.classloader.server.alwaysAllowedResources
以
','區隔的子路徑字串或一律保護資源 (路徑) 的確切路徑名稱, WebSphere Application Server 可讓所有已部署的構件看見這些資源 (路徑)。 WebSphere Application Server 會忽略無效的一律容許資源名稱。例如,如果資源名稱 org/oss/pkg/一律受保護,且 "org/oss/pkg/api/ 一律容許, 方法
ExtClassLoader.getResource(org/oss/pkg/api/PkgFactory.class)會委派給「OSGi 閘道」,並容許已部署的類別探索 WebSphere Application Server所提供的 "org/oss/pkg/api/PkgFactory.class"; 但阻止它探索 WebSphere Application Server也提供的路徑 org/oss/pkg 或 org/oss/pkg/impl/中的資源。預設值為 unset。
- 按一下套用。
- 按一下確定。
- 儲存您所做的變更。 在重新啟動伺服器之前,請確定已完成檔案同步化。
- 重新啟動 WebSphere Application Server ,讓變更生效。
- 檢查 native_stdout.log ,並尋找先前定義的系統內容。例如,當您指定 always-protected 套件 org.apache.http.時,可能會出現如下的陳述式:
ProtectionMetaData.clinit: system property: com.ibm.ws.classloader.server.alwaysProtectedPackages=org.apache.http. ... ... ProtectionMetaData.clinit: always-protected packages: org.slf4j. org.slf4j.spi. org.slf4j.impl. org.slf4j.helpers. org.apache.http.如果您看到套件包含在一律受保護的套件清單中 (例如前一個範例中的 org.apache.http. ) ,則您已正確配置伺服器來隱藏 WebSphere Application Server所提供的 OSS 套件。 伺服器一律會保護其他套件,例如 org.slf4j。 您的應用程式也受到這些套件的保護。 如果您未看到清單中包含一律受保護的套件,則會在 native_stdout.log 的相同工作區中出現一則訊息,指出忽略套件 (或套件) 的原因。 請修訂內容值,然後重新啟動伺服器。
- 在將新的伺服器配置放入正式作業之前,請先移除系統內容 -Dws.ext.debug=true 。