jakarta-ee - Java EE : Proxy cannot be cast to Local Interface, 可能是类加载问题?

标签 jakarta-ee ejb-3.0 classloader

我目前正在“重新安排”我的 Java EE 应用程序,它由三个组件组成:

  • MyAppInterface:主要是 JPA 和 JAXB 注释的 POJO,还有一些 EJB 本地接口(interface)
  • MyAppServer:JPA Facades、EJB、Jersey 资源
  • MyAppWeb:GWT 前端,通过负载均衡器通过 HTTP/REST 与 MyAppServer 通信

MyAppServer 和 MyAppWeb 都使用 MyAppInterface 中定义的类; MyAppServer 通过 MyAppInterface 中的本地接口(interface)“导出”它的一些 EJB。 MyAppInterface 是一种 API,它是您使用 MyAppServer 所需要的。

在 Maven 中,我将 MyAppInterface 打包为 jar,MyAppServer 和 MyAppWeb 都打包为 war,在 compile 范围内依赖于 MyAppInterface .所以 MyAppInterface.jar 最终出现在两个 war 文件中。

当我在同一个 Glassfish 上将两个 war 文件作为单独的应用程序部署时,部署成功。它们之间由 JAXB-Jersey 驱动的通信有效,所以我必须假设这两个应用程序都可以类加载 MyAppInterface。

但在一种情况下,我想从 MyAppWeb 访问 MyAppServer-EJB。通过 InitialContext 的 JNDI 查找有效,但是当我尝试将获得的代理转换为本地接口(interface)时,我得到一个 ClassCast 异常:

com.sun.enterprise.container.common.spi.util.InjectionException: Error creating managed object for class: class com.skalio.bonusapp.web.server.StoreServiceImpl
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:315)
    at com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:717)
    at com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:1959)
...
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:307)
    ... 28 more
Caused by: java.lang.ClassCastException: $Proxy365 cannot be cast to com.skalio.bonusapp.beans.SettingsBeanLocal
    at com.skalio.bonusapp.web.server.StoreServiceImpl.getServerSettings(StoreServiceImpl.java:85)
    at com.skalio.bonusapp.web.server.StoreServiceImpl.(StoreServiceImpl.java:47)
    ... 33 more

Google 让我相信这可能是一个类加载问题,可能与重复包含 MyAppInterface.jar 有关。那是对的吗?你有什么建议?

您将如何分发和打包组件?

注意:目前我想避免创建 EAR,而是保持选择要部署的组件的灵 active ...

最佳答案

是的,对于本地 EJB,接口(interface) JAR 需要位于用于类加载的共享位置。 EJB 规范实际上并不要求本地 EJB 可以跨应用程序(或独立模块)访问,但大多数应用程序服务器使用简单代理实现本地 EJB。

您要么需要将模块打包到 EAR 中,JAR 位于 lib 目录中,要么您需要安排 JAR 由两个应用程序都可见的产品级类加载器加载。

关于jakarta-ee - Java EE : Proxy cannot be cast to Local Interface, 可能是类加载问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7973983/

相关文章:

spring - 在 Apache Tomcat 6 中部署 Spring 2 应用程序时出现问题

java - Glassfish 3.1.2 和 Java EE + Hibernate 的性能非常低

java - 在不使用线程的情况下处理 EJB3 中的超时

java - EJB 3.0 和 future 的方法

java - 在 jsf 中找不到类型的属性

java - 如何使用JSP/Servlet将文件上传到服务器?

java - 继承类注解

java - 魔法值不兼容错误

java - 来自 Hibernate 的同步类加载器调用

java - 在 tomcat root 的 Web 应用程序中找不到 TransformerFactory