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 教程。
Juergen Hoeller 的最新博客宣布 Spring 3.0 的第一个里程碑版本发布。主要亮点包括添加了 REST 支持、Spring Expression Language (EL) 以及迁移到 Java 5 及更高版本。博客文章包含详细信息。
下载 | Subversion | JIRA | 论坛
我很高兴地宣布 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 都在其 J2EE 应用服务器中嵌入了 Tomcat 版本,JBoss Web 2.1.1 的开发者版本也嵌入了 Tomcat),但 tc Server 的独特之处在于它保留了 Tomcat servlet/JSP 编程模型。为 Tomcat 编写的应用可 100% 移植到…
亲爱的 Spring 社区,
我很高兴地宣布我们已经发布了 Spring IDE 2.2.1。此版本主要是错误修复和维护版本,但也包含一些重要的用户级更改。
在Spring IDE 博客获取更多信息
请关注未来一周来自 SpringOne 的更多工具相关公告。
OSGi 联盟决定通过在公共注册表中列出特定于供应商的 manifest 头部来容纳它们。目的是避免供应商之间以及供应商与 OSGi 自身头部之间的冲突。
注册表目前包含 OSGi 自己的头部、SpringSource dm Server 引入的头部,以及 bnd 工具使用的两个头部。
正如在第 1 部分中提到的,在这第二篇博客文章中我没有使用 Spring Framework,而是专注于使用 SpringSource dm Server™ 和 SpringSource Tool Suite 来部署“纯粹的” GWT。
另请参阅第 1 部分,了解 GWT StockWatcher 示例的背景和我正在使用的软件。
这里描述的分步方法将基于我们在第 1 部分中所做的工作,而不是从头开始。我们在第 1 部分中唯一要改变的事情是移除对以下内容的显式依赖:gwt-servlet.jar库。
好消息是,创建这些依赖项的大部分工作已经完成。 SpringSource Enterprise Bundle Repository 包含了大多数常用库的“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 导入了 eclipselink 包,范围是 [1.0, 2.0)。显然,只有 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 中,然后尝试启动应用程序 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,使其能够接受版本 2.0 的 eclipselink 包,并放宽 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 并启动应用程序 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
现在两个应用程序 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 自动诊断。
我很高兴宣布 Grails 自 SpringSource 收购 G2One 以来的第一个版本发布。Grails 1.0.4 包含多项改进以及 Grails 所依赖的关键库的升级,可从 Grails 下载页面下载。更具体地说,Grails 1.0.4 包含了大约一周前发布的最新的 Spring 2.5.6 版本。
除了这些改进之外,此版本中还有一些有趣的新功能。第一个是添加了一个功能,可以更好地支持 GORM 中 Hibernate 用户类型定义的映射。您现在可以映射自定义用户类型…