引言
Java™ 2 企業版(Java™ 2 Enterprise Edition,J2EE)是開發並部署企業 應用程序的環境。J2EE 平台由服務、應用程序編程接口(application programming interfaces,API)及協議所組成,該協議提供了開發多層的且基於 Web 的應用程序的功能 。關於產品信息的內容,請見 WebSphere Application Server 專區 和 WebSphere Studio 專區。
問:EJB 或 Web 服務的 BEA 控制及注釋看上去是非常強大的並且易於使用這些技術。對 此,您的看法是什麼?在 WebSphere® 中使用這些技術有多容易?
答:您似乎希望獲得 BEA® WebLogic Workshop 和 IBM WebSphere Studio Application Developer(以下簡稱 WebSphere Studio)的比較。我沒有使用過 Workshop, 所以不能直接評論它的特點。WebSphere Studio 確實包含許多對於元信息的編輯器,如部署 描述符。使用這些編輯器比編輯原始的 XML 要容易得多(雖然 Source 記錄頁面也允許您那 樣做)。同樣,在 WebSphere Studio V5 中重新設計了這些編輯器,使其與 J2EE 指定的和 WebSphere 指定的配置設置有更加明顯的不同。
問:您知道如果啟用了 WebSphere Application Server V5.1 Global Security,那麼 Web 服務和 WebSphere Application Server 之間的傳輸是否可以自動地轉換成 https?例 如,使用 defaultSSLsettings 和 jmserver 認證。我不必在 Web 和 Application 服務器 之間創建新的證書。同時,我已經具有 Web 和浏覽器客戶端之間的 https 了。目前,這僅 是不完整的 Web<>WAS https。全局安全性還沒有被啟用。
答:在 WebSphere Application Server 5.1 中啟用全局安全性會自動地進行 Web 服務 的 HTTPS 轉換嗎?據我所知不是這樣的。您需要自己手動完成。請見 WebSphere Application Server Information Center 中的“調用 HTTPS 上的 web 服務” 和“使用 HTTP 基礎認證來安全化安全的 Socket 層上的簡單對象訪問協議服務 ”。
問:在我們的項目中有一套 EJB。基本上,我們具備安裝在 WebSphere Studio V5.1.2 上的 EAR 文件。當測試環境服務器運行時,對於 EJB 項目及客戶端項目的代碼變更都不會 受到影響。每次我都需要重新啟動測試環境服務器才能使得改變生效。那麼,存在任何方案 或配置裝置來解決這個問題嗎?
答:如果在您使用調試器編輯代碼的時候(例如編輯 EJB 實現類,但不改變 EJB 的接口 )啟用了 hot-method 替換,那麼將立即改變正在運行的應用程序的代碼。請見 WebSphere Studio 的在線幫助中的“Hot-method 替換”。您也可以重啟個別項目,這比重 新啟動整個項目要快得多。然而,許多變更需要重啟測試服務器才能實現;請見 WebSphere Studio 的在線幫助中的“何時需要重啟測試服務器”。也可參閱“調試服 務器上的企業級 bean”和“調試服務器上的 servlet”。
問:在 Web 應用程序中,我們希望將 uid 和 pwd 傳遞到 EJB 層中,以便會話 EJB 能 夠通過 uid 和 pwd 連接到後端系統。我們不想將 uid 和 pwd 作為參數傳遞,或者存儲到 一些從 Web 層到 EJB 層傳遞的對象中。同時,存在不同的流程,它需要使用 uid 和 pwd 來連接後端。您能推薦完成該任務的解決方案嗎?
答:對於 J2EE 應用程序,所有用戶都使用同樣的登錄信息來訪問後端系統。J2EE 不能 使每個應用程序的用戶都使用各自的登錄信息。您的 EJB 層應當是無狀態的服務,該服務由 無狀態的會話 bean 來負責管理,所以不能存儲用戶的數據,如用戶名或密碼。您可以在用 戶的 HTTPSession 中存儲這些項目,但是這可能是巨大的潛在安全漏洞,並且登錄信息可能 不是非常有用的。所以,您需要使用 J2EE 服務來訪問後端系統,它對於所有用戶都使用同 樣的登錄信息。
如果您的後端系統是 JDBC 數據庫,那麼您應當將登錄信息與數據源聯系起來。例如,在 WebSphere Studio 中,在服務器配置編輯器中添加登錄信息作為安全頁面上的 JAAS 認證條 目,然後將其指定為數據源容器管理的認證別名(在數據源頁面上)。對於其他的後端系統 ,您應當獲取或開發適合於 J2EE 連接器體系結構(J2EE Connector Architecture)的適配 器,它也提供了登錄信息。
如果您有兩種類型的用戶,那麼他們應當使用兩種不同的登錄信息,我的文章消除 J2EE 1.3 的服務探測器實現中的緩存中討論了如何使用兩個不同的 EJB 類來完成此項工作(登錄 )。顯而易見,該技術不能使得成百上千的用戶都用他們自己的登錄信息登錄。
問:我不是 EJB 專家,但是我已經學習了 IBM 提供的該方面的大量的教程和紅皮書。我 個人認為 WebSphere Studio 生成“管理的代碼”(它被優化來管理容器)的能 力激發了開發人員更大的創造力,遠遠超過不使用 EJB 開發的時候。這甚至適用於用不到 EJB 的情形。我的問題是:應當糾正它嗎?我已經試著讓我的公司從純生產的角度來學習 WebSphere Studio 或 WebSphere Application Server 的 EJB 開發,但外面的顧問已經發 現了所有 EJB 的負面案例。
如果 IBM 有以小型或中型商店為對象而編寫的白皮書,那麼它將起到幫助作用。該商店 展示了比“Banking”應用程序(使用 WebSphere Studio 和類似於 Spring/Hibernate/JDO/“whatever”解決方案的 WebSphere Application Server 來開發的應用程序)更復雜的基於 web 的 EJB 應用程序。我認為加快設計及開發應 用程序的速度要與減少實際編寫的代碼量同時進行,通過使用 WebSphere Studio 能夠使代 碼編寫更高效。這假設工具能有效地支持您的向導生成的代碼。
花費的時間、創建的代碼、應用程序的性能及每方面的耗費的具體細節都能證明通過使用 WebSphere Studio 或 WebSphere Application Server 使得 J2EE 或 EJB 開發比一行一行 地推敲業務及管理代碼更加高效且可維護。再一次,將與提高整體性能相關的硬件耗費同縮 短開發時間及提高對於龐大的代碼庫的維護能力所需的耗費進行權衡之後,我認為前者可以 忽略不計。
答:您對於向 SMB 市場提供更多的市場及技術材料的意見我十分贊同,但是在我的部門 這並不實際。我所能做的是試著回答技術問題。
您在正確的軌道上,也就是您應當最大限度地利用這些工具使得您的工作更簡單,最大限 度地利用容器使得代碼的編寫工作更容易。簡短的代碼更易於編寫、測試、調試、維護及通 過端口傳輸。您的代碼應以您唯一的業務值為主,而不是尋找每個典型的應用程序的需求, 這可以由容器來處理。
我對 EJB 的負面案例沒有強烈的興趣。許多由於 EJB 1.0 的時間框架和忽視諸如本地接 口和容器管理的關聯(container-managed relationships,CMR)的改進。大多數負面案例 包含實體 bean 並忽視會話及消息驅動的 EJB 的危險程度。
即使使用實體 bean,O/R 映射還是非常困難的,那麼您使用什麼會好一些呢?我建議開 發者開始使用 CMP 實體 bean 來將他們的域建模並且處理他們數據庫的 O/R 映射。“ 然而 CMP 是非常慢的!”也許,O/R 映射是通用的,至少對於 CMP 而言,您使用容器 來優化該流程。IBM 有許多開發人員致力於將 O/R 映射工作做得盡可能好。我想問每個客戶 :您真的認為您的團隊能夠開發更好的代碼嗎?(尤其是他們是否已經認為 EJB 太難了?) 我認為首先嘗試 CMP。如果證實它確實太慢了(或不能忍受),那麼確定出現問題的特定的 bean 並替換它們。然後您需要再次運行您的加載測試,並且驗證您的新代碼真的優於它所取 代的 CMP 代碼。如果開發者嚴格地檢查結果,並且不相信傳聞,我認為他們會發現標准的 J2EE 的特點及 WebSphere 支持對於他們實際工作是非常有利的。
問:我們使用 WebSphere Studio 5.0 作為開發環境開發了一個 J2EE 應用程序。但是我 們希望將其部署在 WebSphere Application Server 4.0 上。由於 EAR 文件是由 WebSphere Studio 5.0 生成的,所以它兼容 WebSphere Application Server 5.0。它給出了關於 DTD 的錯誤。考慮到相關的 EJB,我們僅使用了無狀態會話 bean。需要哪些改變?在 WebSphere Application Server 4.0 中的哪些地方需要部署應用程序?
答:如果我正確地理解了您的問題,那您的意圖是使用 WebSphere Studio 5.0(目前最 新的版本是 5.1.2,所以您可能希望升級到該版本)來開發應用程序,並將其部署在 WebSphere Application Server 4.0 中。看上去您為 WebSphere Application Server 5.0 開發應用程序,這是 WebSphere Studio 5.0 的缺省模式,目前它不能部署而且 WebSphere Application Server 4.0 也是如此,所以您想知道原因及應該做什麼。我希望正確地理解了 您的問題。
好消息!您一定可以使用 WebSphere Studio 5.0 來開發 WebSphere Application Server 4.0 應用程序。這是 WebSphere Studio 5.0 所特有的,以便開發者能升級到我們最 新的工具,即使產品不准備升級到最新的 WebSphere Application Server 版本。您僅需要 知道如何做。
您需要做的是為 WebSphere Application Server 4.0 開發應用程序,而不是 WebSphere Application Server 5.0 默認的 WebSphere Studio 5.0。下面是關於在哪裡及如何完成這 項工作的兩個例子:
在 J2EE 透視圖中,當您選擇 New -> Enterprise Application Project 時,請選擇 創建 J2EE 1.2 項目。這樣做是因為 WebSphere Application Server 4.0 支持 J2EE 1.2, 不是 J2EE 1.3 默認的 WebSphere Studio 5.0。
同樣在 J2EE 透視圖中,當您選擇 New -> EJB Project 時,請選擇創建 EJB 1.1 項 目。這樣做是因為 WebSphere Application Server 4.0 和 J2EE 1.2 支持 EJB 1.1,不是 EJB 2.0 默認的 WebSphere Studio 5.0。(當然,您不能獲得最新的 EJB 2.0 特征,但是 為此您需要升級到 WebSphere Application Server 5.0.2 或之後的版本。)
在 Server 透視圖中,當您選擇 New -> Server and Server Configuration 時,請 選擇創建服務器配置類型為 WebSphere v4.0 Server Configuration 的服務器。您可以在 Server Type 列表的 WebSphere version 4.0 文件夾中找到它。這創建了測試服務器,它是 WebSphere Application Server 4.0 獨立的服務器,為了能測試您部署在完整的 WebSphere Application Server 4.0 中的 J2EE 1.2 應用程序。
在 Window -> Preferences 中,J2EE 下,對於部署中所用的最高的 J2EE 版本,您 可以選擇 J2EE 1.2。然後,WebSphere Studio 將認為您正在為 WebSphere Application Server 4.0(或另一個 J2EE 1.2 容器)進行部署。
問:這是有關事務管理和回滾的設計問題,它們被編碼在單獨的 DB2® 實例(非分布 式事務)上。應用程序使用 DAO 模式來將數據存儲到多個表中,一個應用程序使用的每個 DAO 都保存在一張表中。會話外觀 EJB 業務方法調用了一個以上的 DAO 來將其保存在一張 以上的表中。啟用了管理事務的容器。我閱讀了一些聲明的事務管理的文章,您需要完成其 中的一件事:
使用業務方法中的 setRollBackOnly()
使業務方法拋出運行時的異常
目前,已經選擇了第二項;構造 DAOException 來擴大 RuntimeException,並且當錯誤 發生時所有的 DAO 類都拋出 DAOException 實例。請您給出建議,哪個選擇是最好的?哪個 能使我們的代碼有更好的復用性?對於第一種選擇,我認為您需要為每個業務方法添加額外 的代碼行 setRollBackOnly(),我認為這很麻煩。
使用 WebSphere Studio V4 IDE 測試環境,事務管理及回滾會很好地進行,但是無論何 時將應用程序部署到 WebSphere Application Server V4 上,都不會有回滾發生。存在任何 特定的配置或設置來啟用 WebSphere Application Server V4 上聲明的事務管理嗎?
答:您很好地利用了模式。數據訪問對象(Data Access Object,DAO)及會話外觀 (Session Facade)都是非常值得一用的。由於您使用 EJB,所以進入了普遍存在的困境中 :如何實現您的 EJB 代碼及如何使用應用程序的異常?何時使用 setRollbackOnly()?怎樣 同時配合使用它們?
應用程序異常表示發生了業務邏輯錯誤:取款超出了賬單余額、預訂已被訂出的座位、獲 取已被凍結的信用卡的費用等等。這同系統異常不同,系統異常表示系統級別的錯誤,如耗 盡內存或者數組越界。根據 EJB 規范(第 18 章)中指出的,應用程序異常必須是 Exception 的子類,並且不能是 RuntimeException 或 RemoteException 的子類,這是非常 好的建議。同時,根據該規范,容器必須能夠捕獲系統異常,標記事務用於回滾,並向EJB 客戶端拋出 RemoteException 或 EJBException 異常。容器必須將應用程序異常傳遞到 EJB 客戶端並且不改變該異常以及事務。
我認為這是非常矛盾的,系統異常引發了自動回滾而應用程序異常不能。已經拋出了異常 ,那麼您真的要執行這些事務嗎(哪個是自動的行為)?我不這麼認為。然而,這是 EJB 的 工作方式。
因此,對於您的情況:您的應用程序異常類是 RuntimeException 的子類。這是不好的。 當它自動執行回滾的同時,也將您有含義的描述的應用程序異常轉換成了通用的異常。規范 中指出不要這樣做。
您必須自己處理回滾。這意味著您在會話外觀(您的 EJB 容器的最高層)中編寫代碼時 需要養成這樣的習慣——捕獲應用程序異常、調用 setRollbackOnly() 方法並重 新拋出同樣的異常以便使 EJB 客戶端知道發生了什麼。這是編寫優秀的 EJB 代碼的方法: 在向 EJB 容器外拋出異常之前,請不要使用 RuntimeException 的子類及 setRollbackOnly() 方法。
問:先前我的應用程序是基於 WebSphere 4.0 的 J2EE 1.2 標准開發的。目前,我試著 使用 WebSphere Studio 5.0(WebSphere 5.0)的 J2EE 1.3 標准轉換它。我將應用程序從 j2ee1.2 移植到 j2ee1.3 的級別。
我有兩個模塊,一個是 EJB 模塊(它包含所有的 EJB),另一個是 Web 模塊。該 Web 模塊被成功地轉換成每個 J2EE 1.3 標准。該 EJB 模塊在轉換過程中出現了一些錯誤。日志 文件如下:
Info: Project structure did not need migration: SCLS-ejb.
Info: J2EE version level did not need migration: SCLS-ejb.
Info: Migration was not required for META-INF/ejb-jar.xml.
Error: java.lang.NullPointerException
Error: Unable to migrate the Map and Schema file structure in project SCLS-ejb
由於這個錯誤,我不能正常地運行應用程序。所有的實體 bean 都不起作用。我不能使用 實體 bean 來插入記錄。
答:您已經使用了 WebSphere Studio 5.0 中的 J2EE Migration Wizard 試圖將您的 J2EE 1.2 應用程序移植到 J2EE 1.3,但是由於使用了 NullPointerException 而使其失敗 了。由於我不了解您的代碼,所以判斷工具出現的故障是很困難的。您或許需要求助於 IBM Support。至於您的 EJB 代碼為什麼不能正常地執行,可能與您移植工具中出現的故障有關 ,但也可能因為您需要移植代碼。移植向導僅更新了您的部署描述符,而沒有更新 EJB 實現 中的代碼。請見 WebSphere Studio 在線幫助中的“移植 J2EE 應用程序”和 “從 J2EE 1.2 移植到 1.3”。
問:我真需要學習 EJB 嗎?
答:我要講一個在我出席 WebSphere Technical Exchange 會議時發生的故事。我提出了 分布式(XA)事務上的會話及實驗:如何將其編碼及它們如何工作。該實驗由一些簡單的樣 例代碼組成,主要是由 JDBC 數據庫及 JMS 消息系統更新的無狀態會話 bean(EJB),因此 需要分布式的事務。該樣例還包含被 SSB 簡單調用的 servlet。該實驗進行得非常好,事務 回滾按預期的計劃進行,所有都很順利。實驗之後,客戶問我:“真是太棒了!我如何 能夠僅使用 servlet 來完成它?”回答是:您不能。我問他為什麼不使用 EJB。他和 他的合作者都感到 EJB 很難。即使 EJB 及容器管理的任何內容能使復雜的編程工作變得更 簡單,人們仍舊認為它們不夠簡單。
該故事的含義是:如果您有完成復雜任務的工具,並且希望完成那些任務,那麼您需要學 習這些工具。我不想論證 EJB 是容易的,但是我不認為用它能非常容易地完成復雜的任務: 事務、安全、池、遠程調用——當然,由於實體 bean 具有容器管理的持久性。 其他的哪些技術使您能夠使用面向幾百個用戶的對象來支持上千個用戶?其他的哪些技術使 您能夠聲明您的事務模型、安全模型、持久性模型等在 XML 中的模型並且能在運行時運行那 些模型?
Java(J2SE)包含龐大的類庫,使您開發應用程序時不能任意妄為。J2EE 包含服務及框 架,它們完成了許多您應用程序所需的工作。使容器完成盡可能多的工作,這樣您的應用程 序就不必去做了。以盡可能少的代碼編寫您的應用程序,並且使容器來完成此項工作。代碼 量越少,開發進度就越快,維護越容易,且能更快地通過端口傳輸到 J2EE 和 WebSphere Application Server 的下一個版本中。因此,我的建議是盡可能多地掌握容器給您帶來的益 處,以及諸如 WebSphere Studio Application Developer 之類的開發工具使您能完成哪些 工作,並且最大限度地利用它們。
問:我應當使用同步或異步的信息傳遞嗎?
答:該問題一直存在。我們正在使用 RPC(例如,RMI、CORBA、具有遠程接口的 EJB 等 等);為什麼我們應當使用 JMS 或消息傳遞?通常,當用戶等候回答時,由於用戶是同步的 ,所以可以同步地調用。當一個應用程序調用其它的應用程序時,進行異步調用。如果一個 應用程序要向其他一些應用程序通告事件,那麼也是異步調用。同步調用極易受破壞,所以 為了使遠程調用更穩固,要進行異步調用。
存在這樣的理解——消息傳遞比 RPC 慢且低效。然而,消息傳遞確實有比 RPC 更高的地方,僅有一點性能差異,除非您加入了高品質的服務,如持久性的消息傳遞。 如果消息傳遞很慢,這由於您的網速很慢,在這種情況下 RPC 也會很慢或者根本不能工作。
通常用戶接口不能支持異步調用,因為 UI 阻礙了調用,可能需等候一段時間。一種技術 是重載該頁面,直到獲得結果為止。請見由 Kyle Brown 所著的 J2EE 中的異步查詢。更好 的方法是重新設計 UI,使其不能同步。例如,電子商務站點當打包並傳輸訂單的時候不會出 現浏覽器阻礙。它告知用戶“謝謝訂購”並且當訂單傳輸的時候發送包含該包裹 號碼的電子郵件。這需要 UI 打破工作流,異步地執行,因此您需要諸如 Process Choreographer 之類的工作流引擎。然後,處理以異步的方式完成,並且用戶可以隨時檢查 它的進行情況。
這是 Web 服務的缺陷,沒有價值。目前,Web 服務(WS-I 基本概要 1.1)是同步的。調 用者發出 HTTP 請求,並且阻止了等候 HTTP 響應。由於 Web 服務是用於應用程序到應用程 序的信息傳遞,所以若它們能夠支持異步的信息傳遞將會更加有用。
問:SOA 和 ESB 之間的區別是什麼?
答:面向服務的體系結構(Service Oriented Architecture,SOA)是一種方式或架構, 用於具有自服務功能的應用程序,應用程序隨後通過用戶接口(UI)或經過工作流將其聚合 成用戶的功能。服務不僅是可復用代碼的組件,更是運行程序的一部分,客戶端可以不必合 並它自己的代碼直接調用該程序。事實上,應用程序的界限變得非常模糊了,它包括所有能 被調用來執行它的功能的服務。
企業服務總線(Enterprise Service Bus,ESB)是用於調節 SOA 中的調用者及服務提供 者的機制。它使得調用者在不知道提供者或提供者使用的地址的情況下調用該服務。ESB 可 在多個提供者、提供者的負載平衡及停止使用提供者(當失效時)之間進行選擇,並且基於 調用者的需求在提供者之間進行選擇,這些提供者提供了各種質量級別的服務。ESB 能夠調 節同步或異步服務,事實上對於同一服務可以提供同步及異步的訪問。
因此 SOA 和 ESB 是相對應的。具備 SOA 的應用程序應當使用 ESB 來調用它的服務。 SOA 和 ESB 不必用 Web 服務實現。然而,經常需要 ESB 來調用服務,該服務提供自我描述 及發現的能力,這由 Web 服務幫助完成。在 SOA 中經常需要由一種技術實現的調用者,它 們用於調用由其它技術實現的服務,這也由 Web 服務幫助完成。所以 SOA、ESB 和 Web 服 務都集中於創建這樣的領域——一個應用程序中的功能在其它應用程序中也是可 用的,本質是復用性。