使用 Rational Application Developer 工具将 Java 应用程序转化为基于 OSGi 框架

使用包含的工具将项目转化为使用 OSGi 框架框架

当您将基于 Java 的企业应用转化为开放服务网关初始化框架(Open Service Gateway initiative framework,OSGi),可以获得更好的灵活性、控制性以及高效率。IBM® Rational® Application Developer V8.0 版本之中的新工具可以帮助您创建 OSGi 绑定包,来导出服务,运行进程,并管理依赖。本文演示了不同的方法。

Ken McClamroch, 资深软件工程师, IBM

作者照片Ken 是 IBM Rational 软件的一名系统和集成测试架构师。他最近七年来,主要关注于基于场景的测试,构建端到端应用软件,使用各种类型的技术,包括 Java Enterprise Edition (JEE),SCA 和 OSGi。



Jarett Stein, 高级软件工程师, IBM

Jarett SteinJarett Stein 是 Rational Application Developer 系统验证测试团队的一名成员。他模拟用户使用 IBM Rational 产品,使用 OSGi,web 和 JPA(Java Persistence API)技术工具设计端到端应用软件。



2011 年 3 月 14 日

下载 Rational Application Developer 试用版  |  在线试用 Rational Application Developer
下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。

开发人员可以从本文中学到什么

本文描述了怎样使用新的 Open Service Gateway initiative(OSGi)开发工具与 IBM® Rational® Application Developer V8.0 版本,以将已有的 Java Enterprise Edition(JEE)应用程序转化为基于 OSGi 的应用程序。这些工具,与 WebSphere Application Server Version 7 Feature Pack for OSGi Applications 一起,提供了开发和部署 OSGi 企业应用的支持功能,它类似于 Java EE 应用程序的功能。

一个 OSGi 框架可以组成 Java EE 项目中部署的相同模块,但是它包含了能够作为 OSGi 绑定包定位的 OSGi 元数据,因此能够从 OSGi 框架所提供的管理机制中获益。对于企业应用开发 Java EE 开发人员选择 OSGi 有一些其他的原因:

  • 应用程序可以作为只包含特定应用程序内容的绑定包,一直引用附件,共享库的元数据一起部署。结果,应用程序空间减少了,因为它使用了引用附件管理的库的单独拷贝。该功能删除了 Java EE 应用程序的趋势,该应用程序让相同的 JAR(Java 档案)嵌入到许多企业应用之中。
  • 开发时,Rational Application Developer V8.0 版本之中包含的 OSGi 开发工具强制性地应用 OSGi 可视性规则,以确保包附件得到清晰的声明,这就最大程度地降低了部署时潜在的运行时问题。
  • 类的多个版本可以使用标准 OSGi 机制同时载入到相同的应用程序之中。
  • 应用程序可以使用公共设施类的自己版本,这样您就不再需要配置应用程序 Java EE classloader 政策(例如,PARENT_LAST 模式)。
  • 部署的应用程序不能在绑定包层次上动态地更新,而不用重新部署整个企业档案。

本文的写作目的,在于帮助 Java EE 开发人员将已有的 Java EE 应用程序转化为基于 OSGi 框架,来权衡使用 OSGi 功能。在结尾,我们将会使用 OSGi 转化工具来将应用程序组织为 OSGi 绑定包,以作为 OSGi 框架部署。文中演示了接下来的三个单独的 OSGi 配置,每一个都得到了配置并在 WebSphere Application Server 上得到了测试。

  • 包含 JPA 的单个转化 OSGi 绑定包
  • 分割网络和数据永久性层的多个转化 OSGi 绑定包
  • Java EE 网络项目(.war)和转化的 JPA OSGi 绑定包

本文还讨论了以下的 Rational Application Developer OSGi 开发工具:

  • OSGi 项目转化工具,可以用来将已有的模块转化为 OSGi 绑定包
  • OSGi 声明编辑器
  • OSGi 框架和绑定包创建向导
  • OSGi 在 IBM WebSphere Application Server 上的部署

需求

在您继续后续的操作之前,您需要安装以下的配置并在工作站上启动:

  • IBM Rational Application Developer V8.0 与已经安装的“OSGi 开发工具”
  • IBM WebSphere Application Server V7.0 与已经安装的 OSGi Applications 特性包

导入 JPA JSF Employee List 范例应用程序

开始时导入“JPA JSF Employee List ”范例应用程序:

  1. 选择 Help 菜单 > Help Contents
  2. 在 Help 窗口的内容部分中,展开 Samples > Faces 并选择 JPA JSF Employee List 应用程序。
  3. 点击 Import the Sample 那么就可以启动 Import Projects 窗口了。
  4. 在 Import Projects 窗口中,点击 Finish

EmployeeListWeb 和 EmployeeListWebEAR 项目将会导入到工作区之中。

  1. (可选的)切换至网络视图。

如果您不能从 Help 处访问范例应用程序,那么您可以下面的文件 EmployeeListSample.zip 中找到 .zip 文件。

