CDI Inject在maven-embedded-glassfish-plugin上失败 - org.jboss.weld.exceptions.DeploymentException:WELD-001408类型不满意的依赖项

Jul*_*oHM 10 java-ee cdi

我们有一个webapp,目前正在使用Java EE 7,JSF 2.2和Glassfish 4.0开发.有两个特定的托管bean,它们具有循环依赖性.

UsuarioController

@Named
@SessionScoped
public class UsuarioController implements Serializable {

    /** snipet **/

    @Inject
    private EnderecoController enderecoController;

    /** snipet **/
}
Run Code Online (Sandbox Code Playgroud)

EnderecoController

@Named
@ViewScoped
public class EnderecoController {

    /** snipet **/

    @Inject
    private UsuarioController esuarioController;

    /** snipet **/
}
Run Code Online (Sandbox Code Playgroud)

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

但是,在开发过程中,我们使用maven-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
Run Code Online (Sandbox Code Playgroud)

是否有人能够帮助我们的开发环境解决这个问题?有些人更喜欢使用嵌入式glassfish插件来完成本地开发的服务器.

看起来像是与maven-embedded-glassfish相关的依赖/类路径问题,但我们不知道从哪里开始.在Google周围找到有关CDI WELD-NNNNNN例外的解释有点困难.

Jul*_*oHM 24

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

为了使它能够像今天一样使用代码,我们必须了解CDI实现的关键区别.直到Java EE 6,CDI将扫描所有包,并且容器将考虑所有bean.这种行为显然随Java EE 7而改变,其方式是只考虑使用特定范围注释的类来成为托管bean.换句话说,所述@Named注释需要由范围的注解(之一陪同@RequestScoped,@SessionScoped,@DependentScoped,@FlowScoped,等等).由于@ViewScoped不再是官方范围列表的一部分,因此EnderecoController当CDI启动时,该类不会成为托管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>
Run Code Online (Sandbox Code Playgroud)

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

我仍然觉得很奇怪,原始代码在完整的glassfish安装中工作,但不在maven-embedded-glassfish-plugin内部.

我个人对Java EE/CDI的咆哮

另外,我想明确评论WELD-001408不满意依赖栈跟踪给出的荒谬广泛的描述.该消息仅表示CDI无法提供依赖注入.没有详细说明哪种类型的错误导致注入的bean首先不会被创建.甚至没有"抱歉,无法找到一个bean来实例化".

由于各种原因可能发生不满意的依赖性.尝试实例化依赖项时发生的任何异常都会远离日志文件.你可能要花一个小时直到你意识到你的bean的构造函数正在抛出一个NullPointerException.这种包含废话的例外是在Google上搜索此错误消息导致人们因不同原因而出现相同错误的原因.

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

  • 我理解这条评论对您的情况没有帮助,但是您是否考虑过创建问题/开始讨论项目的邮件列表?大多数项目都没有关注. (4认同)