我正在尝试在应用程序启动时更新数据库中的某些内容。为此,我创建了一个将这样做的A类。

@Singleton
@Startup
@DependsOn({ "B", "C" })
public class A{
    @Inject B b;
    @Inject C c;
    ...
}


B是一个类,它从数据库中读取一些配置值。 B:

@Singleton
@Startup
public class B {
     @PersistenceContext
     EntityManager em;
     ...
}


C是一个树结构,它使用来自类D和E的数据来构建格式正确的树。C:

@Singleton
@Startup
@DependsOn({ "D", "E" })
public class C{
     @Inject
     D d;
     @Inject
     E e;
     ...
 }


D和E在不依赖其他单例的意义上是叶单例;它们提供数据(从文件读取到db):D:

@Singleton
@Startup
public class D { ... }


E:

@Singleton
@Startup
public class E { ... }


基于DependsOn annotation documentation,我假设CDI将为单例创建依赖关系图,并将按指定顺序对其进行初始化(B,D和E将在C之前初始化,最后在A初始化之前进行初始化)。但是,当我尝试部署应用程序时,出现一个异常告诉我:
生命周期处理中的异常
java.lang.RuntimeException:EJB ContentUpdater的DependsOn依赖性'C'无效。

完整堆栈跟踪:

java.lang.RuntimeException: Invalid DependsOn dependency 'C' for EJB A
at org.glassfish.ejb.deployment.util.EjbBundleValidator.checkDependsOn(EjbBundleValidator.java:602)
at org.glassfish.ejb.deployment.util.EjbBundleValidator.accept(EjbBundleValidator.java:300)
at org.glassfish.ejb.deployment.descriptor.EjbDescriptor.visit(EjbDescriptor.java:2823)
at org.glassfish.ejb.deployment.descriptor.EjbDescriptor.visit(EjbDescriptor.java:2811)
at org.glassfish.ejb.deployment.util.EjbBundleValidator.accept(EjbBundleValidator.java:115)
at com.sun.enterprise.deployment.BundleDescriptor.visit(BundleDescriptor.java:625)
at org.glassfish.ejb.deployment.descriptor.EjbBundleDescriptorImpl.visit(EjbBundleDescriptorImpl.java:757)
at com.sun.enterprise.deployment.util.ApplicationValidator.accept(ApplicationValidator.java:121)
at com.sun.enterprise.deployment.BundleDescriptor.visit(BundleDescriptor.java:625)
at com.sun.enterprise.deployment.archivist.ApplicationFactory.openArchive(ApplicationFactory.java:190)
at org.glassfish.javaee.core.deployment.DolProvider.processDOL(DolProvider.java:203)
at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:227)
at org.glassfish.javaee.core.deployment.DolProvider.load(DolProvider.java:96)
at com.sun.enterprise.v3.server.ApplicationLifecycle.loadDeployer(ApplicationLifecycle.java:881)
at com.sun.enterprise.v3.server.ApplicationLifecycle.setupContainerInfos(ApplicationLifecycle.java:821)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:377)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:219)
at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:491)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:539)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:535)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:534)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:565)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$3.run(CommandRunnerImpl.java:557)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:360)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:556)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1464)
at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1300(CommandRunnerImpl.java:109)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1846)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1722)
at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:534)
at com.sun.enterprise.v3.admin.AdminAdapter.onMissingResource(AdminAdapter.java:224)
at org.glassfish.grizzly.http.server.StaticHttpHandlerBase.service(StaticHttpHandlerBase.java:189)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:745)


有人知道在上述结构下为什么会发生这种异常吗?

当我在类A的@DependsOn批注中遗漏了类C时,会遇到另一个异常,因此很遗憾,这不是解决方案。
该应用程序已部署在GlassFish 4.1上

最佳答案

我建议您重新考虑设计并仅创建一个“ StartUpController”
会按需要触发所有其他ejb的init方法。


@Singleton
public class A {
    public void init() {}
}

@Singleton
public class B {
    public void init() {}
}

@Singleton
public class C {
    public void init() {}
}



@Startup
@Singleton
public class StartUpController {

    @Inject
    private A a;

    @Inject
    private B b;

    @Inject
    private C c;

    @PostConstruct
    protected void setup() {
        a.init();
        b.init();
        c.init();
    }

}


@DependsOn并不是真正的“依赖项控件”,它只是初始化顺序的控件,仅与@PostConstruct方法一起使用才有意义。 (在您的示例中,我看不到任何初始化方法),因此@DependsOn是不必要的。您可以将ejb连接到链中,而无需此注释外观thisthis示例。

我无法确切回答为什么您的代码无法正常工作,也许这只是键入错误。例如,您在上面发布的代码中没有C.class,而有QuestionHandler.class,并且我在代码中也没有看到任何@PostConstruct方法。另一个原因可能是glashfish配置,我建议您尝试在wildfly服务器上进行编码。

10-06 16:20