确认 JPA JSF Employee List 范例应用程序能够按照预期的发挥作用:

  1. 在它导入之后,EmployeeListWeb 应用程序在 persistence.xml 文件处拥有一个错误。该错误将会出现在 Errors 视图之中。双击错误以打开 persistence.xml文件。
  2. 在 persistence.xml 文件中找到 ConnectionURL 属性:
    <property name="openjpa.ConnectionURL" value="jdbc:derby:<workspace_location>\EmployeeListWeb\WebContent\sample" />
  3. 将 <workspace_location> 文本更改为工作区的位置,例如:
    <property name="openjpa.ConnectionURL" value="jdbc:derby:c:\osgiDevWorksTutorial1\EmployeeListWeb\WebContent\sample" />
  4. 运行 WebSphere Application Server V7.0 版本 EmployeeListWeb 应用程序内的 index.jsp。在 EmployeeListWeb 的 Web Content 文件夹之中,右击 index.jsp 文件,并选择 Run > Run on Server
  5. 选择 WebSphere Application Server V7.0 并点击 Finish。
  6. 范例站点应该从该位置处的内部浏览器处启动:
    http://localhost:<port>/EmployeeListWeb/index.faces
  7. 站点应该是功能性的。例如,您应该点击 List all employee records 并看到雇员的列表。
  8. 在继续后续操作之前应该将应用程序从服务器中删除。

单个转化的包含 JPA 的 OSGi 绑定包

首先,我们将会向您演示一个包含 JPA 的已有的网络应用程序是怎样转化为 OSGi Web Application Bundle,并部署为 OSGi 框架。既然范例应用程序正在发挥作用,我们将会使用 OSGi 工具来将范例 JEE 网络项目转化为一个 OSGi 框架,该应用程序包含有支持网络和 JPA 功能的单个 OSGi 绑定包。

将范例应用程序转化为一个 OSGi 绑定包

  1. 右击 EmployeeListWeb 并从下拉菜单中选择 Configure > Convert to OSGi Bundle Project

您将会看到一个如图 1 所示的警告信息。

图 1. 转化为 OSGi 警告的项目
转化不能完成,继续?
  1. 选择 OK 以确定从 JEE 网络项目向 OSGi 绑定包的转变。
  2. 接下来的将会发生:
    1. WebContent/META-INF/manifest.mf 处创建一个绑定包声明。
    2. 在 EmployeeListWeb 项目的属性中,添加了一个 OSGi Bundle 面。
    3. EmployeeListWeb 项目不再是 EmployeeListWebEAR 之中的一个模块。

绑定包声明会列在 EmployeeListWeb 项目之中。您可以双击 Manifest:EmployeeListWeb 以打开 Bundle Manifest Editor。

图 2. 转化的 EmployeeListWeb 项目,现在是一个绑定包
网络绑定包显示了 Manifest 和绑定包图标
  1. 绑定包声明会将 JSF 项目 JARs(包含在 WebContent/WEB-INF/lib中)自动添加至 bundle-classpath,并向导入包添加需要的 Java 类导入

转化之前和之后声明的比较

在转化之前:

清单 1. 网络项目声明
Manifest-Version: 1.0
Ignore-Scanning-Archives: jsf-ibm.jar, icu4j_3_4_1.jar

After conversion:

清单 2. 转化之后的网络绑定包声明
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: EmployeeListWeb
Bundle-SymbolicName: EmployeeListWeb
Bundle-Version: 1.0.0.qualifier
Bundle-ClassPath: WEB-INF/classes,
    WEB-INF/lib/icu4j_3_4_1.jar,
    WEB-INF/lib/jsf-ibm.jar,
    WEB-INF/lib/sitelib.jar,
    WEB-INF/lib/web-jpa.jar
Ignore-Scanning-Archives: jsf-ibm.jar,
    icu4j_3_4_1.jar
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Meta-Persistence: 
Web-ContextPath: /EmployeeListWeb
Import-Package: javax.faces.application,
    javax.faces.validator,
    org.apache.commons.logging;resolution:=optional,
    javax.faces.convert,
    javax.faces.render,
    javax.servlet.jsp;version="2.0",
    javax.persistence;resolution:=optional,
    javax.servlet.http;version="2.5",
    javax.faces.event,
    javax.faces.component.html,
    javax.servlet;version="2.5",
    javax.faces.component,
    javax.servlet.jsp.tagext;version="2.0",
    javax.servlet.jsp.el;version="2.0",
    javax.faces.el,
    javax.faces.model,
    javax.faces.lifecycle,
    javax.faces.webapp,
    javax.faces,
    javax.faces.context,
    javax.el;version="2.0";resolution:=optional

创建 OSGi 框架

为了向 WebSphere Application Server 部署 OSGi 绑定包,首先您需要创建一个 OSGi 框架以为部署包含 OSGi。

  1. 选择 File > New > Other
  2. 在 New Project 对话框之中,展开 OSGi 并选择 OSGi Application Project。点击 Next
  3. 输入一个项目名,对于 EmployeeListApp,确认 WebSphere Application Server V7.0 版本作为运行时目标设置好了,然后点击 Finish

EmployeeListApp 将会在 Enterprise Explorer 视图中列出,展开它并双击 Manifest: EmployeeListApp 以打开 OSGi Application Manifest 编辑器。声明中将会出现一个警告,直到下一步中添加了一个绑定包为止。

