2011-09-01 38 views
9

我要將2個EAR部署到JBoss AS 7.1.0.Alpha1-SNAPSHOT(後7.0.1.Final版本)上。兩者都可以部署。當在AS7中強制查找EJB視圖時發生ClassCastException

我有一隻耳朵內的JAR內包裝的EJB Singleton類,:

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

當它展開時,它說,EJB勢必:到目前爲止

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

,太好了。當我試圖通過JNDI從OTHER CDI內部的非CDI非EJB類中查找它時,它只能在'global'下的JNDI名稱中找到 - 這也是預期的。

然而,當我嘗試生成的對象轉換爲實際的接口類:

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

我得到以下異常:

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] 

無論EJB從任何的標註有一個

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

沒有區別。據我瞭解,它返回代理'視圖'的事實是正常的。但是,我不應該將該視圖投射到界面上嗎?我使用的全局JNDI名稱以及是否我的組合轉換爲商店或店面似乎也沒有什麼區別 - 無法施放任何組合,即使在例外的是像jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store,與之搭配(基地)類名

任何人都可以指出我做錯了什麼?

回答

4

一個更好的方法是一個JBoss模塊中部署共享的接口,其中包括兩個文物與類路徑模塊(使用maven時)

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

啊,我沒有意識到這一點。目前不是我們的選擇,但一個偉大的觀點。 –

3

而且我得到幫助,這解說):

David Lloyd添加評論 - 07/Mar/12 4:02 PM 這是因爲你正在使用本地接口。當使用本地接口時,你可能只有一個接口類的副本(這就是本地接口)。切換到使用遠程接口(或者,使用Class-Path獲取本地接口而不是複製它們),問題應該消失。

2

我遇到了同樣的問題;試圖將接口類作爲一個sperate模塊,並將其包含在一個Ear中,並將其包含在另一個Ear中; 在JBOSS中,每個EAR中的類都由一個單獨的類加載器加載。所以如果一個EAR具有A類,而另一個具有相同的A類,那麼你會得到一個類轉換異常。因此,在第二個EAR中,提供依賴關係,並在jboss-deployment-structure.xml中將第一個EAR添加爲模塊依賴關係。請注意,動態模塊依賴性可能會保證EAR文件名稱不變;您可以構建標籤下指定<finalName>的EAR文件來解決這個

也從本地到遠程更改查找 - 見下文,並且包括含有界面中兩個模塊Maven的模塊

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

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

你想改變從Java查找:應用到Java:全球

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

而且,由於耳通常用的版本是這樣

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

而且你不想在你的代碼中進行版本驅動查找,你需要做更多的事情。在你的你的EAR的application.xml建設者行家目錄(SRC \主\資源\ application.xml中),你需要添加「應用程序名」標籤像

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

,並在你的POM中產生的POM你需要提供的application.xml參考像

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

下面是引用堆棧跟蹤

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

在web模塊的pom文件中將ejb模塊的依賴範圍更改爲'provided'解決了類拋出異常問題。謝謝。 – EmeraldTablet

1

同樣的問題太多,如果你的EJB客戶端是在EAR而在另一個「服務」 -ear EJB實現,和你調用一個@Remote接口方法EJB返回一個複雜的對象而不是原始類型。被返回的複雜對象也被聲明爲一個接口,已正確聲明,已知且可供EJB客戶機使用。返回的Object實現也包含在「服務」-EAR中,以及目標EJB實現。 儘管有這樣一致的代碼,但JBoss在Class拋出異常時失敗。

我注意到您確實可以保留@Remote接口來聲明所有目標EJB方法,但只能對這些方法返回的所有對象使用普通類聲明。如果您將返回的對象聲明爲接口,則在JBoss中會出現類轉換異常。

這是JBoss的限制(或錯誤);它可以在Glassfish和WebLogic中運行,我們在運行時擁有相同的代碼。

1

如果您在您的EAR中將EJB文件的jar文件更多地添加爲一次,則會出現相同的問題。

樣品:

你有

  • 一個myEJB.jar文件,它包含所有EJB的
  • ,其中包含您的網絡班MyWebApp.war的/資源
  • 一個myEnterprise.ear其中包含myEJB.jar和myWebApp.jar

如果您的myWebApp。戰爭還包含自己myEJB.jar然後你會有這個錯誤(ClassCastExc)。看起來EJB對象是在myEnterprise.ear的myEJB.jar中創建的。如果你將這個對象轉換成myWebApp.war中myEJB.jar的同一個類,這將不起作用,因爲這個類是在另一個jar中定義的。

如果你有這樣的錯誤,你必須從你的戰爭文件中刪除myEJB.jar和ClassCastExc不見了......

相關問題