jakarta-ee - maven-embedded-glassfish-plugin 上的 CDI 注入(inject)失败 -- org.jboss.weld.exceptions.DeploymentException : WELD-001408 Unsatisfied dependencies for type

标签 jakarta-ee cdi

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

Usuario Controller

@Named
@SessionScoped
public class UsuarioController implements Serializable {

    /** snipet **/

    @Inject
    private EnderecoController enderecoController;

    /** snipet **/
}

Endereco Controller

@Named
@ViewScoped
public class EnderecoController {

    /** snipet **/

    @Inject
    private UsuarioController esuarioController;

    /** snipet **/
}

当 Web 应用程序打包并部署到正常的 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 异常的解释有些困难。

最佳答案

好吧,经过大量搜索和阅读,我们终于解决了这个问题。事实证明,该 Web 应用程序最初是为 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。尝试将实例注入(inject) 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 无法提供依赖项注入(inject)。没有详细说明什么类型的错误导致注入(inject)的 bean 无法首先创建。甚至没有一句“抱歉,无法找到要实例化的 bean”。

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

我希望他们改进错误处理,引发异常消息,以便我们更好地理解为什么某些特定依赖项无法得到满足。

关于jakarta-ee - maven-embedded-glassfish-plugin 上的 CDI 注入(inject)失败 -- org.jboss.weld.exceptions.DeploymentException : WELD-001408 Unsatisfied dependencies for type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18107858/

相关文章:

java - Quartz 和 JPA EJB

java - 重置 Weld 的廉价方法?

java - 如何解决 SSLHandshakeException ?为什么我得到它?

Java EE 依赖注入(inject)什么时候使用?

java - 将 Weld 与 Dropwizard 结合使用

Java函数中的final变量

events - CDI 事件和泛型

java - 拦截器绑定(bind)不起作用

jakarta-ee - 在 Quartz 作业中使用 CDI

java - 如何多次读取 request.getInputStream()