【问题标题】:EJB asynchronous call not returning control to callerEJB 异步调用未将控制权返回给调用者
【发布时间】:2017-01-31 19:51:36
【问题描述】:

我正在从另一个 EJB 调用异步 EJB 方法。 此方法负载很重(数据库操作),因此它应该将控制权返回给调用者并在单独的线程中执行业务。

根据API,应该是这样的:

远程接口:

@Remote
public interface MyEJBRemote {

    @Asynchronous
    void myMethod() throws RuntimeException;
}

EJB 类:

@LocalBean
@Stateless
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEJB implements MyEJBRemote {

    @Override
    public void myMethod() throws RuntimeException {
        //for testing
        while (true){
            Thread.sleep(5000);
            logger.info("Running asynchronous method");
        }
        //Method code here
    }
}

来电代码:

@LocalBean
@Stateless
@TransactionAttribute(TransactionAttributeType.NEVER)
public class MyEJBCaller {

    @EJB
    private MyEJB myEJB;

    public void request() throws RuntimeException {
        logger.info("Begin");
        myEJB.myMethod();
        logger.info("End");
    }
}

出于测试目的,我在异步方法中创建了一个无限循环。 理论上应该在日志中出现“Begin”-“End”-“Running asynchronous method” 但它永远不会到达“终点”。

我错过了什么?为什么对方法的调用没有将控件返回给调用者?

我正在使用 JBoss EAP 6.4 服务器。会不会是服务器端的配置问题?

【问题讨论】:

    标签: java asynchronous jboss


    【解决方案1】:

    你应该使用 ejb 接口注入。

    @LocalBean
    @Stateless
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public class MyEJBCaller {
    
        @EJB
        private MyEJBRemote myEJB;
    
        public void request() throws RuntimeException {
            logger.info("Begin");
            myEJB.myMethod();
            logger.info("End");
        }
    }
    

    【讨论】:

    • 感谢您的回复!试过了,但我仍然得到相同的结果。即使 EJB 具有远程接口,调用也是从本地应用程序进行的。也许这就是问题所在?
    【解决方案2】:

    没有发现问题,但如果其他人遇到同样的问题,我有一个解决方案:从远程接口中删除注释并将它们放入 EJB 本身。

    界面:

    @Remote
    public interface MyEJBRemote {
    
        void myMethod() throws RuntimeException;
    }
    

    EJB:

    @LocalBean
    @Stateless
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public class MyEJB implements MyEJBRemote {
    
        @Override
        @Asynchronous
        public void myMethod() throws RuntimeException {
            //for testing
            while (true){
                Thread.sleep(5000);
                logger.info("Running asynchronous method");
            }
            //Method code here
        }
    }
    

    调用者:

    @LocalBean
    @Stateless
    @TransactionAttribute(TransactionAttributeType.NEVER)
    public class MyEJBCaller {
    
        @EJB
        private MyEJB myEJB;
    
        public void request() throws RuntimeException {
            logger.info("Begin");
            myEJB.myMethod();
            logger.info("End");
        }
    }
    

    在 API 中搜索 Asynchronous 似乎目标可以是 METHOD 或 TYPE,因此理论上可以在接口中声明注释。但也许如果调用是从另一个本地 EJB 进行的,JVM 只会从类中解析它,而不是接口(因为注释是在运行时解析的)

    也试过创建一个本地接口(而不是远程接口)并得到相同的结果,所以看起来本地调用确实需要在 EJB 方法本身中定义注解

    编辑:问题是 EJB 没有从接口继承注释。这似乎是为了避免多重继承问题

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-22
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多