在OmniFaces @Eager豆注入@EJB导致"重度:无有效EE环境org.omnifaces.cdi.eager.EagerBeansRepository的注射液"

cgh*_*lai 5 ejb glassfish eager-loading cdi omnifaces

使用@ApplicationScoped @Named @Eager,my @EJB-injected @Statelessbean没有正确实例化并进行评估null.

我有一个@ApplicationScoped @ManagedBean(eager=true)习惯于安排一些工作的人.一些@Statelessbean使用@EJB注释注入,并且工作正常.

在转向CDI注释时,我添加了OmniFaces@Eager注释作为@ManagedBean(eager=true)标准CDI中缺少的注释:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.omnifaces.cdi.Eager;

@Named
@ApplicationScoped
@Eager
public class MyScheduler implements Serializable {

    @EJB
    private MyService myService;
    @Inject
    private MyNamedBean myNamedBean;

    @PostConstruct
    public void init() {
        setupSchedulers();
    }

    @PreDestroy
    public void destroy() {
        destroySchedulers();
    }
    //...
}
Run Code Online (Sandbox Code Playgroud)

使用此设置,@PostConstruct在应用程序启动时正确调用该方法(尽管它似乎甚至在初始化上下文之前运行),但随后myService进行求值null.

在日志中,将显示以下警告:

Severe:   No valid EE environment for injection of org.omnifaces.cdi.eager.EagerBeansRepository
Severe:   No valid EE environment for injection of my.package.MyScheduler
Info:   Initializing Mojarra 2.2.8 ( 20140814-1418 https://svn.java.net/svn/mojarra~svn/tags/2.2.8@13507) for context '/tagific'
Run Code Online (Sandbox Code Playgroud)

因为我需要从其他bean访问这个bean,所以我无法使用@Singleton@Schedule注释.

我怎样才能在应用程序启动时实例化@Stateless@Named应用程序作用域bean中正确地注入bean ?

Bal*_*usC 4

这看起来像是 GlassFish 中的初始化排序错误。运行@Eager @ApplicationScopedServletContextListener. 显然此时 GlassFish 还没有准备好注入 EJB。该结构适用于例如WildFly。

然而,以 CDI 统一整个 Java EE 中各种不同依赖注入方法的名义,您也可以只@Inject使用@EJB. CDI 代理能够进一步委派给正确的@Stateless实例。

@Inject
private MyService myService;
Run Code Online (Sandbox Code Playgroud)

您还可以@Inject在 EJB 本身内部使用,但截至目前(Java EE 7),它还不支持例如@Asynchronous方法的自引用。为此你还得坚持@EJB


也就是说,您是否知道 Oracle 停止了对 GlassFish 的商业支持,并且您最好不要将其用于生产环境?另请参阅此博客