SpringOne Americas 2008 的幻燈片和演示
正如我向參加我會議的聽眾承諾的那樣,這是關於我的 dm Server 和併發會話的內容。
dm Server 介紹
本次演示的幻燈片和演示程式碼已附在我的上一篇文章中:《SpringSource dm Server 入門》。
在會議期間,我遇到了來自 Spring by Example 的 David Winterfeldt,他向我推薦了他很棒的 dm Server 教程。
正如我向參加我會議的聽眾承諾的那樣,這是關於我的 dm Server 和併發會話的內容。
本次演示的幻燈片和演示程式碼已附在我的上一篇文章中:《SpringSource dm Server 入門》。
在會議期間,我遇到了來自 Spring by Example 的 David Winterfeldt,他向我推薦了他很棒的 dm Server 教程。
我很高興地宣佈,Spring Framework 3.0 M1 終於可以下載了!
本版本包含多項重大變更,包括 3.0 主要主題的開始,例如 EL 和 REST 支援
以及各種細微增強。
請注意,Spring Framework 3.0 需要 Java 5 或更高版本以及 J2EE 1.4 或更高版本。我們將 Java 6 和 Java EE 5 作為主要的平臺級別進行構建 - 但請放心,我們將保留與支援 Java 5 的 J2EE 1.4 伺服器(如 WebLogic 9 和 WebSphere 6.1)的相容性。
我們還移除/棄用了一些過時的類。更多資訊…
我們剛剛在本週於 SpringOne Americas 會議上釋出了一款名為 SpringSource tc Server 的新產品。SpringSource tc Server 是一個基於 Apache Tomcat 的企業級 Web 應用伺服器。
儘管 SpringSource 並非首家圍繞 Apache Tomcat 構建產品的公司(WebSphere Community Edition 和 JBoss 都將 Tomcat 版本嵌入到其 J2EE 應用伺服器中,並且 JBoss Web 2.1.1 的開發者版本也嵌入了 Tomcat),但 tc Server 的獨特性在於它保留了 Tomcat servlet/JSP 程式設計模型。為 Tomcat 編寫的應用可以 100% 可移植到…
OSGi Alliance 決定透過在公共登錄檔中列出供應商特定的 manifest 頭部來容納它們。目的是避免供應商之間以及供應商與 OSGi 自身頭部之間的衝突。
登錄檔目前包含 OSGi 自身的頭部、SpringSource dm Server 引入的頭部以及 bnd 工具使用的兩個頭部。
正如在第 1 部分中提到的,我在第二篇部落格文章中沒有使用 Spring Framework,而是專注於 SpringSource dm Server™ 和 SpringSource Tool Suite 來部署“純”GWT。
有關 GWT StockWatcher 示例的背景資訊以及我正在使用的軟體,請參閱第 1 部分。
此處描述的循序漸進的方法將基於我們在第 1 部分中所做的工作,而不是重新開始。我們在第 1 部分中所做的唯一現在要改變的事情是移除對以下項的顯式依賴:gwt-servlet.jar庫。
好訊息是,建立這些依賴項的大部分工作已經為你完成。SpringSource 企業 Bundle 倉庫包含大多數常用庫的“bundle 化”版本。然而,在撰寫本文時,我們的 GWT 依賴項就是一個您需要自己將其轉換為 bundle 的庫示例…
在他最近的部落格文章中,Glyn 介紹了 OSGi 的“uses”指令。在這篇部落格中,我想深入探討 uses 約束違規的原因,並提供一些診斷應用中 uses 問題的技巧。
在大多數示例中,我將使用原生的 Equinox 而不是 dm Server。這是因為 uses 約束並非 dm Server 特有,而是與所有 OSGi 使用者相關。在這篇部落格的末尾,我將演示 dm Server 內建的一些智慧約束失敗診斷功能。
uses 違規最常見的原因是一個或多個依賴約束之間的不匹配。下面是三個 manifest 示例:
Manifest-Version: 1.0
Bundle-Name: Spring Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: spring
Bundle-Version: 2.5.5
Export-Package: spring.orm.hibernate;version="2.5.5";uses:="eclipselink"
Import-Package: eclipselink;version="[1.0, 2.0)"
Manifest-Version: 1.0
Bundle-Name: EclipseLink 1 Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: eclipselink
Bundle-Version: 1
Export-Package: eclipselink;version="1.0.0"
Manifest-Version: 1.0
Bundle-Name: EclipseLink 2 Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: eclipselink
Bundle-Version: 2
Export-Package: eclipselink;version="2.0.0"
這裡您可以看到一個 spring bundle 和兩個 eclipselink bundle。顯然,這些不是真實的 bundle。spring bundle 匯入了版本範圍為 [1.0, 2.0) 的 eclipselink 包。很明顯,只有 eclipselink_1 bundle 可以滿足此約束。現在,考慮以下來自兩個不同應用的 manifest:
Manifest-Version: 1.0
Bundle-Name: App1 Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: app1
Bundle-Version: 1.0.0
Import-Package: spring.orm.hibernate,eclipselink;version="[1.0, 1.0]"
Manifest-Version: 1.0
Bundle-Name: App2 Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: app2
Bundle-Version: 1.0.0
Import-Package: spring.orm.hibernate,eclipselink;version="[2.0, 2.0]"
這裡我們可以看到 app1 匯入了版本範圍為 [1.0, 1.0] 的 eclipselink,app2 匯入了版本範圍為 [2.0, 2.0] 的 eclipselink。如果我將這些 bundle 安裝到 Equinox 中,然後嘗試啟動 app bundle,控制檯會顯示如下內容:
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
2 RESOLVED spring_2.5.5
3 RESOLVED eclipselink_1.0.0
4 RESOLVED eclipselink_2.0.0
5 ACTIVE app1_1.0.0
6 INSTALLED app2_1.0.0
這裡我們可以看到 spring 和 eclipselink bundle 都已解析。app1 bundle 已經啟動,但 app2 bundle 無法啟動。要找出原因,我們可以使用 diag 命令:
osgi> diag app2
file:/Users/robharrop/dev/resdiag/uses/app2/bin [6]
Package uses conflict: Import-Package: spring.orm.hibernate; version="0.0.0"
這裡我們可以看到 app2 bundle 無法解析,因為它匯入的 spring.orm.hibernate 包存在 uses 衝突。這意味著 app2 對 spring.orm.hibernate 的匯入無法滿足,因為它的另一個匯入與可能提供 spring.orm.hibernate 的 bundle(在本例中是 spring bundle)上的 uses 約束髮生衝突。
診斷這個問題的第一步是找出 spring.orm.hibernate bundle 的可能提供者。根據我們的用例,我們知道唯一可能的提供者是 spring bundle,但如果您不知道提供者,可以使用 packages 命令找到它們:
osgi> packages spring.orm.hibernate
spring.orm.hibernate; version="2.5.5"<file:/Users/robharrop/dev/resdiag/uses/spring/bin [2]>
file:/Users/robharrop/dev/resdiag/uses/app1/bin [5] imports
這表明 spring.orm.hibernate 包由 bundle 2 匯出。瞭解這一點後,我們可以找出 bundle 2 中 spring.orm.hibernate 包的 uses 指令中列出了哪些包:
osgi> headers 2
Bundle headers:
Bundle-ManifestVersion = 2
Bundle-Name = Spring Bundle
Bundle-SymbolicName = spring
Bundle-Version = 2.5.5
Export-Package = spring.orm.hibernate;version="2.5.5";uses:="eclipselink"
Import-Package = eclipselink;version="[1.0, 2.0)"
Manifest-Version = 1.0
這裡我們可以看到 uses 中唯一的包是 eclipselink 包,所以它一定是罪魁禍首。實際上,我們可以看到 Spring bundle 需要版本範圍為 [1.0, 2.0) 的 eclipselink,而 app2 需要版本範圍為 [2.0, 2.0] 的 eclipselink - 這兩個範圍是互斥的,這意味著 app2 無法與 spring bundle 連線到相同版本的 eclipselink。
如果 uses 列表很長,您可以透過找出列出的哪些包具有多個提供者來縮小可能的違規範圍。要出現 uses 約束違規,必須始終存在不止一個提供者。
版本不匹配不是導致依賴約束不匹配的唯一原因。約束不匹配也可能是由於屬性以及版本造成的。
如果我們回到之前的例子,修改 spring bundle 的 manifest,使其能夠接受 eclipselink 包的 2.0 版本,並放寬 app1 的範圍,使其能夠接受任何高於 1.0 的版本,我們應該能夠解決問題:
Manifest-Version: 1.0
Bundle-Name: Spring Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: spring
Bundle-Version: 2.5.5
Export-Package: spring.orm.hibernate;version="2.5.5";uses:="eclipselink"
Import-Package: eclipselink;version="[1.0, 2.0]"
Manifest-Version: 1.0
Bundle-Name: App1 Bundle
Bundle-ManifestVersion: 2
Bundle-SymbolicName: app1
Bundle-Version: 1.0.0
Import-Package: spring.orm.hibernate,eclipselink;version="1.0"
安裝 bundle 並啟動 app bundle 表明這一變化帶來了很大的不同:
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
1 RESOLVED spring_2.5.5
2 RESOLVED eclipselink_1.0.0
3 RESOLVED eclipselink_2.0.0
4 ACTIVE app1_1.0.0
5 ACTIVE app2_1.0.0
現在兩個 app bundle 都可以啟動了。不幸的是,還有一個更微妙的問題等待著我們。取決於安裝順序,這組 bundle 可能仍然無法一起執行。為了說明這一點,讓我們將 spring、eclipselink_1 和 app1 作為一次事務安裝,並啟動 app1:
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
1 RESOLVED spring_2.5.5
2 RESOLVED eclipselink_1.0.0
3 ACTIVE app1_1.0.0
現在,讓我們安裝 eclipselink_2 和 app2:
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
1 RESOLVED spring_2.5.5
2 RESOLVED eclipselink_1.0.0
3 ACTIVE app1_1.0.0
4 RESOLVED eclipselink_2.0.0
5 INSTALLED app2_1.0.0
app2 bundle 無法啟動。diag 的輸出告訴我們原因:
osgi> diag app2
file:/Users/robharrop/dev/resdiag/uses/app2/bin [5]
Package uses conflict: Import-Package: spring.orm.hibernate; version="0.0.0"
uses 約束問題又回來了。按照上一節中確定的診斷步驟在這裡不起作用,因為沒有依賴約束不匹配——我們知道這一點是因為第一次這些 bundle 解析得很順利。
這裡的問題是解析順序。這些 bundle 是分兩個獨立的批次安裝和解析的。第一個批次包含 spring、eclipselink_1 和 app1,第二個批次包含 eclipselink_2 和 app2。當第一個批次被解析時(由於啟動了 app1 bundle),spring bundle 對 eclipselink 包的匯入被連線到 eclipselink_1 bundle。這可以透過控制檯確認:
osgi> bundle app1
file:/Users/robharrop/dev/resdiag/uses/app1/bin [3]
Id=3, Status=ACTIVE Data Root=/opt/springsource-dm-server-1.0.0.RELEASE/lib/configuration/org.eclipse.osgi/bundles/3/data
No registered services.
No services in use.
No exported packages
Imported packages
spring.orm.hibernate; version="2.5.5"<file:/Users/robharrop/dev/resdiag/uses/spring/bin [1]>
eclipselink; version="1.0.0"<file:/Users/robharrop/dev/resdiag/uses/eclipselink1/bin [2]>
No fragment bundles
Named class space
app1; bundle-version="1.0.0"[provided]
No required bundles
注意,匯入包部分顯示 eclipselink 版本 1.0.0 是從 eclipselink_1 bundle 匯入的。安裝第二個批次時,app2 bundle 無法解析,因為它需要版本為 2.0.0 的 eclipselink,而 spring 已經連線到版本為 1.0.0 的 eclipselink。當所有 bundle 作為一次性安裝並解析時,OSGi 解析器將嘗試滿足所有約束,包括確保 spring.orm.hibernate 上的 uses 約束得到滿足。
要解決這個問題,我們不需要更改我們的 bundle。相反,我們可以選擇一次性重新安裝所有 bundle,或者我們可以對 spring bundle 觸發重新整理——這實際上是要求 OSGi 重新執行解析過程。現在 eclipselink_2 bundle 已經安裝,我們可以期待一個不同的結果:
osgi> refresh spring
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
1 RESOLVED spring_2.5.5
2 RESOLVED eclipselink_1.0.0
3 ACTIVE app1_1.0.0
4 RESOLVED eclipselink_2.0.0
5 ACTIVE app2_1.0.0
osgi> bundle spring
file:/Users/robharrop/dev/resdiag/uses/spring/bin [1]
Id=1, Status=RESOLVED Data Root=/opt/springsource-dm-server-1.0.0.RELEASE/lib/configuration/org.eclipse.osgi/bundles/1/data
No registered services.
No services in use.
Exported packages
spring.orm.hibernate; version="2.5.5"[exported]
Imported packages
eclipselink; version="2.0.0"<file:/Users/robharrop/dev/resdiag/uses/eclipselink2/bin [4]>
No fragment bundles
Named class space
spring; bundle-version="2.5.5"[provided]
No required bundles
請注意,重新整理 spring 導致 app2 bundle 解析。在 spring 中對 eclipselink 包的連線已更改為由 eclipselink_2 bundle 中匯出的 2.0.0 版本來滿足。
當您在 dm Server 中遇到 uses 約束違規時,我們已經嘗試為您執行一些分析步驟,特別是識別可能不匹配的依賴約束:
Could not satisfy constraints for bundle 'app2' at version '1.0.0'.
Cannot resolve: app2
Resolver report:
Bundle: app2_1.0.0 - Uses Conflict: Import-Package: spring.orm.hibernate; version="0.0.0"
Possible Supplier: spring_2.5.5 - Export-Package: spring.orm.hibernate; version="2.5.5"
Possible Conflicts: eclipselink
Uses 約束在企業庫中很常見,手動診斷失敗可能是一場真正的噩夢。特別是,當您有一個匯出包,其 uses 子句中列出了 10 個或更多包時,確定可能的衝突可能會非常耗時。因此,自動化診斷是必須的,我希望不斷改進 dm Server 中的診斷程式碼,以便處理常見錯誤變得微不足道。
在下個版本中,我們計劃將診斷工具直接構建到我們的 dm Server Eclipse 工具中,以便 dm Server 能夠自動診斷大多數此類問題。
我很高興宣佈自 SpringSource 收購 G2One 以來的首個 Grails 版本釋出。Grails 1.0.4 包含多項改進以及對支撐 Grails 的關鍵庫的升級,可以從 Grails 下載頁面下載。更具體地說,Grails 1.0.4 集成了大約一週前釋出的最新 Spring 2.5.6 版本。
除了改進之外,此版本中還有幾個有趣的新功能。第一個是添加了一項新功能,可以更好地支援 GORM 中 Hibernate 使用者型別定義的對映。您現在可以對映自定義使用者型別…
我很高興地宣佈,SpringSource 已經收購了 G2One,這家公司是 Grails 和 Groovy 的幕後推手。
Grails 與 Spring 和 SpringSource 技術非常契合。Grails 構建在 Spring 之上。它提供了另一種採用 Spring 的途徑,Spring 是企業 Java 的事實標準組件模型。Spring(和 Java)的所有強大能力都隱藏在每個基於 Grails 的應用的表面之下——這是 Grails 能夠擴充套件到企業應用的關鍵原因,也是 Spring 強大和靈活性的證明。
與 Spring 一樣,Grails 是一項簡化開發者工作並提高生產力的技術。正如我們的新標語,應對 Java 複雜性之戰的武器,所反映的那樣,簡化始終是我們作為一家公司和技術人員工作的核心…
本部落格假設您已安裝 SpringSource Tool Suite 1.1.1(我使用的是 Eclipse 3.4 版本)、dm Server 1.0.0 和 GWT 1.5。它還假設您對 Java 程式設計有很好的理解,並對 Javascript 和 Ajax 有基本瞭解。
為了演示中使用的路徑,我在以下位置建立了一個新的 Eclipse 工作區:/Users/bcorrie/gwt/workspace。我包含了一些可以在下面下載的壓縮專案,其中包含一個GWT_ROOT_INSTALL我定義的變數。要使用我的專案,匯入後請導航到“Preferences” -> “Java” -> “Build Path” -> “Classpath Variables” 並定義您自己的GWT_ROOT_INSTALL…