Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why stateless beans are treated as pseudo-scoped and cannot have circular dependencies?

Using Wildfly 8.1 I have several beans which I try to inject several EJB into each other. Lets say I have 3 beans:

@Stateless 
public class A{
  @Inject
  private B b;
}

@Stateless 
public class B{
  @Inject
  private C c;
}

@Stateless 
public class C{
  @Inject
  private A a;
}

Obviously, I have circular dependency. According to specification:

The container is required to support circularities in the bean dependency graph where at least one bean participating in every circular chain of dependencies has a normal scope

Running above code in container result in an error of the form:

org.jboss.weld.exceptions.DeploymentException: WELD-001443: Pseudo scoped bean has circular dependencies. Dependency path:

-Session bean [class A with qualifiers [@Default @Any]; local interfaces are [A] BackedAnnotatedField] @Inject private B,

[..]

My question here is: what is the scope of @Stateless beans? Is it by default @Dependent? And most of all how can I enable circular dependencies between stateless session beans?

Sorry if the question is too trivial. I will appreciate any good further reading sources which will explain presented behavior. Thanks in advance.

UPDATED Ok. I found the workaround. I've used @EJB annotation instead of @Inject but this does not explain the weird behavior of @Inject. The question remains open but as Mika suggested it may be unresolved issue in both CDI specification and Weld RI.

like image 378
iku Avatar asked Oct 20 '14 14:10

iku


3 Answers

It's a bug in wildfly/jboss CDI implementation. Current workaround (as suggested by @MikeBraun), provided in issue description https://issues.jboss.org/browse/CDI-414, is to use @EJB annotation instead of @Inject.

like image 121
iku Avatar answered Nov 17 '22 06:11

iku


@Stateless has no scope and has no correlation to any scope. Your beans are ending up as @Dependent since you have not annotated any other scope on your beans.

You need to give them a normal scope - @RequestScoped or @ApplicationScoped, however I'm not sure either makes sense in your case.

like image 35
John Ament Avatar answered Nov 17 '22 06:11

John Ament


This doesn't answer the entire question, but it was the first hit on google when I searched circular dependency exceptions. Hoping this will help other programmers finding a quicker answer here is my solution.

The code that cause circular dependency exception:

class A{
    @Inject B b;
    public void foo(){
        b.bar();
    }
    public void quux(){
        //some code
    }
}
class B{
    @Inject A a;
    public void bar(){
        //some code
    }
    public void baz(){
        a.quux();
    }
}

A solution to solve the issue is by using javax.enterprise.inject.Instance

class A{
    @Inject B b;
    public void foo(){
        b.bar();
    }
    public void quux(){
        //some code
    }
}
class B{
    @Inject Instance<A> a;
    public void bar(){
        //some code
    }
    public void baz(){
        a.get().quux();
    }
}
like image 3
dirbacke Avatar answered Nov 17 '22 04:11

dirbacke