Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CDI Inject fails on maven-embedded-glassfish-plugin -- org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type

Tags:

jakarta-ee

cdi

We have a webapp, currently being developed using Java EE 7, JSF 2.2 and Glassfish 4.0. There are two particular managed beans which with a circular dependency.

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 **/
}

When the webapp is packaged and deployed to a normal glassfish 4.0 installation, it works fine.

However, during development we use maven-embedded-glassfish to test locally inside the IDE. And the app deployment fails with the following exception.

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

Would anyone be able to help resolving this for our development environment? Several people prefer the embedded glassfish plugin to a complete server for local development.

Seems like a dependency/classpath issue related to maven-embedded-glassfish in particular, but we have no clue where to begin. It's been somewhat difficult to find explanations for CDI WELD-NNNNNN exceptions around Google.

like image 553
JulioHM Avatar asked Aug 07 '13 15:08

JulioHM


1 Answers

Well, after much searching and reading we finally resolved it. Turns out, the webapp was initially developed for Java EE 6, and a decision was made to use Java EE 7 along the way. Well... somethings are different in Java EE 7. It handles managed bean scopes differently. For one thing, the @ViewScoped annotation is not even mentioned in the Java EE 7 docs anymore (there is a new @FlowScoped, but we are still reading on that). We bumped up the log level to FINEST and scoured through endless lines of details to understand what happened.

In order to get it working with the code as it is today, we had to understand a key difference on the CDI implementation. Up until Java EE 6, CDI would scan all packages and all beans would be considered by the container. This behavior apparently changed with Java EE 7, in a way that only classes annotated with a specific scope are considered for becoming managed beans. In other words, the @Named annotation needs to be accompanied by one of the scope annotations (@RequestScoped, @SessionScoped, @DependentScoped, @FlowScoped, etc). Since @ViewScoped is no longer part of the official scope list, the class EnderecoController does not become a managed bean when CDI boots. Trying to inject an instance into UsuarioController results in a generic WELD dependency exception because an instance of that bean was never created.

To get things working in back portability, we had to change the WEB-IBNF/beans.xml file to change attribute bean-discovery-mode="annotated" to 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>

Using the all discovery mode causes the CDI to include all classes for consideration while scanning for managed beans, including the ones that do not have a CDI scope annotation. We are now underway to understand the new scope management better to adapt the code to Java EE 7 standards.

I still find it strange enough that the original code works within a complete glassfish install but not inside maven-embedded-glassfish-plugin.

My personal rant about Java EE/CDI

Also, I would like to explicitly comment on the absurdly broad description given by the WELD-001408 Unsatisfied dependency stacktrace. The message simply means that CDI was unable to provide a dependency injection. No details on what type of error caused the injected bean to NOT be created in the first place. Not even a "sorry, unable to find a bean to instantiate".

An unsatisfied dependency can occur for various reasons. Any exception that occurs while trying to instantiate the dependency is hidden away from log files. You might spend an hour until you realize your bean's constructor is throwing a NullPointerException. This exception wrapping nonsense is the reason why searching for this error message on Google results in a ocean of people having the same error due to different causes.

I hope they improve the error handling, raising exception messages so we can understand better WHY some particular dependency cannot be satisfied.

like image 147
JulioHM Avatar answered Oct 20 '22 16:10

JulioHM