Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClassCastException when casting looked-up EJB view in AS7

I have am deploying 2 EARs onto JBoss AS 7.1.0.Alpha1-SNAPSHOT (post 7.0.1.Final version). Both deploy fine.

I have an EJB Singleton class packaged within a JAR, within one of the EARs:

@Startup
@Singleton
// one of @Local(Store.class), @Remote(Store.class), @LocalBean
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Transactional(TransactionPropagation.SUPPORTS)
public class StoreFront implements Store {
...


public interface Store {
...

When it deploys, it says the EJB is bound to:

"java:app/store-core-2011.1.2-SNAPSHOT/StoreFront"
"java:app/store-core-2011.1.2-SNAPSHOT/StoreFront!uk.co.magus.jam.store.core.Store"
"java:module/StoreFront"
"java:module/StoreFront!uk.co.magus.jam.store.core.Store"
"java:global/store-ear-2011.1.2-SNAPSHOT/store-core-2011.1.2-SNAPSHOT/StoreFront!uk.co.magus.jam.store.core.Store"
"java:global/store-ear-2011.1.2-SNAPSHOT/store-core-2011.1.2-SNAPSHOT/StoreFront"

So far, so good. When I try to look it up via JNDI from a non-CDI, non-EJB class within a JAR within the OTHER deployed EAR, it can only be found on the JNDI names under 'global' - again, expected.

However, when I try to cast the resulting object to the actual interface class:

Object lookupObject = new InitialContext().lookup(jndiName);
Store store = (StoreFront)lookupObject;

I get the following exception:

11:17:52,402 ERROR [jam.core.link.LinkListener] (Thread-45) Exception when casting to Store after lookup with [java:global/store-ear-2011.1.2-SNAPSHOT/store-core-2011.1.2-SNAPSHOT/StoreFront]: java.lang.ClassCastException: jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store
    at jam.core.link.LinkListener.getStore(LinkListener.java:108) [core-jar-2011.1.2-SNAPSHOT.jar:]
    at jam.core.link.LinkListener.postLoad(LinkListener.java:27) [core-jar-2011.1.2-SNAPSHOT.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_07]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_07]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_07]
    at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_07]
    at org.hibernate.ejb.event.ListenerCallback.invoke(ListenerCallback.java:48)
    at org.hibernate.ejb.event.EntityCallbackHandler.callback(EntityCallbackHandler.java:96)
    at org.hibernate.ejb.event.EntityCallbackHandler.postLoad(EntityCallbackHandler.java:89)
    at org.hibernate.ejb.event.EJB3PostLoadEventListener.onPostLoad(EJB3PostLoadEventListener.java:49)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:264)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1012)
    at org.hibernate.loader.Loader.doQuery(Loader.java:889)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
    at org.hibernate.loader.Loader.loadEntity(Loader.java:2058)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:81)
    at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3686)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:446)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:427)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204)
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:251)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:947)
    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:863)
    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:856)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:787)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:762)
    at org.jboss.as.jpa.container.AbstractEntityManager.find(AbstractEntityManager.java:220) [jboss-as-jpa-7.1.0.Alpha1-SNAPSHOT.jar:7.1.0.Alpha1-SNAPSHOT]
    at jam.core.dao.GenericDAO.findById(GenericDAO.java:87) [core-jar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.HarvesterDAOUtil.loadLink(HarvesterDAOUtil.java:251) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.1779224926$Proxy$_$$_WeldSubclass.loadLink(1779224926$Proxy$_$$_WeldSubclass.java) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_07]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_07]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_07]
    at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_07]
    at org.jboss.interceptor.proxy.SimpleInterceptionChain.invokeNextInterceptor(SimpleInterceptionChain.java:112) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.interceptor.proxy.InterceptorInvocationContext.proceed(InterceptorInvocationContext.java:119) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:194) [seam-persistence-3.0.0.Final.jar:]
    at org.jboss.seam.transaction.Work.workInTransaction(Work.java:54) [seam-persistence-3.0.0.Final.jar:]
    at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:188) [seam-persistence-3.0.0.Final.jar:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [:1.6.0_07]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [:1.6.0_07]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [:1.6.0_07]
    at java.lang.reflect.Method.invoke(Method.java:597) [:1.6.0_07]
    at org.jboss.interceptor.proxy.InterceptorInvocation$InterceptorMethodInvocation.invoke(InterceptorInvocation.java:72) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.interceptor.proxy.SimpleInterceptionChain.invokeNextInterceptor(SimpleInterceptionChain.java:82) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:133) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:112) [jboss-interceptor-core-2.0.0.Alpha3.jar:2.0.0.Alpha3]
    at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:65) [weld-core-1.1.2.Final.jar:2011-07-26 15:02]
    at harvest.service.1779224926$Proxy$_$$_WeldSubclass.loadLink(1779224926$Proxy$_$$_WeldSubclass.java) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.CombineHarvester.workOnLinkId(CombineHarvester.java:259) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.CombineHarvester.harvestCache(CombineHarvester.java:223) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.CombineHarvester.performHarvest(CombineHarvester.java:136) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at harvest.service.CombineHarvester.run(CombineHarvester.java:107) [harvest-sar-2011.1.2-SNAPSHOT.jar:]
    at java.lang.Thread.run(Thread.java:619) [:1.6.0_07]

Whether the EJB is annotated with one from any of

@Local(Store.class)
@Remote(Store.class)
@LocalBean 

makes no difference. As I understand it, the fact it's returning a proxy 'view' is normal. However, shouldn't I be able to cast that view to the interface? The combination of which global JNDI name I use and whether I cast to Store or StoreFront also appears to make no difference - unable to cast whatever the combination, even when the exception is like jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store, with matching (base) class names

Can anyone point out what I'm doing wrong?

like image 827
Ben Kirby Avatar asked Sep 01 '11 11:09

Ben Kirby


People also ask

What causes a ClassCastException?

ClassCastException is a runtime exception raised in Java when we try to improperly cast a class from one type to another. It's thrown to indicate that the code has attempted to cast an object to a related class, but of which it is not an instance.

What code will cause a ClassCastException to be thrown?

Class ClassCastException Thrown to indicate that the code has attempted to cast an object to a subclass of which it is not an instance. For example, the following code generates a ClassCastException : Object x = new Integer(0); System.

How do you solve ClassCastException?

To prevent the ClassCastException exception, one should be careful when casting objects to a specific class or interface and ensure that the target type is a child of the source type, and that the actual object is an instance of that type.


3 Answers

This is a bug in AS7: https://issues.jboss.org/browse/AS7-1658

One possible workaround is not to cast the returned object, and then use it to fire methods via reflection. Well clunky though.

like image 62
Ben Kirby Avatar answered Nov 07 '22 07:11

Ben Kirby


A better approach is to deploy the shared interfaces in a jboss module and include that module in both artifacts' classpath with (when using maven)

                <archive>
                    <manifestEntries>
                        <Dependencies>${jboss.nonjee.modules}</Dependencies>
                    </manifestEntries>
                </archive>
like image 39
Riccardo Pasquini Avatar answered Nov 07 '22 07:11

Riccardo Pasquini


Also i get help with this commentary ;):

David Lloyd added a comment - 07/Mar/12 4:02 PM It's because you're using local interfaces. When using local interfaces, you may only have one copy of the interface class (that's what makes it local). Switch to using remote interfaces (or, use Class-Path to get your local interfaces instead of duplicating them) and the problem should disappear.

like image 4
Pasha Avatar answered Nov 07 '22 09:11

Pasha