图 3. OSGi Application Manifest 编辑器
EmployeeListApp 的 OSGi Application Manifest 编辑器
  1. Contained Bundles 部分中,点击 Add
  2. 选择 EmployeeListWeb 1.0.0 并点击 OK。警告将会得到解决。
  3. 保存并关闭 EmployeeListApp 声明编辑器。

在服务器上创建一个数据源

您需要在 WebSphere Application Server 上手动创建一个数据源。与 EARs 不一样,EARs 包含了运行时创建数据源的信息,OSGi 框架需要的数据源已经存在于服务器上了。

  1. 如果 WebSphere Application Server V7.0 版本尚未启动,那就启动它。
  2. 在 Servers 视图中,右击 WebSphere Application Server V7.0,并从下拉菜单中选择 Administration > Run Administrative Console 以启动操控台。
  3. 在 Administrative Console 中,在左边展开 Resource > JDBC 然后点击 JDBC Providers
  4. 点击已有的 Derby JDBC Provider 资源,以确认默认条件下它已经由应用程序服务器创建了。
  5. 点击 Data sources 链接。
  6. 点击 New 以创建一个新的数据源。
  7. 创建带有以下属性的新数据源:
    1. 在 Data Source 向导的第一步,将 JNDI Name 设置为 jdbc/sample
    2. 在 Data Source 向导的第二步,将 Database Name 设置为工作区范例数据库的位置,例如:c:\osgiDevWorksTutorial1\EmployeeListWeb\WebContent\sample
    3. 接受对所有其他实体所作的默认设置,并完成新的 Data Source 向导。
  8. 测试数据源连接,以确认它已经得到了成功的创建。

创建绑定包以访问服务器

既然数据源在 WebSphere 服务器中已经创建好了,那么您就需要创建 OSGi 绑定包以访问它。为了完成该操作,您可以创建 EmployeeListWeb 绑定包,通过编辑 persistence.xml 来访问服务器上的数据源,该文件位于指向服务器上定义数据源的 EmployeeListWeb 项目。您可以按照下面的步骤来操作:

  1. 在 Enterprise Explorer 视图中,展开 EmployeeListWeb > JPA Content,双击 persistence.xml 以将其在 Persistence XML Editor 中打开。
  2. 如果您看到 persistence.xml 源的话,那么您可以点击 Design 项。
  3. 在编辑器左边的 Overview 部分中,展开 Persistence 并点击 Persistence Unit(EmployeeListWeb)
  4. 设置 Details 部分:
    • JTA Data Source:jdbc/sample
  5. 在 Overview 中,展开 Persistence > Persistence Unit > Properties。
  6. 强调显示属性并点击 Remove 按钮来删除三个属性。
  7. 选择 Properties,点击 Add 按钮,选择 Property 并点击 OK,来添加一个属性。
  8. 设置属性:
    • 名字:openjpa.jdbc.Schema
    • 值:SAMP
  9. 点击 Source 视图。

代码清单 3 显示了永久性源是什么样的。

清单 3. 编辑之后的 Persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
    <persistence version="2.0"
        xmlns="http://java.sun.com/xml/ns/persistence" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
     http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
        <persistence-unit name="EmployeeListJPA">
            <jta-data-source>jdbc/sample</jta-data-source>
            <class>employee.list.Department</class>
            <class>employee.list.Employee</class>
            <properties>
                <property name="openjpa.jdbc.Schema" value="SAMP" />
            </properties>
        </persistence-unit>
    </persistence>
  1. 保存 并关闭 Persistence XML 编辑器。

部署并运行 OSGi 框架

在转化为一个 OSGi 框架和包含绑定包之后,部署和运行 EmployeeListWeb 范例应用程序的所有准备都已经就绪了。因为所有需要的文件都位于单独的网络绑定包之中,所以 JPA 运行时就会当在 Rational Application Developer 中创建 JEE 模块时发挥作用。

  1. EmployeeListApp 发布到 WebSphere Application Server V7.0 版本上。注意包含的绑定包显示在 OSGi 框架之下。
图 4. 向服务器添加和删除对话框
Add to Server 对话框之中的 EmployeeListApp

Note:
EmployeeListWebEAR 会仍然作为一个项目存在于工作区之中,并且仍然包含了一个警告错误说不能找到 EmployeeListWeb.war 文件。您可以忽略或者删除 EAR 文件。

  1. 在 WebSphere Application Server V7.0 版本上的 EmployeeListWeb 应用程序内运行 index.jsp。在 EmployeeListWeb 中的网络内容文件之中,右击 index.jsp 并选择 Run > Run on Server
  2. 选择 WebSphere Application Server V7.0,并点击 Finish。
  3. 范例站点应该在以下位置的内部浏览器中启动:
    http://localhost:<port>/EmployeeListWeb/index.faces

站点应该是功能性的。例如,您应该点击 List all employee records 并看到雇员的列表。

图 5. 范例页面,列出了所有的雇员
all_employees JSF 页面显示了来自数据库的列表
  1. 在继续下一步之前从服务器中删除应用程序,并在工作区中删除所有的项目。选项: 让已有的变量一直存在于当前的工作区中,让下一个变量存在于新的 Rational Application Developer 工作区之中。

