Local no-interface view EJB3.1 proxy requests superclass of EJB from container
------------------------------------------------------------------------------

                 Key: WELD-625
                 URL: https://jira.jboss.org/browse/WELD-625
             Project: Weld
          Issue Type: Bug
    Affects Versions: 1.0.1.Final, 1.1.0.BETA2
         Environment: Glassfish 3.0.1 with JDK 1.6.0r18, Glassfish 3.1 build 15 
with JDK 1.7b101. Ubuntu 10.04. Also tried upgrading Glassfish 3.0.1 to Weld 
1.0.1-Final and upgrading Glassfish 3.1 build 15 to the latest Weld 1.1 
snapshot (900); issue still occurs.

Tested with JBoss AS 6 M4 as well, but cannot reproduce the issue there. 
            Reporter: Craig Ringer


If Weld (CDI) is used to inject a local no-interface view of an EJB into 
another managed bean, the generated proxy that is injected cannot resolve calls 
to methods implemented in the EJB's superclass that aren't overridden by the 
concrete EJB class. 

An outline of the simplified test case that demonstrates the problem is:

// This can be any DI candidate in an EJB container. In this case it's a JSF2 
backing bean
// managed in a CDI context.
//
@javax.inject.Named
@javax.enterprise.context.SessionScoped
public class InjectionSite {
    // If injected via @EJB, everything works, because we don't use Weld to 
create the proxy.
    @Inject private EJBClass ejb;
    public int getValue() {
        // Throws IllegalStateException from Weld
        return ejb.getValue();
    }
}

// The EJB its self has a method that's implemented by a superclass and
// not overridden by the concrete EJB class.
@Stateless
public class EJBClass extends EJBSuper {
    // Inherits getValue() from super
}

public class EJBSuper {
   public int getValue() {
       return 1;
   }
}

This seems to come down to Weld's EnterpriseBeanProxyMethodHandler. It decides 
which EJB class to ask the container for an instance of by determining which 
class implements the method being called. If the implementation is in a 
superclass of the EJB, this will fail, because the container doesn't know 
anything about the EJB's superclass, and in any non-trivial case there'll be 
several different EJBs with the same superclass anyway.

The test case functions correctly if modified to use the Glassfish native 
JSF2/EJB injection via @EJB instead of Weld injection with @Inject, as the 
proxy created by @EJB isn't the Weld proxy implementation. That's only an 
option if you're using JSF2, though.

As a workaround, the concrete EJB can wrap the superclass's methods, but this 
is rather clumsy in real-world cases where the superclass exists for a reason, 
particularly for things like data access facades where the superclass contains 
generified DAO methods and subclasses only provide a type param and a few 
helpers.

If the object being injected isn't an EJB, everything works fine, but that's 
not really an option if you need EJB features or if you're injecting a bean 
that can't be made serializable into a serializable object like a JSF2 
session-scoped bean.

Background here: 
http://forums.java.net/jive/thread.jspa?messageID=480532&#480532 . A test case 
is attached to the thread.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
https://jira.jboss.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        
_______________________________________________
weld-issues mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/weld-issues

Reply via email to