2011-09-01 23 views
9

Tengo que implementar 2 EAR en JBoss AS 7.1.0.Alpha1-SNAPSHOT (post 7.0.1.Final version). Ambas implementan bien.ClassCastException cuando se lanza la vista EJB buscada en AS7

tengo una clase EJB Singleton empaquetado dentro de un frasco, dentro de una de las orejas:

@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 { 
... 

Cuando se despliega, se dice que el EJB está obligado a:

"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" 

Hasta el momento, tan bueno. Cuando trato de buscarlo a través de JNDI desde una clase no CDI, no EJB dentro de un JAR dentro de OTR desplegado, solo puede encontrarse en los nombres JNDI en 'global', de nuevo, esperado.

Sin embargo, cuando intento convertir el objeto resultante a la clase de interfaz real:

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

consigo la siguiente excepción:

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] 

Si el EJB se anota con uno de cualquiera de

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

no hace ninguna diferencia. Tal como lo entiendo, el hecho de que esté devolviendo una 'vista' de proxy es normal. Sin embargo, ¿no debería ser capaz de transmitir esa vista a la interfaz? La combinación de qué nombre JNDI global uso y si envío contenido a Store o StoreFront también parece no tener ninguna diferencia: no se puede emitir la combinación, incluso cuando la excepción es jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store, con nombres de clase (base) coincidentes

¿Alguien puede señalar lo que estoy haciendo mal?

Respuesta

4

Un mejor enfoque consiste en implementar las interfaces compartidas en un módulo de JBoss e incluir ese módulo en la ruta de clase dos artefactos con (cuando se utiliza Maven)

   <archive> 
        <manifestEntries> 
         <Dependencies>${jboss.nonjee.modules}</Dependencies> 
        </manifestEntries> 
       </archive> 
+0

Ahh, no me di cuenta de eso. Actualmente no es una opción para nosotros, pero es un gran punto. –

3

también obtener ayuda con este comentario;):

David Lloyd agregó un comentario - 07/Mar/12 4:02 PM Es porque estás usando interfaces locales. Al usar interfaces locales, solo puede tener una copia de la clase de interfaz (eso es lo que la hace local). Cambie al uso de interfaces remotas (o use Class-Path para obtener sus interfaces locales en lugar de duplicarlas) y el problema debería desaparecer.

2

Estaba teniendo el mismo problema; Intenté colocar la clase de interfaz como un módulo sperate e incluirlo en un oído e incluirlo como proporcionado en el otro oído; En JBOSS las clases en cada EAR son cargadas por un cargador de clases separado. Entonces, si un EAR tiene Clase A y otro tiene la misma Clase A, entonces usted obtiene una excepción de lanzamiento de clase. Por lo tanto, en el segundo EAR, proporcione la dependencia tal como se proporciona y en jboss-deployment-structure.xml agregue el primer EAR como dependencia del módulo.Tenga en cuenta que la dependencia del módulo dinámico puede garantizar que el nombre del archivo EAR sea constante; Puede especificar <finalName> bajo la etiqueta de compilación para el archivo EAR para solucionar este

también cambió la búsqueda de local a remoto - véase más adelante, y se incluye el módulo experto que contiene la interfaz tanto en los módulos

//jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); 

TO 
    jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.naming.remote.client.InitialContextFactory"); 

y que le gustaría cambiar la búsqueda de java: app de java: mundial

final javax.naming.Context context = new InitialContext(jndiProperties); 
     AsyncFutureItf test =(AsyncFutureItf)context.lookup 
       //("java:app/Executor/AsyncFutureTest!pacakge.AsyncFutureItf"); 
       ("java:global/ExecutorEar/Executor/AsyncFutureTest!package.AsyncFutureItf"); 

y puesto que el oído es normalmente registrado en la versión como esta

java:global/ExecutorEar-<version>/Executor/AsyncFutureTest!package.AsyncFutureItf 

