1
votes

In the following code I'm trying to inject a SessionScoped bean into a stateless EJB, but I want to do the @Inject in an abstract base class of the EJB. According to the CDI spec it seems to suggest that this should work (never a spec to waste words):

"4.2. Inheritance of member-level metadata

Suppose a class X is extended directly or indirectly by the bean class of a managed bean or session bean Y.

If X declares an injected field x then Y inherits x."

What happens is that I can access the inherited protected member sessionView from TestEjb, but not from code within the base class. When I say "can access", I mean that the injected member is accessible at runtime and is not null.

@Named
@ViewAccessScoped
public class JsfBean extends implements Serializable {
  @Inject private TestEjb ejb;

  SessionView s1 = ejb.getSessionViewChild();  // sessionView injected ok
  SessionView s2 = ejb.getSessionViewBase();   // sessionView is null
}

@Named
@SessionScoped
public class SessionView implements Serializable {}

@Stateless
public class TestEjb extends BaseClass implements Serializable {

  public SessionView getSessionViewChild() {
    return sessionView;
  }
}

public abstract class BaseClass implements Serializable {
    @Inject
    protected SessionView sessionView;

    public SessionView getSessionViewBase() {
      return sessionView;
  }
}

What happens is that s1 is a valid SessionView reference, but s2 is null.

I am using MyFaces CODI 1.01 in conjunction with Weld from Glassfish 3.1.1. I've tried removing abstract from BaseClass and even added @Named, but this hasn't helped and I can't see what I'm doing wrong.

As it stands it looks like I'll have to inherit sessionView from the base class and pass it back in as a parameter to methods from the base class. So I'll be grateful if anyone can point out if I'm doing something stupid, perhaps this is a CODI/Weld issue?

Thanks.

2
It now seems that if I change the access of sessionView in BaseClass to private, it works, but only if I shutdown the app server and clean & build. It will then reliably work across rebuilds & redeployments. If I then change the access back to protected & clean & build, it will consistently not work until reverted back to private. It looks like I'll be logging a bug against CODI, but if anyone can shed any light on this it would be appreciated.Oversteer

2 Answers

1
votes

That's a bug in Weld. If it works with other scopes, it's a bug with custom scopes in combination with Weld.

0
votes

It turns out that my understanding of the problem at the time of posting was based on too limited a set of observations - it was all wrong. It turns out that the actual problem was that I wasn't successfully injecting an entity manager into a stateless ejb with @PersistenceContext in an overloaded method that accepts a generic type parameter. This problem is supposedly fixed in glassfish 3.1.2. For example:

@Stateless
public class Myejb<T> {

  @PersistenceContext(unitName = "TestPU")
  private EntityManager em;

  public void find(String id) { em.find... }
  public void find(T id) { em.find... }

em in find(T id) will be null, and there's the same problem injecting with @EJB as with @PersistenceContext. Quite a biggy really!

http://java.net/jira/browse/GLASSFISH-17235