单独绑定包之中的 JPA

在这个范例中,永久性层仍然包含在其 OSGi JPA 绑定包之中,并且可以从 OSGi 网络绑定包中访问。最佳实践方式是让 JPA 永久性层位于它自己的项目或者绑定包之中。通过这种方法,JPA 实体会在一个地方进行管理,并且可以作为数据层由许多项目使用,而不是包含 JPA 实体和管理豆的项目使用。在运行时 OSGi JPA 绑定包不会当做 JEE 模块处理,所以对于网络绑定包需要一些特别的步骤,以成功地访问管理 JPA 类。

导入编辑的范例以分割 JPA

EmployeeListSample-Part2Begin.zip 文件(见于 Downloads)作为一个已有的项目导入到 Rational Application Developer 工作区之中:

  1. 选择 File > Import
  2. 选择 General > Existing Projects into Workspace
  3. Import 对话框之中,选择 Select Archive File 单选按钮。
  4. 点击 Browse 并找到 EmployeeListSample-Part2Begin.zip 文件。选择文件并点击 Open。您应该在 Browse 按钮旁边区域看到 .zip 文件的完整路径。
  5. 点击 Finish

在这些项目之中,JPA 实体已经被复制到单独的 JPA 项目和永久性单元之中。这就是 JPA JSF Employee List 范例应用程序,但是 JPA 实体和管理豆位于它们自己的项目之中。另外,EmployeeListJPA 项目之中的 persistence.xml 文件已经被创建了,以在您创建的服务器上使用 jdbc/sample 数据源。假设数据源在服务器上被设置成访问 EmployeeListWeb 项目之中包含的范例数据库,而且使用范例工作区位置,项目已经为部署做好准备,并且可以通过在服务器上运行 index.jsp 来进行测试。

将项目转化为 OSGi 绑定包

首先,将 JPA 项目转化为一个 OSGi JPA 绑定包:

  1. 右击 EmployeeListJPA 项目,并从下拉菜单中选择 Configure > Convert to OSGi Bundle Project

您将会看到一个如图 6 所示的警告。

图 6. 转化为 OSGi 警告的项目
转化为 OSGi 的操作不能完成,继续?
  1. 选择 OK 以确定从 JPA 项目到 OSGi 绑定包的转变。

然后接下来的就会发生了:

  • src/META-INF 中,现在有一个绑定包声明文件,MANIFEST.MF
  • 一个 OSGi Bundle 已经被添加到了该项目之中。这使得 JPA 项目成为一个 JPA 绑定包。
  • MANIFEST.MF 文件之中:
    • 实体和实体管理豆包已经作为导出包添加了。之所以这样,其他的绑定包就可以导入它了,在这种情况下,所以 JPA 实体就可以访问了,数据也得到控制了。
    • 已有类的需要导入操作已经添加到了导入-包之中。

结果得到的声明应该如代码清单 4 所示。

清单 4. 转化之后的 JPA 绑定包声明
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: EmployeeListJPA
Bundle-SymbolicName: EmployeeListJPA
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Meta-Persistence: 
Export-Package: employee.list.controller,
    employee.list
Import-Package: javax.persistence;resolution:=optional,
javax.faces.model;resolution:=optional

转变网络项目

接下来,您可以将网络项目转化为一个 OSGi 网络绑定包:

  1. 右击 EmployeeListWeb ,并从下拉菜单中选择 Configure > Convert to OSGi Bundle Project

您会再一次遇到一条警告信息,说转变不能完成,并询问确认您要继续下去(图 7)。

图 7. 项目转变为 OSGi 的警告
转变为 OSGi 不能完成,继续?
  1. 选择 OK 以确认从 JEE 网络项目到 OSGi 绑定包的转变操作。

接下来的将会发生:

  • 在 EmployeeListWeb 项目的属性之中,可以添加一个 OSGi Bundle。
  • 您可以在 WebContent/META-INF/manifest.mf 处创建一个绑定包声明。
  • EmployeeListWeb 项目不再是 EmployeeListWebEAR 之中的一个模块。

注意:
EmployeeListWebEAR 仍然作为一个项目存在于工作区之中,并包含了一个错误说“一个 Java EE Enterprise Application 必须包含一个或者多个模块”。

  • 绑定包声明会列在 EmployeeListWeb 项目之中。您可以双击 Manifest: EmployeeListWeb 以打开 Bundle Manifest Editor。
  • 绑定包声明会自动添加至 JSF 项目 JAR 文件(包含在 WebContent/WEB-INF/lib)。
  • 绑定包声明会自动将 Java 类导入添加至导入包的列表,包括导入的条目类,该类会得到解决以从 JPA 绑定包导出。

结果绑定包声明如代码清单 5 所示。

