【问题标题】:CDI Inject fails on maven-embedded-glassfish-plugin -- org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for typeCDI Inject 在 maven-embedded-glassfish-plugin 上失败 -- org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type
【发布时间】:2013-08-09 02:14:44
【问题描述】:

我们有一个 web 应用程序,目前正在使用 Java EE 7、JSF 2.2 和 Glassfish 4.0 开发。有两个具有循环依赖关系的特定托管 bean。

UsuarioController

@Named
@SessionScoped
public class UsuarioController implements Serializable {

    /** snipet **/

    @Inject
    private EnderecoController enderecoController;

    /** snipet **/
}

EnderecoController

@Named
@ViewScoped
public class EnderecoController {

    /** snipet **/

    @Inject
    private UsuarioController esuarioController;

    /** snipet **/
}

将 webapp 打包并部署到普通 glassfish 4.0 安装时,它可以正常工作。

但是,在开发过程中,我们使用 ma​​ven-embedded-glassfish 在 IDE 内进行本地测试。并且应用部署失败并出现以下异常。

SEVERE: Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [EnderecoController] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private net.jhm.exemplo.view.UsuarioController.enderecoController]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [EnderecoController] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject private net.jhm.exemplo.view.UsuarioController.enderecoController]
    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:325)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:177)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:208)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:519)
    at org.jboss.weld.bootstrap.Validator.validateBeans(Validator.java:505)
    at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:480)
    at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:536)
    at org.glassfish.weld.WeldDeployer.event(WeldDeployer.java:216)
    at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:131)
    at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:328)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:493)
    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:527)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2$1.run(CommandRunnerImpl.java:523)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:356)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:522)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:546)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1423)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1500(CommandRunnerImpl.java:108)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1762)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1674)
    at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:133)
    at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:109)
    at org.glassfish.maven.PluginUtil.doDeploy(PluginUtil.java:108)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.glassfish.maven.AbstractDeployMojo.doDeploy(AbstractDeployMojo.java:259)
    at org.glassfish.maven.DeployMojo.execute(DeployMojo.java:69)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)

Aug 07, 2013 12:22:31 PM PluginUtil doDeploy
INFO: Deployed null

谁能帮助我们的开发环境解决这个问题?有几个人更喜欢嵌入式 glassfish 插件,而不是用于本地开发的完整服务器。

似乎是一个与 maven-embedded-glassfish 相关的依赖项/类路径问题,但我们不知道从哪里开始。在 Google 周围找到 CDI WELD-NNNNNN 异常的解释有点困难。

【问题讨论】:

    标签: jakarta-ee cdi


    【解决方案1】:

    好吧,经过大量搜索和阅读,我们终于解决了它。事实证明,该 webapp 最初是为 Java EE 6 开发的,并且在此过程中决定使用 Java EE 7。嗯...在 Java EE 7 中有些不同。它以不同的方式处理托管 bean 范围。一方面,Java EE 7 文档中甚至都没有提到 @ViewScoped 注释(有一个新的 @FlowScoped,但我们仍在阅读它)。我们将日志级别提高到了 FINEST,并通过无穷无尽的细节来了解发生了什么。

    为了让它与现在的代码一起工作,我们必须了解 CDI 实现的一个关键区别。在 Java EE 6 之前,CDI 会扫描所有包,并且容器会考虑所有 bean。这种行为显然在 Java EE 7 中发生了变化,在这种方式下,只有使用特定范围注释的类才被考虑成为托管 bean。换句话说,@Named 注释需要伴随一个范围注释(@RequestScoped@SessionScoped@DependentScoped@FlowScoped 等)。由于@ViewScoped 不再是官方范围列表的一部分,所以当CDI 启动时EnderecoController 类不会成为托管bean。尝试将实例注入UsuarioController 会导致通用 WELD 依赖异常,因为从未创建过该 bean 的实例。

    为了使事情在向后可移植性中发挥作用,我们必须更改 WEB-IBNF/beans.xml 文件以将属性 bean-discovery-mode="annotated" 更改为 bean-discovery-mode="all"

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
           bean-discovery-mode="all">
    </beans>
    

    使用all 发现模式会导致 CDI 在扫描托管 bean 时包含所有要考虑的类,包括那些没有 CDI 范围注释的类。我们现在正在着手更好地了解新的范围管理,以使代码适应 Java EE 7 标准。

    我仍然觉得奇怪的是,原始代码可以在完整的 glassfish 安装中运行,但不能在 maven-embedded-glassfish-plugin 中运行。

    我个人对 Java EE/CDI 的吐槽

    另外,我想明确评论 WELD-001408 Unsatisfied dependency 堆栈跟踪给出的荒谬广泛的描述。该消息仅意味着 CDI 无法提供依赖注入。没有关于什么类型的错误导致注入的 bean 首先没有被创建的详细信息。甚至没有“抱歉,无法找到要实例化的 bean”。

    由于各种原因,可能会出现不满足的依赖关系。尝试实例化依赖项时发生的任何异常都会隐藏在日志文件之外。您可能会花费一个小时,直到您意识到您的 bean 的构造函数正在抛出 NullPointerException。这种包装废话的异常是为什么在 Google 上搜索此错误消息会导致大量人由于不同原因而出现相同错误的原因。

    我希望他们改进错误处理,引发异常消息,以便我们更好地理解为什么某些特定的依赖关系不能满足。

    【讨论】:

    • 我知道此评论对您的情况没有帮助,但您是否考虑过在项目的邮件列表上创建问题/开始讨论,而不是在 SO 上大吵大闹?大多数项目都没有关注 SO。
    猜你喜欢
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多