在 SpringSource dm Server 中部署 GWT 应用程序 - 第 2 部分

工程 | Ben Corrie | 2008 年 11 月 24 日 | ...

简介

这是描述在 SpringSource dm Server™ 中构建和部署 GWT 应用程序的分步方法的三个博客系列中的第二个。第一个博客介绍了从 GWT 示例应用程序创建简单 WAR 文件的过程。下一个博客将介绍如何将我们在 第 1 部分 中创建的 WAR 文件转换为 “共享库” WAR。这意味着我们将把应用程序的 GWT 依赖项外部化到一个 OSGi 捆绑包中,以便任何数量的 GWT 应用程序都可以共享它。您可以将其视为使用 GWT 远程处理功能扩展我们的 dm Server。

第 1 部分 中所述,在此第二个博客文章中,我没有使用 Spring 框架,而是专注于 SpringSource dm Server™SpringSource Tool Suite 来部署“纯”GWT。

另请参阅 第 1 部分,了解 GWT StockWatcher 示例和我的软件使用情况的背景信息。

快速回顾

第 1 部分 中,我们从头开始构建了 GWT StockWatcher 示例应用程序作为 Eclipse 项目,然后将代码生成到一个动态 Web 项目中,然后将其部署到 dm Server 中。最后,我们将动态 Web 项目导出到 WAR 文件中,并将其部署在 STS 之外。

此处描述的分步方法将在我们 第 1 部分 中所做工作的基础上进行构建,而不是从头开始。我们在 第 1 部分 中所做的唯一更改是删除对以下内容的显式依赖关系:gwt-servlet.jar库。

步骤 1:将我们的 GWT 依赖项转换为 OSGi 捆绑包

首先,再介绍一些背景信息。“共享库”方法的整体概念是在 dm Server 中使用 OSGi 捆绑包之间的显式导入和导出创建依赖项映射。对于像我们的 StockWatcher 示例这样的小型 WAR,这主要只是一个有趣的学术练习。但是,鉴于许多商业 Web 项目以包含数十甚至数百个依赖 jar 文件的大型 WAR 文件的形式交付,将这些依赖项分解为可共享的资源不仅在占用空间方面有意义,而且还使应用程序的打包、版本控制和维护变得不那么痛苦。

好消息是,创建这些依赖项的大部分工作已经为您完成。SpringSource 企业捆绑包存储库 包含大多数常用库的“捆绑”版本。但是,在撰写本文时,我们的 GWT 依赖项是您必须将其转换为捆绑包的库示例……

诊断 OSGi uses 冲突

工程 | Rob Harrop | 2008 年 11 月 22 日 | ...

在他 最近的博客文章 中,Glyn 介绍了 OSGi“uses”指令。在本博客中,我想更深入地探讨 uses 约束冲突的原因,并提供一些在应用程序中诊断 uses 问题的技巧。

对于我将要使用的大多数示例,我将使用原始的 Equinox,而不是 dm Server。这样做的原因是 uses 约束不是 dm Server 特有的,而是与所有 OSGi 用户相关。在本博客的最后,我将演示 dm Server 中内置的一些智能约束失败诊断。

依赖约束不匹配

uses 冲突的最常见原因是依赖约束之一或多个不匹配。例如,考虑以下三个清单

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 捆绑包和两个 eclipselink 捆绑包。显然,这些不是真正的捆绑包。spring 捆绑包具有对 [1.0, 2.0) 范围内的 eclipselink 包的导入。显然,只有 eclipselink_1 捆绑包可以满足此约束。现在,考虑来自两个不同应用程序的这些清单

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。如果我将这些捆绑包安装到 Equinox 中,然后尝试启动应用程序捆绑包,控制台将显示如下内容

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

在这里,我们可以看到 springeclipselink 捆绑包都已解析。app1 捆绑包已启动,但 app2 捆绑包不会启动。要找出原因,我们可以使用 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 捆绑包无法解析,因为其对 spring.orm.hibernate 的导入存在包 uses 冲突。这意味着 app2 中对 spring.orm.hibernate 的导入无法满足,因为其其他导入之一与可能提供 spring.orm.hibernate 的捆绑包(在本例中为 spring 捆绑包)上的 uses 约束冲突。

诊断此问题的第一步是找出 spring.orm.hibernate 捆绑包的可能提供者。我们从我们的用例中知道,唯一的可能提供者是 spring 捆绑包,但是如果您不知道提供者,可以使用 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 包由捆绑包 2 导出。有了这些知识,我们可以找出捆绑包 2spring.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 捆绑包在 [1.0, 2.0) 范围内需要 eclipselink,而 app2[2.0, 2.0] 范围内需要 eclipselink - 这两个范围是不相交的,这意味着 app2 无法连接到与 spring 捆绑包相同的 eclipselink 版本。

