3.2.11. EJB 2.x 的修改
3.2.11.1. 更新使用 EJB 2.x 的应用程序 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
JBoss EAP 6 构建于开放式标准,它和 Java EE 6 规格兼容。虽然应用程序服务器支持 EJB 2.x,但它不会再支持超过这个规格的功能。请记住,Java EE 7 规格已经将 EJB 2.x 标记为可选的,所以我们强烈推荐您根据 EJB 3.x 规格重写您的应用程序。
如果您仍想移植 EJB 2.x 代码,多数情况下您需要修改代码以在 JBoss EAP 6 里运行。本节描述了其中一些修改。
在 JBoss EAP 6 上运行 EJB 2.x 所需的配置修改
- 用 Full 配置集启动服务器
- EJB 2.x Container Managed Persistence (CMP) bean 要求 Java EE 6 Full 配置集。这个配置集包含运行 CMP EJB 所需的配置元素。这个配置集包含了
org.jboss.as.cmp
扩展模块:它也包含Copy to Clipboard Copied! Toggle word wrap Toggle overflow cmp
子系统:.Copy to Clipboard Copied! Toggle word wrap Toggle overflow 要用 Full 配置集启动 JBoss EAP 6 独立服务器,在用命令行启动服务器时请使用-c standalone-full.xml
or-c standalone-full-ha.xml
参数。 - 容器配置不再被支持了
- 在以前的 JBoss EAP 版本里,我们可以为 CMP 实体和其他 bean 配置不同的容器并通过在
jboss.xml
部署描述符文件里设置引用来使用它。例如,对于 SLSB 对 Session Bean 的引用通常有不同的配置。在 JBoss EAP 6.x 里,我们可以将 EJB 2 Entity Bean 和标准容器一起使用。JBoss EAP 6 里的默认容器配置包含几个对 EJB2 CMP Bean 的修改:- 默认情况下悲观锁是活动的。这可能导致死锁。
- JBoss EAP 6 里不再有 JBoss EAP 5.x 里的 CMP 层的死锁检测代码。
在 JBoss EAP 5.x 里,我们也可以在定义缓存、池、commit-options
和拦截器栈。而在 JBoss EAP 6 里这是不可能的,它只有一个类似于带有commit-option
C
的Instance Per Transaction
策略的实现。如果您移植使用了cmp2.x jdbc2 pm
entity bean 容器配置的应用程序(使用了兼容 CMP2.x 的基于 JDBC 持久化管理者 ),这会对性能有影响。这个容器为性能作了优化。我们推荐您在移植应用程序之前将这些实体移植到 EJB3。 - 服务器端连接器的配置
- JBoss EAP 6 支持使用
@Interceptors
和@AroundInvoke
注解的标准 Java EEInterceptor
。然而,这并不会允许安全性或事务之外的操作。在以前的 JBoss EAP 版本里,我们可以修改拦截器栈为每个 EJB 调用定制拦截器。这通常用来实现自定义的安全性或安全检查、事务检查或创建前的重试机制。JBoss EAP 6.1 引入了容器拦截器来提供类似的功能。关于容器拦截器的更多信息,请参考《JBoss EAP 开发指南》里的『容器拦截器』章节。在事务的提交阶段之前、期间、之后提供更多控制且遵循 Java EE 规格的方法是使用事务同步注册表(Transaction Synchronization Registry)来添加 listener。资源可以用下列方法之一来获取:回调 Routine 必需实现- 使用
InitialContext
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry"); tsr.registerInterposedSynchronization(new MyTxCallback());
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry"); tsr.registerInterposedSynchronization(new MyTxCallback());
Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 使用注入
@Resource(mappedName = "java:comp/TransactionSynchronizationRegistry") TransactionSynchronizationRegistry tsr; ... tsr.registerInterposedSynchronization(new MyTxCallback());
@Resource(mappedName = "java:comp/TransactionSynchronizationRegistry") TransactionSynchronizationRegistry tsr; ... tsr.registerInterposedSynchronization(new MyTxCallback());
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
javax.transaction.Synchronization
接口。请在事务提交或回滚前用beforeCompletion{}
方法来执行任何检查。如果这个方法抛出RuntimeException
,事务会被回滚且用EJBTransactionRolledbackException
通知客户。如果是 XA-Transaction,所有的资源将按照 XA 合约回滚。我们也可以根据事务状态用afterCompletion(int txStatus)
方法启用商业逻辑。如果这个方法抛出RuntimeException
,事务将保持之前的状态,提交或回滚,且客户不会得到通知。只有事务管理者会在服务器日志文件里显示一个警告信息。 - 客户端拦截器的服务器端配置
- 在以前的 JBoss EAP 版本里,我们可以在服务器配置文件里配置客户拦截器并只提供带有客户 API 的类。在 JBoss EAP 6 里这已不可能了,因为服务器端不会再创建客户代理并再查找后传输到客户端。这个代理现在是在客户端生成。这次优化避免了查找和类上传时对服务器的调用。
- Entity Bean 池配置
- 我们不推荐在 JBoss EAP 6 里进行 Entity bean 的池配置。因为它受限于
<strict-max-pool>
元素的配置,如果池过小而无法加载结果集里的所有实体,死锁和其他问题就可能发生。Entity Bean 在初始化时没有大型的生命周期方法,所以创建实例和使用容器并不会比池化的 Entity Bean 实例慢。 - 替换 jboss.xml 部署描述符文件
jboss-ejb3.xml
部署描述符文件替换jboss.xml
以覆盖和添加 Java EE 定义的ejb-jar.xml
里提供的功能。这个新文件和jboss.xml
兼容,而目前的部署里已经忽略了jboss.xml
。例如,在以前的 JBoss EAP 版本里,如果您在ejb-jar.xml
文件里定义了<resource-ref>
,jboss.xml
里的 JNDI 名称需要有对应的资源定义。XDoclet 自动生成这两个部署描述符文件。在 JBoss EAP 6,jboss-ejb3.xml
文件里现在已定义了 JNDI 映射信息。我们假定 Java 源代码里的数据源是如下这样定义的。DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1"); DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");
DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1"); DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ejb-jar.xml
定义了下列资源引用。Copy to Clipboard Copied! Toggle word wrap Toggle overflow jboss-ejb3.jxml
文件用下列 XML 语法映射 JNDI 名称和引用Copy to Clipboard Copied! Toggle word wrap Toggle overflow JBoss EAP 6 没有实现 JBoss EAP 5.xjboss.xml
文件里可用的一些配置选项。下表描述了jboss.xml
文件里常用的属性以及在 JBoss EAP 6 是否有替代的方法。method-attribute
元素用来配置单独的 Entity 和 Session Bean 方法。read-only
和idempotent
配置选项没有移植到 JBoss EAP 6 里。transaction-timeout
选项现在在jboss-ejb3.xml
文件里进行配置。
missing-method-permission-exclude-mode
属性修改了方法的行为,而不用实现 secured bean 上的显性安全元数据。在 JBoss EAP 6 里,@PermitAll
注解也会依据和@RolesAllowed
注解类似的方式处理。
- 数据源类型映射配置
- 在以前的 JBoss EAP 版本里,我们可以在
*-ds.xml
数据源部署配置文件里配置数据源的类型映射。在 JBoss EAP 6 里,这必须在jbosscmp-jdbc.xml
部署描述符文件里进行。Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在以前的 JBoss EAP 版本里,自定义的映射是在standardjbosscmp-jdbc.xml
文件里完成的。这个文件已取消,现在映射是通过jbosscmp-jdbc.xml
部署描述符文件进行的。
其他 Container-Managed Persistence (CMP) 和 Container-Managed Relaationship(CMR) 的修改
- Container Managed Relationship (CMR) Iterator 和 Collection 的修改
- 在以前的 JBoss EAP 版本里,一些容器如
cmp2.x jdbc2 pm
可以迭代 CMR 容器并删除或添加关系。JBoss EAP 6 不支持这种容器配置,所以无法再这样做了。关于如何在程序代码实现相同功能的信息,请参考客户门户的『Support Knowledgebase Solutions』部分的 EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6。 - 用于 Finder 的 Container Managed Relationship (CMR) 重复条目
- 在以前的 JBoss EAP 版本里,我们可以选择使用了不同持久化策略的 CMP 容器。JBoss EAP 5.x 里的
cmp2.x jdbc2 pm
容器使用优化的SQL-92
来为 Finder 生成优化的 LEFT OUTER JOIN 语法。因为 JBoss EAP 6.x 只支持标准的 CMP 和 CMR 容器,其实现没有包含这些优化。Finder 应该在SELECT
语句里包含关键字DISTINCT
来避免结果集出现笛卡尔集合。更多的信息请参考客户门户的『Support Knowledgebase Solutions』部分的 EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6。 - 对 CMP Entity Beans 的 Cascade Delete 默认值的修改
- Cascade Delete 的默认值已改成
false
。这可能导致 JBoss EAP 6 里出现删除失败。如果实体关系被标记为cascade-delete
,您必须在jbosscmp-jdbc.xml
文件里显性地设置batch-cascade-delete
为true
。更多的信息请参考客户门户的『Support Knowledgebase Solutions』部分的 cascade delete fail for EJB2 CMP Entities after migration to EAP6。 - 用于自定义字段的 CMP 自定义映射器
- 如果您的 JBoss EAP 5.x 应用程序里使用了自定义的映射器类,如
JDBCParameterSetter
、JDBCResultSetReader
和Mapper
,在部署到 JBoss EAP 6 里时,您可能会看到java.lang.ClassNotFoundException
。这是因为这些接口的软件包名从org.jboss.ejb.plugins.cmp.jdbc.Mapper
改成了org.jboss.as.cmp.jdbc.Mapper
。更多的信息请参考客户门户的『Support Knowledgebase Solutions』部分的 How to use Field mapping for custom classes in an EJB2 CMP application in EAP6。 - 使用 entity-commands 生成主键
- 如果您的 JBoss EAP 5 应用程序使用了
entity-commands
来生成主键,如Sequence
或Auto-increment
,当移植应用程序到 JBoss EAP 6 时,您可以看到JDBCOracleSequenceCreateCommand
抛出ClassNotFoundException
。这是因为类软件包从org.jboss.ejb.plugins.cmp.jdbc
改成了org.jboss.as.cmp.jdbc.keygen
。如果您在 JBoss EAP 6 应用程序里使用了这个类,您必须添加对EAP_HOME/modules/system/layers/base/org/jboss/as/cmp
模块的依赖关系。
应用程序的修改
- 修改代码以使用新的 JNDI 命名空间规则。
- 和 EJB 3.0 一样,对 EJB 2.x 您必须使用完整的 JNDI 前缀。关于新的 JNDI 命名空间规则和代码示例,请参考 第 3.1.8.1 节 “更新应用程序 JNDI 命名空间的名称”。关于如何更新以前版本的 JNDI 命名空间的例子,您可以参考 第 3.1.8.5 节 “以前版本的 JNDI 命名空间示例和它们在 JBoss EAP 6 里是如何指定的”。
- 修改
jboss-web.xml
文件描述符 - 对每个
<ejb-ref>
的<jndi-name>
进行修改以使用新的 JNDI 全限定查找格式。 - 使用 XDoclet 来映射内部 Local 接口的 JNDI 名称
- 对于 EJB2,使用
Locator
模式来查找 Bean 是非常常见的。如果您在程序里使用了这个模式,不需要修改代码,您可以使用 XDoclet 来生成新 JNDI 名称的映射。典型的 XDoclet 注解类似于:上述例子里的 JNDI 名称@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"
@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow ejb21/UserAttributeEntity
在 JBoss EAP 6 里不再有效。您可以用服务器配置和 XDoclet 补丁里的naming
子系统将这个名称映射到有效的 JNDI 名称。如上面的『用于自定义字段的 CMP 自定义映射器』里说提及的,您可以创建自定义的映射器,或者您可以按照下面过程描述的那样修改代码。过程 3.24. 修改 XDoclet Generated Code 并使用 Naming 子系统
- 解压
ejb-module.jar
里的 XDocletlookup.xdt
末班并修改lookupHome
里的lookup()
:Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 运行 Ant,对于
ejbdoclet
任务设置 template 属性以使用改动的lookup.xdt
。 - 修改服务器配置文件里的
naming
子系统来映射旧的 JNDI 名称到新的有效 JNDI 名称。Copy to Clipboard Copied! Toggle word wrap Toggle overflow
废弃的文件概述
JBoss EAP 6 不再支持下列文件。
- jboss.xml
- Jboss EAP 6 不再支持
jboss.xml
部署描述符文件且没有在部署归档里包含它。 - standardjbosscmp-jdbc.xml
- Jboss EAP 6 不再支持
standardjbosscmp-jdbc.xml
配置文件。这个配置信息现在包含在org.jboss.as.cmp
模块里且不再是可以定制的了。 - standardjboss.xml
- JBoss EAP 6 不再支持
standardjboss.xml
配置文件。运行独立服务器时配置信息现在包含在standalone.xml
文件里,而运行在受管域时包含在domain.xml
文件里。