我目前正在“重新安排”我的 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/