从 JBoss 7 迁移到 WildFly 9 时使用 CMT 的 EJB

Posted

技术标签:

【中文标题】从 JBoss 7 迁移到 WildFly 9 时使用 CMT 的 EJB【英文标题】:EJB with CMT when migrate from JBoss 7 to WildFly 9 【发布时间】:2018-11-02 15:42:48 【问题描述】:

我正在将我的应用程序从 JBoss 7 迁移到 WildFly (v9.0.1),但由于 bean 事务管理错误而未部署。

    Caused by: javax.naming.NamingException: WFLYNAM0062: Failed to lookup env/com.component.eventmgt.EventServiceImpl/transaction [Root exception is java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:157)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 90 more
Caused by: java.lang.RuntimeException: WFLYNAM0059: Resource lookup for injection failed: java:jboss/UserTransaction
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:319)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:143)
    ... 95 more
Caused by: javax.naming.NameNotFoundException: UserTransaction [Root exception is java.lang.IllegalStateException: WFLYEJB0137: Only session and message-driven beans with bean-managed transaction demarcation are allowed to access UserTransaction]
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:153)
    at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:83)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:207)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:193)
    at org.jboss.as.naming.NamingContext.lookup(NamingContext.java:189)
    at org.jboss.as.naming.deployment.ContextNames$BindInfo$1$1.getReference(ContextNames.java:316)
    ... 96 more

这里是 EventServiceImpl 类。

    @Stateless
    @Remote(EventService.class)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public class EventServiceImpl implements EventService 

        /**
         * Logger
         */
        private static Logger log = LoggerFactory.getLogger(EventService.class);

        private EventTableDAO eventDao;

        @PersistenceContext(unitName = "SOMF-GT")
        private EntityManager entityManager;

        @Resource
        private UserTransaction transaction;

       public List<Map> loadEvents() throws EventsException 

        Configuration configurationEntry = new Configuration();
        try 
            Map configuration = configurationService.getConfiguration();
            if (configuration != null) 

        eventDao = new EventTableDAO(Event.class, entityManager, transaction);
        List<Map> eventsMapList = new ArrayList();


我知道如果我使用 @TransactionManagement(TransactionManagementType.BEAN) 将事务管理更改为 BMT,但随后会出现以下错误

WFLYJPA0060:执行此操作需要事务(使用事务或扩展持久性上下文)

我想知道为什么我们必须首先改变它?

任何信息,请!

【问题讨论】:

我认为 JBoss 7 不存在此限制(EJB 中的 UserTransaction with javax.ejb.TransactionManagementType.CONTAINER) 【参考方案1】:

这些更改在 Wildfly 8 中推出,并且(如下所述)基于 EJB 3.1 中全局 JNDI 命名空间的标准化。

来自 Wildfly 8 Developer Guide:

EJB 3.1 引入了一个标准化的全局 JNDI 命名空间和一系列映射到 Java EE 应用程序不同范围的相关命名空间。用于可移植 JNDI 查找的三个 JNDI 名称空间是 java:global、java:module 和 java:app。如果您在应用程序中使用 JNDI 查找,则需要更改它们以遵循新的标准化 JNDI 命名空间约定。

要符合新的可移植 JNDI 命名空间规则,您需要查看 JNDI 命名空间规则并修改应用程序代码以遵循这些规则。

指南进一步说明:

WildFly 8 加强了 JNDI 命名空间名称,以便为应用服务器中绑定的每个名称提供可预测且一致的规则,并防止未来出现兼容性问题。这意味着如果应用程序中的当前命名空间不遵循新规则,您可能会遇到问题。

这是表格中的一个 sn-p,显示特定于 UserTransaction 的 Examples of JNDI mappings in previous releases and how they might look now:

Previous Namespace          New Namespaces
------------------          --------------
java:comp/UserTransaction   java:comp/UserTransaction (This will not be accessible for non EE threads, e.g. Threads your application directly creates)
java:comp/UserTransaction   java:jboss/UserTransaction (Globally accessible, use this if java:comp/UserTransaction is not available)

重新编辑:WFLYEJB0137:

这是理论技巧,可能毫无价值 - 告诉我,我会删除它。 Java EE 6 Tutorial - Container-Managed Transactions 说:

使用容器管理的事务划分的企业 bean 也不得使用 javax.transaction.UserTransaction 接口。

进一步:

(交易)必需属性

如果客户端在事务中运行并调用企业 bean 的方法,则该方法在客户端的事务中执行。如果客户端未与事务关联,则容器会在运行该方法之前启动一个新事务。

Required 属性是使用容器管理的事务划分运行的所有企业 bean 方法的隐式事务属性。您通常不设置 Required 属性,除非您需要覆盖另一个事务属性。由于事务属性是声明性的,您可以在以后轻松更改它们。

异常消息几乎说明了一切:

WFLYEJB0137:只有具有 bean 管理的事务分界的会话和消息驱动的 bean 才允许访问 UserTransaction

您的 EJB 正在使用容器管理事务 (CMT) 分界,它与 UserTransaction 所在的 bean 管理事务 (BMT) 分界不互操作。

关于切换到 BMT 和

WFLYJPA0060:执行此操作需要事务(使用事务或扩展持久性上下文)

我发现Transaction is required to perform this operation (either use a transaction or extended persistence context) 似乎表明事务将由您管理,正如您在 cmets @Marco 中所指出的那样。看来您已经进行了适当的修改。

【讨论】:

使用“java:jboss/UserTransaction”命名空间出现以下错误:WFLYNAM0059 注入资源查找失败:java:jboss/UserTransaction (Wildfly 9) @Marco 哪个版本的 9? 9.0.0.Final、9.0.1.Final 还是 9.0.2.Final? 9.0.2.Final,目前我已将 TransactionManagementType 从 CONTAINER 转换为 BEAN 并手动管理 UserTransaction。 @Marco 您的 WFLYNAM0059 是否有基本异常 WFLYEJB0137,如问题所示? 是的,WFLYEJB0137

以上是关于从 JBoss 7 迁移到 WildFly 9 时使用 CMT 的 EJB的主要内容,如果未能解决你的问题,请参考以下文章

EJB远程客户端从JBoss AS 7.1迁移到Wildfly 8.1

Wildfly/JBOSS 持久性错误 MSC000001:无法启动服务 jboss.persistenceunit

JBoss as7 到 WildFly 的 Hibernate 迁移

WildFly 迁移、ejb 问题(8.1.0.Final 到 9.0.1.Final)

将 glassfish JEE8 weapp 迁移到 Wildfly10 (Jboss) - eclipseLink 不创建数据库表

EJB 未使用 @EJB 在 Wildfly 9.0.0 中初始化