如果 uses 列表很长,您可以通过找出列出的哪些包有多个提供者来缩小可能的冲突范围。您必须始终有多个提供者才能看到 uses 约束冲突。

版本不匹配不是依赖约束不匹配的唯一原因。约束可能不匹配,因为属性以及版本。

安装顺序问题

如果我们重新审视前面的示例,并更改 spring 捆绑包的清单,使其能够接受 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"

安装捆绑包并启动应用程序捆绑包表明此更改产生了重大影响

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

现在这两个应用程序捆绑包都可以启动。不幸的是,还有一个更微妙的问题在等待着我们。根据安装顺序,这组捆绑包可能仍然无法一起运行。为了说明这一点,让我们将 springeclipselink_1app1 作为一个事务安装,并启动 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_2app2

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 捆绑包不会启动。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 约束又回来了。运行上一节中确定的诊断步骤在这里将无济于事,因为没有依赖约束不匹配 - 我们知道这一点是因为第一次这些捆绑包解析得很好。

此处的問題是解析顺序问题。捆绑包被分成两个不同的块进行安装和解析。第一块包括 springeclipselink_1app1,第二块包括 eclipselink_2app2。当第一个块解析(作为启动 app1 捆绑包的结果)时,spring 捆绑包与其对 eclipselink 包的导入连接到 eclipselink_1 捆绑包。这可以使用控制台确认

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 捆绑包导入的。当第二个块安装时,app2 捆绑包无法解析,因为它需要版本 2.0.0eclipselink,但 spring 已经连接到版本 1.0.0eclipselink。当所有捆绑包作为一个块安装和解析时,OSGi 解析器将尝试满足所有约束,包括确保可以满足 spring.orm.hibernate 上的 uses 约束。

要解决此问题,我们不需要更改我们的捆绑包。相反,我们可以将捆绑包作为一个块重新安装,或者我们可以对 spring 捆绑包触发刷新 - 有效地要求 OSGi 重新运行解析过程。现在 eclipselink_2 捆绑包已安装,我们可以预期这将产生不同的结果

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 捆绑包解析。 springeclipselink 包的连接已更改,以满足 eclipselink_2 捆绑包中版本 2.0.0 的导出。

在 dm Server 中使用约束

当您在 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 子句中列出了 10 个或更多包时,确定可能的冲突可能非常耗时。因此,自动化诊断是必须的,我希望始终改进 dm Server 中的诊断代码,以便处理常见错误变得微不足道。

在下一个版本中,我们计划将诊断工具直接构建到我们的 dm Server Eclipse 工具中,以便 dm Server 自动诊断大多数这些问题。

SpringSource 旗下首个 Grails 版本

工程 | Graeme Rocher | 2008 年 11 月 14 日 | ...

我很高兴地宣布,自 SpringSource 收购 G2One 以来,Grails 的第一个版本发布了。Grails 1.0.4 包含许多改进以及对支撑 Grails 的关键库的升级,您可以从 Grails 下载页面 下载。更具体地说,Grails 1.0.4 附带了大约一周前发布的 最新 Spring 2.5.6 版本

除了 这些改进 之外,此版本中还有一些有趣的新功能。首先是添加了一个功能,该功能更好地支持在 GORM 中映射 Hibernate 用户类型定义。您现在可以映射自定义用户类型……

对抗复杂性的更多武器:SpringSource 收购 Groovy/Grails 领导者

工程 | Rod Johnson | 2008 年 11 月 11 日 | ...

我很高兴地宣布 SpringSource 已收购 G2One,该公司是 GrailsGroovy 背后的公司。

为什么?

我对这笔交易感到兴奋有很多原因。

Grails 与 Spring 和 SpringSource 技术非常契合。Grails 基于 Spring 构建。它提供了另一种采用 Spring 的途径,Spring 是企业 Java 事实上的标准组件模型。所有 Spring(和 Java)的强大功能都隐藏在每个基于 Grails 的应用程序的表面之下——这是 Grails 可以扩展到企业用途的关键原因,也是 Spring 强大功能和灵活性的证明。

与 Spring 一样,Grails 也是一项简化开发人员生活并提高其生产力的技术。正如我们的新口号“对抗 Java 复杂性的武器”所反映的那样,简化始终是我们作为一家公司和技术人员的核心工作……

