扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
引言
|
最初基于 Apache Geronimo 的 IBM WebSphere Application Server Community Edition(即开源 Java™ 2, Enterprise Edition (J2EE™) 应用程序服务器)在 2005 年底被引入 WebSphere Application Server 产品系列。其内存占用小的特性、易用性及灵活的可用性使其非常有助于中小型企业利用 J2EE 编程模型和运行时环境。
JOnAS(Java开放应用程序服务器)是一种由 ObjectWeb 公司生产的开源应用程序服务器产品,该公司在欧共体占有主要地位。该产品平台与 J2EE 兼容,并且已通过 Sun™ 公司的 J2EE 1.4 Certification Test Suite 的测试。JOnAS 支持用于运行 Web 应用程序的 Web 容器层的 Tomcat 和 Jetty。
鉴于 WebSphere Application Server 和开源社区的服务与基础结构的支持,WebSphere Application Server Community Edition(以下称为 Community Edition)是 JOnAS 及其他开源应用程序服务器的绝佳备选方案。虽然将应用程序从 JOnAS 迁移到 Community Edition 相对比较简单,但像所有迁移一样,仍会出现复杂的情况。本文讨论将应用程序从 JOnAS 迁移到 Community Edition 时可能会遇到的一些问题。
有关有助于从 JBoss、WebLogic 及其他平台迁移到 Community Edition 的文章,请参见参考资料。
|
关于 J2EE 迁移
如果应用程序符合以下要求,则其迁移过程就非常简单:
如果符合以上三种情况,则只需要使用目标平台的部署方法对应用程序进行部署。对于其他应用程序,其额外工作的多少视与这些条件的偏差程度而定。
JOnAS 和 Community Edition 环境的主要 Web 容器实现均基于 Apache Tomcat。这极大地简化了 WAR 迁移过程。Community Edition Web 容器基于 Tomcat 5.5.x 核心引擎,并支持 Servlet 2.4 和 JSP 1.2 规范。如果在具有不同核心规范级别的引擎之间进行迁移,则会稍微复杂一些,这种情况在所有环境都会出现,并且不是平台特定的条件。(有关其他迁移文章,请参见参考资料。)
|
转换部署描述符文件
针对特定应用程序处理部署描述符中的差异是任何迁移工作的主要任务。J2EE 应用程序的标准部署描述符为:
这些文件支持 J2EE 规范内详细描述的配置、参数及选项。除了这些文件之外,每个 J2EE 应用程序服务器具有供应商特定的部署描述符,用于支持供应商特定的对规范所要求的各种功能的实现,或支持供应商对规范的扩展。
表 1 列出了 Community Edition 和 JOnAS 环境的部署描述符,并说明这些描述符与 J2EE 部署描述符的关系。
表 1. 部署描述符关系
文件类型 | J2EE | Community Edition | JOnAS |
---|---|---|---|
EAR | application.xml | geronimo-application.xml | -- |
WAR | web.xml | geronimo-web.xml | jonas-web.xml |
EJB | ejb-jar.xml | openejb-jar.xml | jonas-ejb-jar.xml |
只要所支持的 J2EE 规范级别相同,J2EE 部署描述符无需更改就可以在应用程序服务器环境之间进行迁移。本文假设是这样的情况。
需要将平台(供应商)特定的部署描述符从一种格式转换为另一种格式,在本例中,从 JOnAS 格式转换为 Community Edition 格式。接下来的几部分将详细描述在此迁移方案中一些更常用的功能的转换:
引用映射
将各种类型的引用映射到目标对象的全局 JNDI 名称是一项常见的迁移任务。引用是应用程序的特定指针,该指针指向通常存在于更大的上下文(如服务器或集群)中并且供多方使用的对象。当对象具有全局名称时,使用该资源的每个实体可以使用应用程序的特定名称,该名称即为引用。可以在部署时指定该指针的名称,并不需要重新构建应用程序。两个最常见的引用类型为 EJB 引用和指向 JDBC 数据源的资源引用。
EJB 引用可在 WAR 模块中定义,以供 JSP 和 Servlet 使用。EJB 引用还可以在 EJB 模块中定义,以进行EJB 到 EJB 的交互,例如,会话 Bean 调用实体 Bean。J2EE 规范已处理此类型引用的映射,Community Edition 和 JOnAS 都遵循该定义。因此,并不需要实施进一步的操作以处理 EJB 引用,web.xml 和 ejb-jar.xml 文件将包含所有的必要信息,并且无需进行更改。本地和远程 EJB 引用都是这样的情况。
清单 1 显示了 web.xml 的相关片段。
清单 1
<ejb-ref id="'EjbRef_1152738645974"'> <description></description> <ejb-ref-name>ejb/SessionReference</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>ejbs.SessionHome</home> <remote>ejbs.Session</remote> <ejb-link>HelloJonasEJB.jar#Session</ejb-link> </ejb-ref> <ejb-local-ref id="'EJBLocalRef_1152738602724"'> <description></description> <ejb-ref-name>ejb/SessionLocalReference</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>ejbs.SessionLocalHome</local-home> <local>ejbs.SessionLocal</local> <ejb-link>HelloJonasEJB.jar#Session</ejb-link> </ejb-local-ref> |
资源引用
资源引用的实现略有不同,需要进行小部分额外工作。J2EE 规范需要应用程序服务器来实现对资源引用的支持,但并不规定用于将引用映射到目标对象的机制。因此,映射信息通常在供应商的特定部署描述符(如 jonas-web.xml 和 geronimo-web.xml)中定义。
以下是 jonas-web.xml 文件的片段:
<jonas-resource> <res-ref-name>jdbc/dsreference</res-ref-name> <jndi-name>jdbc/MyDatasourceDB2</jndi-name> </jonas-resource> |
geronimo-web.xml 的等效片段为:
<naming:resource-ref> <naming:ref-name>jdbc/dsreference</naming:ref-name> <naming:resource-link>jdbc/MyDatasourceDB2</naming:resource-link> </naming:resource-ref> |
只有在文件中定义了关联的命名空间才可以使用以上命名前缀,如下所示:xmlns:naming=http://geronimo.apache.org/xml/ns/naming-1.0
。并不要求使用前缀,在此仅用于举例说明。完全可接受以下代码:
<resource-ref> <ref-name>jdbc/dsreference</ref-name> <resource-link>jdbc/MyDatasourceDB2</resource-link> </resource-ref> |
对于 Community Edition,可以在 geronimo-application.xml 文件的 Web 模块定义中存储该信息,并且会覆盖模块的特定 geronimo-web.xml 文件中的任何内容。对于 EJB 模块上定义的资源引用,XML 将非常相似。jonas-ejb-jar.xml 中有关资源引用的代码可能为:
<jonas-resource> <res-ref-name>jdbc/dsreference</res-ref-name> <jndi-name>jdbc/MyDatasourceDB2</jndi-name> </jonas-resource> |
openejb-jar.xml 内的等效 XML 为:
<resource-ref> <ref-name>jdbc/dsreference</ref-name> <resource-link>jdbc/MyDatasourceDB2</resource-link> </resource-ref> |
对于 Community Edition,可以在 geronimo-application.xml 文件的 EJB 模块定义中存储该信息,并且会覆盖模块的特定 openejb-jar.xml 文件中的任何内容。
EJB JNDI 名称
Enterprise Java Bean 根据 J2EE 规范的要求部署时在 JNDI 中注册一个名称。如果已存储该信息,并且 ejb-jar.xml 格式并不含有针对 Bean 的 JNDI 名称的特定字段,则该规范不会作此定义。因此,该值会在供应商的特定部署描述符中定义。在我们的示例中,对于 JOnAS,该部署描述符为 jonas-ejb-jar.xml;对于 Community Edition,则为 openejb-jar.xml。
以下是 jonas-ejb-jar.xml 文件的片段:
<jonas-session> <ejb-name>Session</ejb-name> <jndi-name>ejb/ejbs/SessionHome</jndi-name> </jonas-session> |
以下是 openejb-jar.xml 中的等效片段:
<session> <ejb-name>Session</ejb-name> <jndi-name>ejb/ejbs/SessionHome</jndi-name> </session> |
对于 Community Edition,可以在 geronimo-application.xml 文件的 EJB 模块定义中存储该信息,并且会覆盖模块的特定 openejb-jar.xml 文件中的任何内容。
|
示例应用程序
本文中包括的示例应用程序是所有上述构造的工作示例,该示例应用程序还包括两个环境的部署描述符。应用程序由单个 WAR 模块和单个 EJB 模块组成。每个模块的内容为:
应用程序:HelloJonasWeb
应用程序:HelloJonasEJB
部署描述符
为了能够进行直观的比较,Hello.Jonas.ear 应用程序内包括的部署描述符如下所示:
清单 2. application.xml
<?xml version="1.0" encoding="UTF-8"?> <application id="HelloJonas" version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"> <display-name>HelloJonas</display-name> <module id="EjbModule_1152731275709"> <ejb>HelloJonasEJB.jar</ejb> </module> <module id="WebModule_1152729750334"> <web> <web-uri>HelloJonasWeb.war</web-uri> <context-root>HelloJonasWeb</context-root> </web> </module> </application> |
<application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:moduleId> <dep:groupId>HelloJonas</dep:groupId> <dep:artifactId>HelloJonasApp</dep:artifactId> <dep:version>1.0</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies/> <dep:hidden-classes/> <dep:non-overridable-classes/> </dep:environment> <!--if module def's present module dd's e.g. geronimo-web.xml ignored--> <module> <web>HelloJonasWeb.war</web> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1"> <sys:environment> <sys:moduleId> <sys:groupId>HelloJonas</sys:groupId> <sys:artifactId>HelloJonasWeb</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>war</sys:type> </sys:moduleId> <sys:dependencies> <sys:dependency> <sys:groupId>HelloJonas</sys:groupId> <sys:artifactId>MyDataSourceDB2</sys:artifactId> </sys:dependency> </sys:dependencies> <sys:hidden-classes/> <sys:non-overridable-classes/> </sys:environment> <context-root>/HelloJonasWeb</context-root> <naming:resource-ref> <naming:ref-name>jdbc/dsreference</naming:ref-name> <naming:resource-link>jdbc/MyDataSourceDB2</naming:resource-link> </naming:resource-ref> </web-app> </module> <module> <ejb>HelloJonasEJB.jar</ejb> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1"> <sys:environment> <sys:moduleId> <sys:groupId>HelloJonas</sys:groupId> <sys:artifactId>HelloJonasEJB</sys:artifactId> <sys:version>1.0</sys:version> <sys:type>car</sys:type> </sys:moduleId> <sys:dependencies> <sys:dependency> <sys:groupId>HelloJonas</sys:groupId> <sys:artifactId>MyDataSourceDB2</sys:artifactId> </sys:dependency> </sys:dependencies> <sys:hidden-classes/> <sys:non-overridable-classes/> </sys:environment> <enterprise-beans> <session> <ejb-name>Session</ejb-name> <jndi-name>ejb/ejbs/SessionHome</jndi-name> <resource-ref> <ref-name>jdbc/dsreference</ref-name> <resource-link>jdbc/MyDataSourceDB2</resource-link> </resource-ref> </session> </enterprise-beans> </openejb-jar> </module> <!-- --> </application> |
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>HelloJonasWeb</display-name> <servlet> <description></description> <display-name>HelloServlet</display-name> <servlet-name>HelloServlet</servlet-name> <servlet-class>HelloServlet</servlet-class> </servlet> <servlet> <description></description> <display-name>InfoServlet</display-name> <servlet-name>InfoServlet</servlet-name> <servlet-class>InfoServlet</servlet-class> </servlet> <servlet> <description></description> <display-name>TestLocal</display-name> <servlet-name>TestLocal</servlet-name> <servlet-class>TestLocal</servlet-class> </servlet> <servlet> <description></description> <display-name>TestRemote</display-name> <servlet-name>TestRemote</servlet-name> <servlet-class>TestRemote</servlet-class> </servlet> <servlet> <description></description> <display-name>Lookup</display-name> <servlet-name>Lookup</servlet-name> <servlet-class>Lookup</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/HelloServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>InfoServlet</servlet-name> <url-pattern>/InfoServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TestLocal</servlet-name> <url-pattern>/TestLocal</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TestRemote</servlet-name> <url-pattern>/TestRemote</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Lookup</servlet-name> <url-pattern>/Lookup</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <ejb-ref id="EjbRef_1152738645974"> <description> </description> <ejb-ref-name>ejb/SessionReference</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>ejbs.SessionHome</home> <remote>ejbs.Session</remote> <ejb-link>HelloJonasEJB.jar#Session</ejb-link> </ejb-ref> <ejb-local-ref id="EJBLocalRef_1152738602724"> <description> </description> <ejb-ref-name>ejb/SessionLocalReference</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>ejbs.SessionLocalHome</local-home> <local>ejbs.SessionLocal</local> <ejb-link>HelloJonasEJB.jar#Session</ejb-link> </ejb-local-ref> <resource-ref> <description> </description> <res-ref-name>jdbc/dsreference</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app> |
<?xml version="1.0" encoding="ISO-8859-1"?> <jonas-web-app xmlns="http://www.objectweb.org/jonas/ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.objectweb.org/jonas/ns http://www.objectweb.org/jonas/ns/jonas-web-app_4_0.xsd" > <jonas-resource> <res-ref-name>jdbc/dsreference</res-ref-name> <jndi-name>jdbc_1</jndi-name> </jonas-resource> </jonas-web-app> |
<?xml version="1.0" encoding="UTF-8"?> <web-app configId="HelloJonasWeb" xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.0" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.0"> <context-root>/HelloJonasWeb</context-root> <context-priority-classloader>false</context-priority-classloader> <naming:resource-ref> <naming:ref-name>jdbc/dsreference</naming:ref-name> <naming:resource-link>jdbc/MyDatasourceDB2</naming:resource-link> </naming:resource-ref> </web-app> |
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar id="ejb-jar_ID" version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"> <display-name> HelloJonasEJB</display-name> <enterprise-beans> <!-- @generated ejbs.SessionBean#ejb/aejbdd.ejbs.SessionBean --> <session id="ejbs.SessionBean"> <ejb-name>Session</ejb-name> <home>ejbs.SessionHome</home> <remote>ejbs.Session</remote> <local-home>ejbs.SessionLocalHome</local-home> <local>ejbs.SessionLocal</local> <ejb-class>ejbs.SessionBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <resource-ref> <description> </description> <res-ref-name>jdbc/dsreference</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </session> </enterprise-beans> <assembly-descriptor> </assembly-descriptor> </ejb-jar> |
<?xml version="1.0" encoding="ISO-8859-1"?> <jonas-ejb-jar xmlns="http://www.objectweb.org/jonas/ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.objectweb.org/jonas/ns http://www.objectweb.org/jonas/ns/jonas-ejb-jar_4_0.xsd" > <jonas-session> <ejb-name>Session</ejb-name> <jndi-name>ejb/ejbs/SessionHome</jndi-name> <jonas-resource> <res-ref-name>jdbc/dsreference</res-ref-name> <jndi-name>jdbc_1</jndi-name> </jonas-resource> </jonas-session> </jonas-ejb-jar> |
?xml version="1.0" encoding="UTF-8"?> <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.0" xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.0" xmlns:sec="http://geronimo.apache.org/xml/ns/security-1.1" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.0" xmlns:pkgen="http://www.openejb.org/xml/ns/pkgen-2.0" configId="HelloJonasEJB" parentId="HelloJonas"> <enterprise-beans> <session> <ejb-name>Session</ejb-name> <jndi-name>ejb/ejbs/SessionHome</jndi-name> <local-jndi-name></local-jndi-name> <resource-ref> <ref-name>jdbc/dsreference</ref-name> <resource-link>jdbc/MyDatasourceDB2</resource-link> </resource-ref> </session> </enterprise-beans> </openejb-jar> |
结束语
本文简要介绍了 WebSphere Application Server Community Edition 和 JOnAS 之间的实现差异,有助于迁移到 Community Edition 并将其用作跳板,从而使用 WebSphere Application Server 系列产品。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者