2011-09-01 19 views
9

Tôi đang triển khai 2 EAR lên JBoss AS 7.1.0.Alpha1-SNAPSHOT (phiên bản 7.0.1.Final). Cả hai đều triển khai tốt.ClassCastException khi truyền chế độ xem EJB tra cứu trong AS7

Tôi có một lớp EJB Singleton đóng gói trong một JAR, trong một trong những tai:

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

Khi triển khai, nó nói các EJB là ràng buộc để:

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

Cho đến nay, rất tốt Khi tôi cố gắng tìm kiếm nó qua JNDI từ một lớp không phải CDI, không phải EJB trong một JAR bên trong EAR được triển khai KHÁC, nó chỉ có thể được tìm thấy trên các tên JNDI dưới 'toàn cầu' - một lần nữa, được mong đợi.

Tuy nhiên, khi tôi cố gắng cast đối tượng dẫn đến các lớp giao diện thực tế:

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

tôi nhận được ngoại lệ sau đây:

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] 

Cho dù EJB được chú thích với một từ bất kỳ

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

không có sự khác biệt. Như tôi đã hiểu, thực tế nó quay trở lại một cái nhìn 'proxy' là bình thường. Tuy nhiên, tôi có nên bỏ chế độ xem đó vào giao diện không? Sự kết hợp giữa tên JNDI toàn cục mà tôi sử dụng và liệu tôi có cast hay StoreFront cũng không tạo ra sự khác biệt nào - không thể đúc bất kỳ kết hợp nào, ngay cả khi ngoại lệ giống như jam.store.core.Store$$$view1 cannot be cast to jam.store.core.Store, với tên lớp cơ sở phù hợp

Bất cứ ai có thể chỉ ra những gì tôi đang làm sai?

Trả lời

8

Đây là một lỗi trong AS7: https://issues.jboss.org/browse/AS7-1658

Một workaround có thể không phải là để cast đối tượng trở lại, và sau đó sử dụng nó để bắn phương pháp thông qua reflection. Vâng clunky mặc dù.

4

Một cách tiếp cận tốt hơn là để triển khai các giao diện được chia sẻ trong một module JBoss và bao gồm rằng mô-đun trong classpath cả hiện vật với (khi sử dụng maven)

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

Ahh, tôi đã không nhận ra điều đó. Hiện không phải là một lựa chọn cho chúng tôi, nhưng là một điểm tuyệt vời. –

3

Ngoài ra tôi nhận được sự giúp đỡ với lời bình luận này;):

David Lloyd đã thêm nhận xét - 07/Mar/12 4:02 PM Đó là vì bạn đang sử dụng giao diện cục bộ. Khi sử dụng các giao diện cục bộ, bạn chỉ có thể có một bản sao của lớp giao diện (đó là những gì làm cho nó trở thành cục bộ). Chuyển sang sử dụng giao diện từ xa (hoặc sử dụng Class-Path để nhận các giao diện cục bộ của bạn thay vì sao chép chúng) và vấn đề sẽ biến mất.

2

Tôi đã nhận được cùng một vấn đề; Đã cố gắng đặt lớp Giao diện như là một mô-đun sperate và bao gồm nó trong một tai và bao gồm nó như là một cung cấp trong tai khác; Trong JBOSS, các lớp trong mỗi EAR được nạp bởi một trình nạp lớp riêng biệt. Vì vậy, nếu một EAR có Class A, và một EAR khác có cùng Class A, thì bạn sẽ có một ngoại lệ cast class. Vì vậy, trong EAR thứ hai cung cấp sự phụ thuộc như được cung cấp và trong tệp jboss-deployment-structure.xml, hãy thêm EAR đầu tiên làm phụ thuộc vào mô-đun.Lưu ý rằng phụ thuộc vào mô đun động có thể đảm bảo tên tệp EAR là không đổi; Bạn có thể chỉ định <finalName> dưới xây dựng từ khóa cho file EAR để sửa lỗi này

Cũng thay đổi tra cứu từ địa phương để từ xa - xem dưới đây, và bao gồm các module maven chứa giao diện ở cả module

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

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

và bạn sẽ muốn thay đổi tra cứu từ java: ứng dụng java: toàn cầu

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

và kể từ khi tai thường được đăng ký với các phiên bản như thế này

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

và bạn không muốn tra cứu theo định hướng phiên bản trong mã của mình, bạn cần phải làm hai việc nữa. Trong application.xml của bạn trong EAR của bạn builder maven dir (src \ resources \ chính \ application.xml), bạn cần phải thêm "application-name" tag như

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

và trong pom của bạn để tạo ra pom bạn cần cung cấp một tham chiếu đến application.xml như

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

Đây là stack trace để tham khảo

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

Thay đổi phạm vi phụ thuộc của mô-đun ejb thành 'được cung cấp' trong tệp pom của mô-đun web đã giải quyết vấn đề ngoại lệ của lớp diễn viên. Cảm ơn bạn. – EmeraldTablet

1

vấn đề tương tự quá nếu EJB-client của bạn là trong một EAR và thực hiện EJB trong một -EAR "dịch vụ", và bạn gọi một phương pháp @Remote Interface trên EJB trả về một đối tượng phức tạp thay vì một kiểu nguyên thủy. Đối tượng phức tạp được trả về cũng được khai báo là một Giao diện, được khai báo chính xác, đã biết và có sẵn cho EJB-client. Việc thực hiện đối tượng trả về là, nó, chứa trong "dịch vụ" -EAR cùng với việc thực hiện EJB đích. Mặc dù mã tuân thủ như vậy, JBoss không thành công trên ngoại lệ lớp học diễn viên.

Tôi lưu ý rằng bạn thực sự có thể giữ giao diện @Remote để khai báo tất cả các phương thức EJB đích, nhưng chỉ có thể sử dụng khai báo lớp đơn giản cho tất cả các đối tượng được trả về bởi các phương thức đó. Nếu bạn khai báo các đối tượng được trả về dưới dạng các giao diện, thì các trường hợp ngoại lệ của lớp diễn ra trong JBoss.

Đây là giới hạn (hoặc lỗi) trong JBoss; nó hoạt động trong Glassfish và WebLogic, nơi chúng tôi có cùng mã khi chạy.

1

Cùng một vấn đề xảy ra nếu bạn có tệp jar với EJB của bạn nhiều hơn một lần trong EAR của bạn.

mẫu:

Bạn có

  • một file myEJB.jar mà chứa tất cả các EJB bạn
  • một myWebApp.war mà chứa các lớp web của bạn/nguồn
  • một myEnterprise.ear chứa myEJB.jar và myWebApp.jar

Nếu myWebApp của bạn.chiến tranh cũng chứa myEJB.jar bởi bản thân bạn sẽ có lỗi này (ClassCastExc). Dường như đối tượng EJB được tạo bên trong myEJB.jar của myEnterprise.ear. Và nếu bạn sau đó sẽ được đúc đối tượng này vào cùng một lớp của myEJB.jar bên trong myWebApp.war, điều này sẽ không hoạt động vì đây là lớp được định nghĩa trong một jar khác.

Nếu bạn gặp lỗi này, bạn phải xóa tệp myEJB.jar khỏi tệp chiến dịch của mình và ClassCastExc đã biến mất ...

Các vấn đề liên quan