在 AS7 中转换查找的 EJB 视图时出现 ClassCastException

发布于 2024-12-02 14:25:10 字数 7890 浏览 6 评论 0原文

我正在将 2 个 EAR 部署到 JBoss AS 7.1.0.Alpha1-SNAPSHOT(7.0.1.Final 版本之后)。两者都部署得很好。

我有一个 EJB Singleton 类打包在一个 JAR 中,在一个 EAR 中:

@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 从其他部署的 EAR 内的 JAR 内的非 CDI、非 EJB 类中查找它时,它只能在“全局”下的 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 名称的组合以及是否转换为 Store 或 StoreFront 似乎也没有什么区别 - 无法转换任何组合,即使异常类似于 jam.store.core.Store$$$ view1 无法转换为 jam.store.core.Store,具有匹配的(基)类名

有人能指出我做错了什么吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

遮了一弯 2024-12-09 14:25:10

这是 AS7 中的错误: https://issues.jboss.org/browse/AS7-1658

一种可能的解决方法是不强制转换返回的对象,然后使用它通过 反射。不过很笨重。

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.

瑾兮 2024-12-09 14:25:10

更好的方法是在 jboss 模块中部署共享接口,并将该模块包含在两个工件的类路径中(使用 maven 时)

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

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>
两相知 2024-12-09 14:25:10

我还获得了有关此评论的帮助;):

David Lloyd 添加了一条评论 - 2012 年 3 月 7 日下午 4:02
这是因为您使用的是本地接口。使用本地接口时,您可能只有接口类的一份副本(这就是它本地化的原因)。切换到使用远程接口(或者,使用类路径来获取本地接口而不是复制它们),问题就会消失。

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.

哆啦不做梦 2024-12-09 14:25:10

我遇到了同样的问题;尝试将 Interface 类作为单独的模块并将其包含在一个 Ear 中,并将其作为提供的包含在另一个 Ear 中;
在 JBOSS 中,每个 EAR 中的类由单独的类加载器加载。因此,如果一个 EAR 具有 A 类,而另一个 EAR 具有相同的 A 类,则会出现类转换异常。因此,在第二个 EAR 中给出所提供的依赖项,并在 jboss-deployment-struction.xml 中添加第一个 EAR 作为模块依赖项。请注意,动态模块依赖性可能保证 EAR 文件名保持不变;您可以在 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:app 更改为 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");

并且由于 Ear 通常是使用这样的版本注册的

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

,并且您不希望在代码中进行版本驱动的查找,因此您还需要做两件事。在 EAR 构建器 maven 目录 (src\main\resources\application.xml) 的 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 中添加“application-name”标签,如 和 来生成您需要提供对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

I was getting the same problem; Tried to put the Interface class as a sperate module and include it in one Ear and include it as a provided in the other Ear;
In JBOSS the classes in each EAR are loaded by a separate class loader. So if one EAR has Class A , and another has the same Class A , then you get a class cast exception. So in the second EAR give the dependency as provided and in jboss-deployment-structure.xml add the first EAR as a module dependency. Note that the dynamic module dependency might warrant the EAR file name to be constant; You can specify <finalName> under the build tag for the EAR file to fix this

Also changed the lookup from local to remote - see below, and included the maven module containing the interface in both the modules

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

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

And you would want to change the lookup from java:app to 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");

And since the Ear is usually registered with the version like this

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

and you do not want version driven lookup in your code, you need to do two more things. In your application.xml in your EAR builder maven dir (src\main\resources\application.xml) you need to add the "application-name" tag like

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

and in your pom to generate the pom you need to provide a reference to the application.xml like

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

Here is the stack trace for reference

java.lang.ClassCastException: com.package.TaskSplitterItf$$view210 cannot be cast to com.package.TaskSplitterItf
空城旧梦 2024-12-09 14:25:10

如果您的 EJB 中的 jar 文件在 EAR 中多次存在,则会出现同样的问题。

示例:

您有

  • 一个 myEJB.jar 文件,其中包含所有 EJB
  • a myWebApp.war,其中包含您的 Web 类/资源
  • a myEnterprise.ear,其中包含 myEJB.jar 和 myWebApp.jar

如果您的 myWebApp.war 还包含 myEJB.jar如果你自己的话,你会遇到这个错误(ClassCastExc)。似乎 EJB 对象是在 myEnterprise.ear 的 myEJB.jar 内创建的。如果您随后将此对象转换为 myWebApp.war 内的 myEJB.jar 的同一类,则这将不起作用,因为该类是在另一个 jar 中定义的。

如果出现此错误,则必须从 war 文件中删除 myEJB.jar,并且 ClassCastExc 会消失...

Same Problem occurred if you have the jar file with your EJBs more as one time in your EAR.

Sample:

You have

  • a myEJB.jar file which contains all of your EJB
  • a myWebApp.war which contains your web classes / resources
  • a myEnterprise.ear which contains myEJB.jar and myWebApp.jar

If your myWebApp.war also contains the myEJB.jar by self then you will have this error (ClassCastExc). Seems that the EJB object is created inside the myEJB.jar of the myEnterprise.ear. And if you then will be cast this object into the same class of the myEJB.jar inside of the myWebApp.war this will not worked because this is class is defined in another jar.

If you have this error you must remove the myEJB.jar from your war file and the ClassCastExc is gone ...

海夕 2024-12-09 14:25:10

如果您的 EJB 客户端位于 EAR 中并且 EJB 实现位于另一个“服务”-EAR 中,并且您在 EJB 上调用 @Remote Interface 方法返回复杂对象而不是原始类型,那么也会出现同样的问题。返回的复杂对象也被声明为接口,正确声明、已知并可供 EJB 客户端使用。返回的对象实现也与目标 EJB 实现一起包含在“服务”-EAR 中。
尽管有这样的一致代码,JBoss 在类转换异常上失败了。

我注意到,您确实可以保留 @Remote 接口来声明所有目标 EJB 方法,但只能对这些方法返回的所有对象使用普通类声明。如果将返回的对象声明为接口,则 JBoss 中会发生类转换异常。

这是 JBoss 中的一个限制(或错误);它确实可以在 Glassfish 和 WebLogic 中运行,我们在其中运行时具有相同的代码。

Same issue too if your EJB-client is in an EAR and the EJB implementation in another "service"-EAR, and you invoke a @Remote Interface method on the EJB returning a complex Object instead of a primitive type. The complex Object being returned is also declared as an Interface, properly declared, known, and available to the EJB-client. The returned Object implementation is, it, contained in the "service"-EAR along with the target EJB implementation too.
Despite such conformant code, JBoss fails on Class cast exception.

I noted that you can indeed keep a @Remote Interface for declaring all target EJB methods, but can only use a plain class declaration for all the Objects returned by those methods. If you declare the returned Objects as Interfaces, Class cast exceptions ensue in JBoss.

This is a limitation (or bug) in JBoss; it does work in Glassfish and WebLogic where we had the same code once running.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文