清单 5. 转变之后的网络绑定包声明
Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: EmployeeListWeb
    Bundle-SymbolicName: EmployeeListWeb
    Bundle-Version: 1.0.0.qualifier
    Bundle-ClassPath: WEB-INF/classes,
     WEB-INF/lib/icu4j_3_4_1.jar,
     WEB-INF/lib/jsf-ibm.jar,
     WEB-INF/lib/sitelib.jar,
     WEB-INF/lib/web-jpa.jar,
     WEB-INF/lib/EmployeeListJPA.jar
    Ignore-Scanning-Archives: jsf-ibm.jar,
      icu4j_3_4_1.jar
    Bundle-RequiredExecutionEnvironment: JavaSE-1.6
    Web-ContextPath: /EmployeeListWeb
    Import-Package: javax.faces.application,
     javax.faces.validator,
     org.apache.commons.logging;resolution:=optional,
     javax.faces.convert,
     javax.faces.render,
     javax.servlet.jsp;version="2.0",
     javax.servlet.http;version="2.5",
     javax.faces.event,
     employee.list.controller;resolution:=optional,
     javax.faces.component.html,
     javax.servlet;version="2.5",
     javax.faces.component,
     javax.servlet.jsp.tagext;version="2.0",
     javax.servlet.jsp.el;version="2.0",
     javax.faces.el,
     javax.faces.model,
     javax.faces.lifecycle,
     javax.faces.webapp,
     javax.faces,
     employee.list;resolution:=optional,
     javax.faces.context,
javax.el;version="2.0";resolution:=optional

Bundle Manifest 编辑器还提供了声明的可视展现方式。图 8 显示了 EmployeeListWeb 绑定包声明的 Imported Packages 的一个范例。

图 8. 绑定包声明编辑器附属页面
声明编辑器中显示的导入包

最后,您需要删除 EmployeeListWeb 与 EmployeeListJPA 项目之间的项目附件。当项目是网络项目的属性所定义的 EmployeeListWeb 与 EmployeeListJPA 之间的附件时,JPA 实体可以由网络项目所解决的。当项目被转换为绑定包时,实体类会作为 JPA 绑定包中的导出-包和网络中的导入-包添加。项目之间的双重附件,作为一个 OSGi 和插件附件,需要得到我们的处理。您可以按照下面的步骤来进行操作:

  1. 右击 EmployeeListWeb,并选择 Properties。
  2. 在 Properties 对话框窗口之中,您可以切换至 Deployment Assembly 页面。
  3. 选择 EmployeeListJPA.jar 条目并点击 Remove
  4. 在 Properties 对话框窗口之中点击 OK 并接受作出的更改。

现在附件只会作为绑定包之间的插件附属存在。

编辑 JPA Manager Beans

在 EmployeeListJPA 绑定包内,JPA 管理豆,它作为 JPA 条目豆的基本豆,需要在 OSGi 环境中编辑。在 OSGi 环境之中,为了获得一个管理的永久单元,您必须执行一次 OSGi 服务查找操作。这不像 JEE,在 JEE 之中,管理的永久性豆可以通过 @PersistenceUnit 注释由容器注入。如果 OSGi 服务注册查找不会添加至 JPA 条目管理豆,WebSphere 就不能解决永久性单元的问题,在网络页面试着访问 JPA 数据并查找永久性单元时,您会看到如代码清单 6 所示的错误。

清单 6. 如果 @PersistenceUnit 在 JPA 管理豆中使用时会发生的错误
Error 500: javax.servlet.ServletException: javax.faces.el.EvaluationException: 
javax.el.ELException: <openjpa-2.0.0-r422266:935683 fatal user error> 
org.apache.openjpa.persistence.ArgumentException: A JDBC Driver or Data source 
class name must be specified in the ConnectionDriverName property.

另外,范例应用程序会使用管理的交易。用户交易对象必须从 OSGi 服务处获得。如果您试着调用 em.getTransaction(),那么运行时您会遇到如代码清单 7 所示的错误。

清单 7. 如果调用 em.getTransaction() 会发生的错误
SystemErr    R <openjpa-2.0.0-r422266:935683 nonfatal user error>
org.apache.openjpa.persistence.InvalidStateException: 
You cannot access the EntityTransaction when using managed transactions.

您可以按照下面的步骤来编辑 JPA 管理豆:

  1. 打开 Employee 条目管理豆,EmployeeManager.java,您可以在 EmployeeListJPA/src/employee/list/controller 处找到它。
  2. 在 EmployeeManager 类中,找到 getEntityManager() 方法。

在 JPA EntityManagerClass 上执行一次 OSGi 服务注册查找操作,并设置持续性单元,这样您可以在 OSGi 背景下访问它。

  1. 在 getEntityManager() 方法中,使用如代码清单 8 所示的代码来替换内容。
清单 8. 新的 getEntityManager() 方法内容
try 
{ 
  emf = (EntityManagerFactory) new InitialContext().lookup( 
"osgi:service/javax.persistence.EntityManagerFactory/(osgi.unit.name=EmployeeListJPA)"
  );
} catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} return emf.createEntityManager();
  1. 选择“create field emf”快速修复来校正 emf 变量上的错误(添加区域声明:私人 EntityManagerFactory emf;)。
  2. 同样,快速修复 InitialContext() 和 NamingException 上的错误,并向类添加需要的导入。
  3. 在 JPA 管理豆的 创建,获取,更新和删除 方法之中,EntityTransaction 类不能在 OSGi 框架之中解决。另一种成功运行这些方法的方式是通过 OSGi 查找来调用 UserTransaction。
  4. 使用如代码清单 9 所示的代码替换构造器方法,EmployeeManager(),以声明一个带有 OSGi 查找操作的 UserTransaction 变量,以创建,获取,更新和删除 JPA 管理豆的方法。