y no desea que la versión de búsqueda impulsado en su código, es necesario hacer dos cosas más. En su aplicacion.xml en el oído experto constructor de dir (src \ principales recursos \ \ aplicacion.xml) es necesario agregar la etiqueta "nombre-aplicación" como

<?xml version="1.0" encoding="UTF-8"?> 
<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5"> 
    <description>Task Controller EAR</description> 
    <display-name>TaskControllerEAR</display-name> 
    <application-name>TaskControllerEAR</application-name> 
    <module> 
    <ejb>TaskController.jar</ejb> 
    </module> 
    <library-directory>lib</library-directory> 
</application> 

y en su pom pom para generar la que Deberá proporcionar una referencia a la aplicacion.xml como

<groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-ear-plugin</artifactId> 
      <version>2.4.2</version> 
      <configuration> 
       <version>5</version> 
       <defaultLibBundleDir>lib</defaultLibBundleDir> 
       <earSourceDirectory>src/main/resources</earSourceDirectory> 
       <applicationXml>${project.basedir}/src/main/resources/application.xml</applicationXml> 

...

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0"> 
     <ear-subdeployments-isolated>false</ear-subdeployments-isolated> 


     <sub-deployment name="MROControllerRest.war"> 
       <exclusions> 
          <module name="org.apache.commons.logging" /> 
          <module name="org.slf4j" /> 
          <module name="org.slf4j.ext" /> 
          <module name="org.slf4j.jcl-over-slf4j" /> 
          <module name="org.slf4j.impl" /> 
          <module name="org.apache.log4j" /> 
       </exclusions> 
       <dependencies> 
        <module name="org.slf4j" slot="1.7.5" /> 
        <module name="logger" /> 
        <module name="deployment.TaskControllerEAR.ear.TaskController.jar" export="TRUE"/> 

       </dependencies> 

Aquí es el seguimiento de la pila para referencia

java.lang.ClassCastException: com.package.TaskSplitterItf$$$view210 cannot be cast to com.package.TaskSplitterItf 
+0

Cambiar el ámbito de dependencia del módulo ejb a 'provided' en el archivo pom del módulo web resolvió el problema de excepción de lanzamiento de clase. Gracias. – EmeraldTablet

1

mismo problema también si el EJB-cliente se encuentra en una oreja y la implementación de EJB en otro -auriculoterapia "servicio", y que invoque un método @Remote interfaz de el EJB devuelve un objeto complejo en lugar de un tipo primitivo. El objeto complejo que se devuelve también se declara como una interfaz, declarada correctamente, conocida y disponible para el cliente EJB. La implementación Objeto devuelta está contenida en el "servicio" -EAR junto con la implementación de EJB de destino también. A pesar de dicho código conforme, JBoss falla en la excepción de lanzamiento de clase.

Me observó que de hecho puede mantener una interfaz @Remote para declarar todos los métodos EJB de destino, pero sólo puede usar una declaración de clase normal para todos los objetos devueltos por esos métodos. Si declara los objetos devueltos como interfaces, se producirán excepciones de lanzamiento de clases en JBoss.

Esto es una limitación (o error) en JBoss; funciona en Glassfish y WebLogic donde tuvimos el mismo código una vez que se ejecuta.

1

mismo problema ocurrido si tiene el archivo JAR EJB con sus más que una vez en su oído.

muestra:

Tienes

  • un archivo myEJB.jar que contiene la totalidad de su EJB
  • un myWebApp.war que contiene las clases web/recursos
  • un myEnterprise.ear que contiene myEJB.jar y myWebApp.jar

Si su myWebApp.war también contiene el myEJB.jar por sí mismo, entonces tendrá este error (ClassCastExc). Parece que el objeto EJB se crea dentro de myEJB.jar de myEnterprise.ear. Y si luego va a convertir este objeto en la misma clase del myEJB.jar dentro de myWebApp.war, esto no funcionará porque esta clase está definida en otro jar.

Si tiene este error, debe quitar la myEJB.jar de su archivo de la guerra y la ClassCastExc se ha ido ...

Cuestiones relacionadas