2011-09-01 16 views
9

Wdrażam 2 EAR na JBoss AS 7.1.0.Alpha1-SNAPSHOT (wersja 7.0.1.Final). Oba wdrażają dobrze.Wyjątek ClassCastException podczas rzucania wyeksponowanego widoku EJB w AS7

Mam klasy EJB Singleton pakowane w słoik, w jednym z uszu:

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

Gdy instaluje, to mówi EJB jest zobowiązany do:

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

tej pory tak dobrze. Kiedy próbuję wyszukać za pośrednictwem JNDI z klasy innej niż CDI, nie należącej do EJB w obrębie pliku JAR w ramach INDZIEGO wdrożonego pliku EAR, można go znaleźć tylko w nazwach JNDI pod "globalnym" - ponownie, oczekiwano.

Jednak kiedy próbuję oddać obiekt wynikowy do rzeczywistej klasy interfejs:

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

otrzymuję następujący wyjątek:

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] 

czy EJB jest opatrzone jednym z dowolnego

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

nie ma znaczenia. Jak rozumiem, fakt, że zwraca "widok" proxy, jest normalny. Jednak czy nie powinienem móc rzutować tego widoku na interfejs? Kombinacja tej globalnej nazwy JNDI, której używam, oraz tego, czy rzutuję na Store lub StoreFront, również wydaje się nie mieć żadnej różnicy - nie można rzucić tej kombinacji, nawet jeśli wyjątek jest taki jak jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store, z pasującymi nazwami (podstawowymi)

Czy ktoś może wskazać, co robię źle?

Odpowiedz

4

Lepszym rozwiązaniem jest, aby wdrożyć wspólne interfejsy w module jboss i te moduły w ścieżce klas obu artefaktów z (przy użyciu Maven)

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

Ahh, nie zdawałem sobie sprawy, że. Obecnie nie jest to opcja dla nas, ale świetny punkt. –

3

także uzyskać pomoc z tym komentarzem;):

David Lloyd dodał komentarz - 07/Mar/12 4:02 PM To dlatego, że używasz lokalnych interfejsów. Podczas korzystania z lokalnych interfejsów, możesz mieć tylko jedną kopię klasy interfejsu (co czyni ją lokalną). Przełącz się na zdalne interfejsy (lub użyj Ścieżka klasy, aby uzyskać lokalne interfejsy zamiast ich duplikowania), a problem powinien zniknąć.

2

Miałem ten sam problem; Próbowałem umieścić klasę Interface jako moduł sperate i umieściłem go w jednym uchu i uwzględniłem go jako dostarczony w drugim uchu; W JBOSS klasy w każdym pliku EAR są ładowane przez osobny moduł ładujący klasy. Jeśli więc jedna EAR ma klasę A, a inna ma tę samą klasę A, otrzymasz wyjątek od klasy. Tak więc w drugim pliku EAR podaj zależność podaną w jboss-deployment-structure.xml dodaj pierwszą wartość EAR jako zależność od modułu.Należy zauważyć, że zależność modułu dynamicznego może gwarantować, że nazwa pliku EAR będzie stała; Można określić <finalName> pod tagiem kompilacji dla pliku EAR to naprawić

zmienił także odnośnika od lokalnego do zdalnego - patrz niżej, a zawarte moduł maven zawierający interfejs w obu modułach

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

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

i co chcesz zmienić odnośnika z Java: aplikację Java: Global

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

a ponieważ ucho jest zazwyczaj zarejestrowany w wersji jak ta

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

i nie chcesz, aby wyszukiwanie oparte na wersji było w twoim kodzie, musisz zrobić jeszcze dwie rzeczy. W swojej application.xml w uchu budowniczy Maven dir (src \ main \ Resources \ application.xml) trzeba dodać "application-name" tag jak

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

oraz w pom pom do wygenerowania ty należy podać odniesienie do application.xml jak

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

Oto ślad stosu dla odniesienia

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

Zmiana zakresu zależności modułu ejb na "dostarczony" w pliku pom w module WWW rozwiązał problem wyjątków związanych z klasą rzutowania. Dziękuję Ci. – EmeraldTablet

1

sam problem zbyt jeśli EJB-klient jest w uchu i wdrażania EJB w innej „serwis” -EAR i wywołać metodę @Remote interfejsu na EJB zwraca obiekt złożony zamiast typu pierwotnego. Zwracany obiekt złożony jest również zadeklarowany jako interfejs, właściwie zadeklarowany, znany i dostępny dla klienta EJB. Zwrócona implementacja Object jest zawarta w "usłudze" -EAR wraz z docelową implementacją EJB. Mimo takiego zgodnego kodu, JBoss kończy się niepowodzeniem na wyjątku odlewania klasy.

Zauważyłem, że rzeczywiście można zachować interfejs @Remote do deklarowania wszystkich docelowych metod EJB, ale można użyć tylko deklaracji klasowej dla wszystkich obiektów zwróconych przez te metody. Jeśli zadeklarujesz zwrócone obiekty jako interfejsy, wystąpią wyjątki odlewane w JBoss.

To jest ograniczenie (lub błąd) w JBoss; działa w Glassfish i WebLogic, gdzie po uruchomieniu mieliśmy ten sam kod.

1

Ten sam problem wystąpił, jeśli plik JAR zawiera EJB więcej niż jeden raz w pliku EAR.

Próbka:

Masz

  • myEJB.jar pliku, który zawiera wszystkie swoje EJB
  • się myWebApp.war który zawiera swoje klasy internetowych/Zasoby
  • się myEnterprise.ear która zawiera myEJB.jar i myWebApp.jar

Jeśli twój myWebApp.wojna zawiera również plik myEJB.jar, a następnie pojawi się ten błąd (ClassCastExc). Wygląda na to, że obiekt EJB został utworzony w pliku myEJB.jar pliku myEnterprise.ear. I jeśli następnie zostaniecie rzuceni tym obiektem do tej samej klasy myEJB.jar wewnątrz myWebApp.war, to nie zadziała, ponieważ ta klasa jest zdefiniowana w innym słoiku.

Jeśli masz ten błąd należy usunąć z pliku myEJB.jar wojennej i ClassCastExc nie ma ...

Powiązane problemy