首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaEE 6中的异步方法

JavaEE 6中的异步方法
EN

Stack Overflow用户
提问于 2015-12-20 10:55:18
回答 1查看 1K关注 0票数 1

我尝试在 6中使用JavaEE异步方法,创建了以下类。但是,输出日志的结果是同步。这不对。

无状态类

代码语言:javascript
复制
   @javax.ejb.Stateless
    public class MailManager implements Serializable{
    @Asynchronous
        public void send(List<String> toList, Mail mail, final SystemSetting systemSetting) throws MailException, UnsupportedEncodingException{

            boolean isError = false;
            for(InternetAddress addr :addressList){
                    MimeMessage msg = getMimeMessage(addr, mail, session);
                    Transport.send(msg);
                    log.info("Sent email to ["+addr+"].");
            }
            if(isError){
                throw new MailException("Mail sending error occurred. Check error log.");
            }
            log.debug("Async finish.");
        }
    }

ManagedBean

代码语言:javascript
复制
@Named
@SessionScoped
public class MailController extends AbstractController{
    @Inject @new(MailCreater.class)
    private MailFactory mailCreater;

    @Inject
    private MailManager mailManager;

    public void send(){
        Mail mail = null;
            mail = mailCreater.createFromTemplate(this, false,
                    mimeInfo, "template/testTemplate.txt","template/FOOTER1.body", map);
            mailManager.send(list, mail, systemSetting);
        log.debug("send() finish.");
    }
}

日志

代码语言:javascript
复制
INFO[Log4jLogger] - Sent email to [test1@test.co.jp].
INFO [Log4jLogger] - Sent email to [test2@test.co.jp].
.
.
.
DEBUG [Log4jLogger] - Async finish.
DEBUG [Log4jLogger] - send() finish.

更新

当我将@Inject更改为@EJB时出错代码

代码语言:javascript
复制
warning : javax.ejb.EJBException: javax.ejb.EJBException:
javax.ejb.CreateException: Could not create stateless EJB
        at
com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:454)
        at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2547)
        at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1899)
        at com.sun.ejb.containers.EjbAsyncTask.call(EjbAsyncTask.java:99)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:745)
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not
create stateless EJB
        at
com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:726)
        at
com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:247)
        at
com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:449)
        ... 7 more
Caused by: javax.ejb.CreateException: Could not create stateless EJB
        at
com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:534)
        at
com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:95)
        at
com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:724)
        ... 9 more
Caused by: java.lang.NullPointerException
        at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
        at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
        at
org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:1076)
        at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:148)
        at
org.glassfish.weld.services.JCDIServiceImpl._createJCDIInjectionContext(JCDIServiceImpl.java:169)
        at
org.glassfish.weld.services.JCDIServiceImpl.createJCDIInjectionContext(JCDIServiceImpl.java:146)
        at
com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1639)
        at
com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:475)
        ... 11 more
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-20 16:08:03

您的代码MailController.send()示例缺少了当前如何获取对MailManager的引用。我假设mailManager是参考,但样本并没有显示引用是如何产生的,所以我在这里有点盲目地告诉你们到底出了什么问题。

但是,一般来说,您需要做的是将MailManager EJB注入到MailController中,类似于@EJB MailManager mailManager;

而且,它看起来像是依赖于您的日志来告诉您事情是否真的是异步的。由于时间的关系,这可能会有问题。另外,您所包含的日志片段不包括“发送电子邮件到”消息,如果一切顺利,它看起来应该是MailManager.send()发出的消息。

--更新--

@KensukeSato提出了一个很好的问题:“在他的情况下,我应该使用@Inject@EJB作为‘工作’吗?”

这基本上可以归结为这样一个事实: JavaEE6 CDI和EJB提供了不同的功能,而EJB是CDI,但CDI不是EJB。因此,如果您只想要EJB服务,可以使用@EJB将会话bean注入CDI。但是,如果除了@EJB服务之外,您还希望bean能够利用CDI服务,那么您应该使用@Inject

CDI为您提供了EJB本身不能提供的东西?

  • 基于注释的编程模型
  • 型安全注入拦截器装饰器
  • 上下文管理、范围、会话
  • 活动和观察员
  • 生产者和处置者
  • 通过自定义作用域的可扩展性;以编程方式定义的bean;等等。

因此,如果除了EJB功能之外,您还需要任何这些功能,那么您可以使用@Inject,否则您可以简单地使用@EJB

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34380228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档