[undertow-dev] ClassCastException when retrieving a beans from CDI with Weld Proxy beans
Martin Kouba
mkouba at redhat.com
Fri Apr 21 03:44:41 EDT 2017
Hi Eric,
I wouldn't recommend to use CDI.current().select() to lookup session
beans at all. From CDI POV, if you do a lookup from the ejbs.jar you
should not see the bean from the webapp.war.
Also note that having a class deployed in two different bean archives is
non-portable, see also 12.1. Bean archives:
"If a bean class is deployed in two different bean archives,
non-portable behavior results...". [1] In real life having this causes
similar CL/casting issues, esp. in EARs.
In any case, this is not an Undertow issue and we should move this
discussion to Weld or WildFly channels.
Martin
[1]
http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#bean_archive
Dne 20.4.2017 v 20:04 Eric B napsal(a):
> Indeed, it was an issue with duplicate copies of the class. But I'm
> still not convinced I should be getting this error. Is this aou
> parent-first vs parent-last class loading issue?
>
> The LoginManager.class is part of my ejbs.jar archive.
>
> In my EAR, I had the following
> - ejbs.jar
> - webapp.war
> \- WEB-INF/lib
> \- ejbs.jar
>
>
> I am deploying the with default classloading mechanism (I believe it is
> parent-first). But based on the
> https://docs.jboss.org/author/display/WFLY10/Class+Loading+in+WildFly, I
> seem to understand that the Local Resources (ie: classes within my WAR)
> would have a higher dependence than those from the EAR:
>
> In order of highest priority to lowest priority
>
> 1. System Dependencies - These are dependencies that are added to
> the module automatically by the container, including the Java EE
> api's.
> 2. User Dependencies - These are dependencies that are added
> through jboss-deployment-structure.xml or through
> the Dependencies: manifest entry.
> 3. Local Resource - Class files packaged up inside the deployment
> itself, e.g. class files from WEB-INF/classes or WEB-INF/lib of
> a war.
> 4. Inter deployment dependencies - These are dependencies on other
> deployments in an ear deployment. This can include classes in an
> ear's lib directory, or classes defined in other ejb jars.
>
>
> If that is the case, is my problem that I have the EJB implementation
> class in my WAR as well? Is my war only supposed to have a copy of the
> LoginManager interface and not the actual impl code as well? Wouldn't
> that still cause an issue in that my EJB interface and implementation is
> in the root/ejbs.jar and I have an additional copy of the interface in
> my war?
>
> Thanks,
>
> Eric
>
>
> On Mon, Apr 17, 2017 at 6:01 PM, Stuart Douglas <sdouglas at redhat.com
> <mailto:sdouglas at redhat.com>> wrote:
>
> It sounds like a class loading problem. You likely have two copies of
> ejbs.LoginManager, and somehow you are using the wrong one. If you
> look at the output of
> System.out.println(LoginManager.class.getClassLoader()) and
> System.out.println(CDI.current().select(clazz).get().getClass().getClassLoader())
> it should give you a clue.
>
> This is not an Undertow issue.
>
> Stuart
>
> On Fri, Apr 14, 2017 at 11:52 AM, Eric B <ebenzacar at gmail.com
> <mailto:ebenzacar at gmail.com>> wrote:
> > I posted this problem on StackOverflow, but after doing more
> research, I'm
> > not sure if this is a Weld, JBoss/WildFly or undertow issue. Or
> whether its
> > a framework issue, or how the framework is being used. If this is
> not the
> > correct list, can you please let me know which list/group I should be
> > directing the issue to?
> >
> > I'm running into a strange problem and error message that I do not
> > understand. I'm running my application on JBoss 7 EAP.
> >
> > Caused by: java.lang.ClassCastException: Cannot cast
> > ejbs.LoginManager$417755913$Proxy$_$$_Weld$EnterpriseProxy$ to
> > ejbs.LoginManager
> >
> > I'm trying to programatically retrieve an EJB from the CDI context
> by using
> > its interface and am getting this error message. I've created a sample
> > proof-of-concept that is trying to retrieve EJB beans from the CDI
> context
> >
> > public <T> T getSesionBean(Class<T> clazz, String name) {
> > Properties properties = new Properties();
> >
> > try {
> > InitialContext initContext = new InitialContext();
> >
> > return clazz.cast(CDI.current().select(clazz).get());
> > } catch (Exception e) {
> > // TODO Auto-generated catch block
> > throw new RuntimeException(e);
> > }
> > }
> >
> > It is being called as:
> >
> > LoginManager login = getSesionBean(LoginManager.class);
> >
> > with my EJB defined as:
> >
> > @Stateless(name="LoginManager")
> > @Local(LoginManager.class)
> > @LocalBinding(jndiBinding="LoginManager")
> > public class LoginManagerBean implements LoginManager {
> > ...
> > ...
> > ...
> > }
> >
> > I don't understand it. I'm expecting the bean being retrieved from the
> > context to be a proxy. Shouldn't it be castable to my interface?
> Otherwise,
> > how am I supposed to retrieve it?
> >
> > More interestingly, this does not seem to be a consistent error;
> sometimes
> > the code works fine. Sometimes it fails. I haven't been able to
> determine
> > what makes it work or throw an exception.
> >
> > I found a related issue here, but not sure if this is the same problem
> > and/or which version of Weld is used in JB7EAP. I'm including the
> following
> > dependency in my application:
> >
> > <dependency>
> > <groupId>org.wildfly</groupId>
> > <artifactId>wildfly-ejb-client-bom</artifactId>
> > <version>10.1.0.Final</version>
> > <type>pom</type>
> > </dependency>
> >
> > Am I doing something completely wrong? If this is a Weld bug, can
> I use a
> > different proxy system than Weld? Is this even configurable in
> undertow?
> >
> >
> > Thanks,
> >
> >
> > Eric
> >
> >
> > _______________________________________________
> > undertow-dev mailing list
> > undertow-dev at lists.jboss.org <mailto:undertow-dev at lists.jboss.org>
> > https://lists.jboss.org/mailman/listinfo/undertow-dev
> <https://lists.jboss.org/mailman/listinfo/undertow-dev>
>
>
>
>
> _______________________________________________
> undertow-dev mailing list
> undertow-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/undertow-dev
>
--
Martin Kouba
Senior Software Engineer
Red Hat, Czech Republic
More information about the undertow-dev
mailing list