Spring for .NET 1.2.0 发布

发布 | Mark Pollack | 2008 年 11 月 10 日 | ...

我们很高兴地宣布 Spring for .NET 1.2.0 现已可用。

下载 | 支持 | 文档| 社区

此版本包含以下新的主要功能

  • WCF 集成 - 使用依赖注入配置 WCF 服务。将 AOP 建议应用于 WCF 服务。
  • MSMQ 集成 - MSMQ 帮助类,可提高开发消息应用程序的效率。提供与 Spring 的事务管理功能的集成。
  • Apache ActiveMQ 集成 - 帮助类,可提高使用 ActiveMQ/NMS 开发消息应用程序的效率
  • Quartz 集成 - 使用依赖注入配置 Quartz 作业、调度程序、触发器。用于实现 Quartz 作业的便捷类。
  • AOP- 新的基于继承的 AOP 代理生成
  • NHibernate 2.0.1 支持。
自 1.1.2 版本以来,此版本包含大约 100 个错误修复和增强功能。

请参阅 更改日志 以获取更多详细信息。

享受!

Spring JavaConfig 1.0.0.M4 发布

发布 | Chris Beams | 2008 年 11 月 7 日 | ...

尊敬的 Spring 社区:
我们很高兴地宣布 Spring JavaConfig 1.0.0.M4 现已可用。
下载 | 参考文档 | API 文档

主要亮点

  • @AnnotationDrivenTx - 支持声明式事务管理
  • @AnnotationDrivenConfig - 支持 @Autowired、@Resource 等。
  • @ComponentScan - 直接从 JavaConfig 扫描 @Component 类
  • @AspectJAutoProxy - 对 @Aspect bean 的一流支持
  • @MBeanExport - 对导出 JMX MBean 的一流支持
  • 完整的 PetClinic 示例现已随发行版一起提供,演示了 JavaConfig 的用法
  • 使用 @ExternalValue 和 @PropertiesValueSource 改进了对外部化值的支持
  • @ImportXml - 从 JavaConfig 引导 Spring XML bean 定义
  • 改进了错误处理
  • ……以及数十个其他 已解决的问题


请试用此里程碑版本,并通过 Spring JavaConfig 论坛问题跟踪器 提供您的反馈。有关更多信息,请访问 Spring JavaConfig 主页

Chris Beams
Spring JavaConfig 负责人

在 SpringSource dm Server 中部署 GWT 应用程序 - 第 1 部分

工程 | Ben Corrie | 2008 年 11 月 7 日 | ...

简介

这将是一系列 3 篇博文,描述在 SpringSource dm Server™ 中构建和部署 GWT 应用程序的分步方法。博文的重点如下
  1. 使用 SpringSource Tool Suite 从头开始构建 GWT StockWatcher 示例应用程序作为 WAR 文件在 dm Server 中部署。
  2. 使用 “共享库” 方法部署:如何从 WAR 中删除 GWT 依赖项并在 dm Server 中将其部署为 OSGi 捆绑包。
  3. 使用 “共享服务” 方法部署:我们将单个 WAR 文件转换为 OSGi 服务,其他应用程序可以共享这些服务并进行热交换。
值得注意的是,在这些前两篇博文中,我并没有在任何地方使用 Spring 框架。Spring 和 GWT 之间的集成本身就是一个主题,我想尽量使每篇博文都尽可能集中。在第三篇博文中,我将展示如何使用 Spring 发布和使用 OSGi 服务,以及如何将其与 GWT 集成。

背景

该博文将采用一种实用的分步方法来构建 此处 描述的 GWT StockWatcher 示例。Google 教程将引导您完成使用 RPC 从头开始构建 GWT 示例所需的步骤。在进行过程中,我将参考教程中的页面,并讨论各种方法的优缺点。

该博文假设您已安装 SpringSource Tool Suite 1.1.1(我使用的是 Eclipse 3.4 版本)、dm Server 1.0.0GWT 1.5。它还假设您对 Java 编程有很好的了解,并且对 Javascript 和 Ajax 有基本的了解。

为了演示中使用的路径的目的,我在以下位置创建了一个新的 Eclipse 工作区:/Users/bcorrie/gwt/workspace。我包含了您可以下载的已压缩项目,其中包含一个GWT_ROOT_INSTALL变量我已定义。要使用我的项目,当您导入它们时,导航到“首选项”->“Java”->“构建路径”->“类路径变量”,并定义您自己的GWT_ROOT_INSTALL……

获取 Spring 时事通讯

通过 Spring 时事通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您快速提升技能。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅,提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看全部