清单 9. 新的 EmployeeManager() 构造器
privateUserTransaction utx; public EmployeeManager() { 
  try {
    utx = (UserTransaction) new InitialContext().lookup(
      "osgi:service/javax.transaction.UserTransaction");
  } catch (NamingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
 }
}
  1. 在 JPA 管理豆的创建,获取,更新和删除方法之中,您需要更改它们以使用 utx,这里会使用到 em.getTransaction()。例如,updateEmployee(Employee employee) 方法的 try/catch 块将会从代码清单 10 所示转变为代码清单 11 所示。
清单 10. 原始的 updateEmployee() try/catch 块
try {
            em.getTransaction().begin();
            employee = em.merge(employee);
            em.getTransaction().commit();
        } catch (Exception ex) { try { if (em.getTransaction().isActive()) {
                    em.getTransaction().rollback();
                }
            } catch (Exception e) {
                ex.printStackTrace(); throw e;
            } throw ex;
        } finally {
            em.close();
清单 11. 新的 updateEmployee() try/catch 块
try {
    
            utx.begin();
            em.joinTransaction();
            em.merge(employee);
            utx.commit();
        } catch (Exception ex) { try {
                utx.rollback();
            } catch (Exception e) {
                ex.printStackTrace(); throw e;
            } throw ex;
        } finally {
            em.close();
        }
  1. 快速修复错误以向类添加需要的导入。
  2. 对于在 OSGi 框架中您将会使用到的其他创建,获取,更新和删除方法,您可以重复第 11 到 13 步。例如:
    • updateEmployee()
    • deleteEmployee()
    • createEmployee()
  3. 对于 DepartmentManager.java JPA 管理豆重复第 5 步到 14 步,您可以从 EmployeeListJPA/src/employee/list/controller 的相同包中找到。

创建一个 OSGi 框架

为了将 OSGi 绑定包部署到 WebSphere Application Server 上,您需要创建一个 OSGi 框架以包含 OSGi 绑定包为部署做好准备。

  1. 选择 File > New > Other
  2. 在 New Project 对话框窗口中,展开 OSGi 并选择 OSGi Application Project
  3. 点击 Next
  4. 输入一个项目名,例如 EmployeeListApp
  5. 确认 WebSphere Application Server V7.0 版本被设置为目标运行时,并点击 Finish
图 9. 新 OSGi 框架向导
创建 EmployeeListApp OSGi 框架
  1. EmployeeListApp 将会列在 Enterprise Explorer 视图之中。将其展开并双击 Manifest: EmployeeListApp 以打开 OSGi Application Manifest 编辑器。声明中将会出现一个警告信息,直到下一步添加一个绑定包为止。
  2. Contained Bundles 部分中,点击 Add
  3. 选择 EmployeeListWeb 1.0.0EmployeeListJPA 1.0.0,并点击 OK。警告将会得到解决。
图 10. OSGi Application Manifest Editor 概述页面
添加至 OSGi App Manifest 编辑器的绑定包

注意:
绑定包还可以添加至新 OSGi 框架向导之中的 OSGi 框架。

  1. 保存 并关闭 EmployeeListApp 声明编辑器。

在 WebSphere 上创建一个数据源并部署

您需要在 IBM WebSphere Application Server 上创建数据源。查看 Create a data source on the server section 以得到怎样在服务器上创建 Derby 数据源,该服务器指向 EmployeeListWeb 项目之中的范例数据库。如果您正在使用相同的服务器概述,那么对于该配置您可以在前面的部分中重复使用服务器上的数据源。

EBA 导入-导出支持

导入和导出 EBA 功能也值得研究一番。EBA 文件包含了 OSGi 框架及其包含的绑定包。它们还可以从 Rational Application Developer 中导出,并使用 Administrative Console 手动导入到 WebSphere。

现在既然 EmployeeListWeb 范例应用程序已经作为一个带有 OSGi JPA 绑定包和动态网络项目的 OSGi 框架配置好了,那么部署和运行 EmployeeListWeb 范例应用程序的所有准备工作已经就绪了。

  1. 将 EmployeeListApp 发布到 WebSphere Application Server V7.0 版本上。注意包含的绑定包会在 OSGi 框架下面显示出来(见于图 11)。
图 11. Add and Remove to Server 对话框窗口
Add to Server 对话框之中的 EmployeeListApp 和绑定包

注意:
EmployeeListWebEAR 会作为一个项目仍然存在于工作区之中,并包含了一个错误“一个 Java EE Enterprise Application 必须包含一个或者多个模块”。您可以删除或者忽略该 EAR 文件

  1. 在 WebSphere Application Server V7.0 版本之中的 EmployeeListWeb 应用程序内运行 index.jsp。在 EmployeeListWeb 之中的 Web Content 文件夹内,右击 index.jsp 文件夹并选择 Run > Run on Server
  2. 选择 WebSphere Application Server V7.0 并点击 Finish。
  3. 范例站点应该在以下的内部浏览器中启动:
    http://localhost:<port>/EmployeeListWeb/index.faces
  4. 站点应该是功能性的。例如,您应该能够点击 List all employee records 并查看雇员的列表。
图 12. 范例页面列出了所有的雇员,以及网络和 JPA 作为单独的绑定包
all_employees 页面显示了来自数据库的列表
  1. 在继续操作操作之前,您需要从服务器中删除应用程序,并从工作区中删除所有的项目。

将网络项目作为 JEE 模块部署的变量

OSGi 框架可以包含作为 JEE 模块的动态网络项目。这就给 Rational Application Developer 用户一些选项,在开发 OSGi 框架时就可以使用网络项目。接下来的步骤将会显示怎样使用带有 OSGi 框架的“JSF JPA Employee List Sample”,该 OSGi 框架包含有 OSGi 框架部署中的动态网络项目。

组织应用程序模块

您可以按照下面的步骤,来组织 EmployeeListApp,以使用一个动态的网络项目,而不是 OSGi 框架网络前端的 Web Application Bundle:

设置目标平台

在导入到工作区的内部项目 .zip 文件处,您可能需要清晰地设置目标平台,以解决汇编性的错误。在导入的档案之中,与导入的 OSGi 框架(.eba)相比较,目标平台会设置为工作区默认目标平台。为了解决这个问题,您可以选择 Window > Preferences > Plug-in development > Target Platform,并将选项由 Running Platform 变为目标服务器平台,来将目标平台设置为适当的目标服务器。

  1. 从第二个配置变量中导入结果(本文的 Single converted OSGi bundle containing JPA 部分),或者使用 EmployeeListSample-Part2Complete.zip 文件(来自 下载 部分),除了 EmployeeListWeb 项目之外。不要 导入带有其他资源的 EmployeeListWeb 绑定包。您可以在后续的步骤中导入一个网络项目。

工作区现在包含有两个项目:

  • EmployeeListJPA
  • EmployeeListApp
  1. EmployeeListApp 上将会有一条警告信息:“1.0.0 版本的 Bundle EmployeeListWeb 不能解决问题”。您可以按照下面的步骤来处理这条警告信息:
    1. 展开 EmployeeListApp
    2. 您可以双击 Manifest: EmployeeListApp 来打开 OSGi Application Manifest 编辑器。
    3. Contained Bundles 部分中,您可以选择 EmployeeListWeb 1.0.0 并点击 Remove
    4. 保存 并关闭声明编辑器。
  2. 导入 EmployeeList-Part2Begin.zip 文件(查看 下载 部分):
    1. File > Import
    2. 选择 General > Existing Projects into Workspace
    3. Import 对话框窗口之中,选择 Select Archive File 单选按钮。
    4. 点击 Browse 按钮,并找到 EmployeeList-Part2Begin.zip 文件。
    5. 只选择 EmployeeListWeb 项目以进行导入。
    6. 点击 Finish
    7. 工作区中将会有一个新的网络项目:EmployeeListWeb。

在当前的配置之中,EmployeeListWeb 项目和 EmployeeListJPA 绑定包之间将会有一个附件。您需要将其删除以避免运行时错误。另外,来自 EmployeeListJPA 的 src 文件夹需要添加至 EmployeeListWeb 项目的构建路径,以避免开发时汇编错误。

  1. EmployeeListWeb 项目属性中,切换至 Deployment Assembly 页面。
  2. 从该页面中将 EmployeeListJPA.jar 条目删除。
  3. EmployeeListWeb 项目属性中,切换至 Java Build Path 页面并点击 Libraries 项。
  4. 点击 Add Class Folder 按钮。
  5. 选择在 EmployeeListJPA 项目之下添加 src 文件夹。这将会把以下的文件夹条目添加至构建路径:
    EmployeeListJPA/src (类文件夹)。
  6. 点击 OK 以保存对项目属性所作的更改。

Java EE 网络模块,EmployeeListWeb,可以作为动态的网络项目添加至 OSGi 框架。网络模块对 OSGi 的支持允许用户缓慢地将他们的 Java EE 应用程序转化为 OSGi,还提供了 Java EE 和 OSGi 容器都支持的网络模块的支持。当您将一个动态的网络模块发布到 OSGi 框架上时,运行时服务器实际上将其转化为了一个 OSGi 网络绑定包。如果用户想要得到优化的性能和绑定包版本的支持,那么建议将 JEE 网络项目转化为 OSGi 绑定包。但是,您可以按照下面的步骤来将一个动态网络项目,作为一个 JEE 模块添加至 JEE 模块。

  1. 在 Enterprise Explorer 视图中展开 EmployeeListApp
  2. 双击 Manifest: EmployeeListApp 来打开 OSGi Application Manifest 编辑器。
  3. 在 OSGi Application Manifest 编辑器之中,展开 Dynamic web projects 部分,并点击 Add
  4. 选择一个动态网络项目对话框窗口之中,选择 EmployeeListWeb 并点击 OK。该操作可以向声明文件添加以下的内容:
    Application-WebModules: EmployeeListWeb

OSGi Application Manifest 编辑器如图 13 所示。

图 13. OSGi Application Manifest 编辑器显示了网络项目
添加至 OSGi 声明编辑器的网络项目

在 WebSphere 上创建数据源并部署

包含动态网络项目的 OSGi 框架只能在服务器被配置为“Run server with resources on server”时,才可以成功地部署到 WebSphere Application Server 上。这不是默认的设置。您可以按照下面的步骤来设置该配置:

  1. 打开 Servers 视图。
  2. 双击 WebSphere Application Server V7.0 以打开 Server Overview 编辑器。
  3. 展开 WebSphere Application Server 部分的 Publishing 设置。
  4. 选择发布的设置,Run server with resources on Server(图 14)。
图 14. 在服务器上使用资源的发布设置
服务器编辑器资源位置设置
  1. 保存 并关闭 Server Overview 编辑器。

您需要在 IBM WebSphere 应用程序服务器上创建数据源。查看 第一部分 以得到怎样在指向 EmployeeListWeb 项目中范例数据库的服务器上创建 Derby 数据源的具体步骤。

部署并运行 OSGi Application,EmployeeListApp

现在既然 EmployeeListWeb 范例应用程序已经作为一个带有 OSGi JPA 绑定包和动态网络项目的 OSGi 框架配置好了,那么部署和运行 EmployeeListWeb 范例应用程序的所有准备工作已经就绪了。

  1. EmployeeListApp 发布到 WebSphere Application Server V7.0 版本之上。注意包含的绑定包和 JEE 网络项目会显示在 OSGi 框架的下面。
图 15. Add and Remove Server 对话框窗口
添加至服务器的 OSGi 框架与网络模块

运行 WebSphere Application Server V7.0 版本上 EmployeeListWeb 应用程序内的 index.jsp

  1. 在 EmployeeListWeb 中的 Web Content 文件夹内,右击 index.jsp 文件,然后选择 Run > Run on Server
  2. 选择 WebSphere Application Server V7.0,并点击 Finish。
  3. 范例站点应该在以下位置的内部浏览器中启动:
    http://localhost:<port>/EmployeeListWeb/index.faces
  4. 该站点应该是功能性的。例如,您应该能够点击 List all employee records 并看到一个关于雇员的列表。
图 16. 列出所有雇员的范例页面,以及 OSGi 框架的网络模块
显示数据库列表的 all_employees 页面

本文演示了通过将已有的 Java EE 应用程序转化为基于 OSGi 的应用程序,Java EE 开发人员是怎样权衡使用 IBM Rational Application Developer OSGi 开发工具所提供的功能。您可以从本文中看到三种方法,去转化并将一个简单的动态网络和 JPA 应用程序组织为一个 OSGi 框架:

  • 包含一个 JPA 的单独转化 OSGi 网络绑定包
  • 多个转化的 OSGi 绑定包,将网络和数据永久性层分开
  • Java EE 网络模块(动态网络项目)与转化的 JPA OSGi 绑定包

新 OSGi 开发工具的一些功能,可以用于创建一些 OSGi 框架变量,包括以下的这些特性:

  • OSGi 项目转化向导,以将动态网络项目转化为一个 OSGi 网络应用程序绑定包(WAB),并将 JPA 项目转化为一个 OSGi 绑定包
  • OSGi 绑定包声明编辑器,以描述绑定包元数据,包括绑定包的附件
  • OSGi 框架项目,它创建了 Enterprise Bundle Archive(EBA),替换 Java EE EAR 文件。
  • 支持在 OSGi 背景下进行 JPA 访问,使用 JNDI 来执行 OSGi 服务注册查找操作
  • 服务集成,支持以一种与 Java EE 应用程序非常类似的方式来完美地发布和部署一个 OSGi 框架
  • 支持导入/导出 Enterprise Bundle Archive(EBA)以共享 OSDi 应用程序,或者导出到 WebSphere Application Server 以进行手动的部署

还有一些其他与 OSGi 相关的功能,本文不再赘述,但是我们建议,既然您对 OSGi 已经有了一个大概的了解,那您就可以进一步地去学习这些功能:

  • 插件开发环境(PDE)项目向 OSGi 的转化
  • OSGi 组合绑定包
  • 蓝图容器及一个附属的注入模型
  • OSGi 生命周期管理,支持应用程序的安装,更新,启动,关闭及卸载操作,而不用您重启服务器

查看参考资料 部分,以得到描述以上内容及与 OSGi 相关的其他概念。


致谢

作者非常感谢 Tim DeBoer,Zina Mostafia 和 Jim Zhang 对本文所作的技术性和编辑性工作。


下载

描述名字大小
Employee List 示例EmployeeListSample.zip788KB
Employee List 示例 - 第 2 部分开始部分EmployeeListSample-Part2Begin.zip5445KB
Employee List 示例 - 第 2 部分结束部分EmployeeListSample-Part2Complete.zip5439KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=632203
ArticleTitle=使用 Rational Application Developer 工具将 Java 应用程序转化为基于 OSGi 框架
publish-date=03142011