我目前正在“重新安排”我的Java EE应用程序,它由三个组件组成:
MyAppServer和MyAppWeb都使用MyAppInterface中定义的类; MyAppServer通过MyAppInterface中的本地接口“导出”其部分EJB。 MyAppInterface是一种API,它是您使用MyAppServer所需要的。
在Maven中我将MyAppInterface打包为jar
,MyAppServer和MyAppWeb都打包为war
,依赖于compile
范围内的MyAppInterface。所以MyAppInterface.jar最终都出现在两个war文件中。
当我将两个war文件作为单独的应用程序部署在同一Glassfish上时,部署成功。它们之间的JAXB-Jersey驱动的通信工作,所以我必须假设两个应用程序都可以加载MyAppInterface。
但在一个案例中,我想从MyAppWeb访问MyAppServer-EJB。通过InitialContext
进行的JNDI查找有效,但是当我尝试将获得的代理强制转换为本地接口时,我得到了一个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,而是保持灵活选择要部署的组件......
答案 0 :(得分:1)
是的,对于本地EJB,接口JAR需要位于用于类加载的共享位置。 EJB规范实际上不需要跨应用程序(或独立模块)访问本地EJB,但大多数应用程序服务器使用简单代理实现本地EJB。
您需要在EAR中将模块打包到lib目录中的JAR,或者您需要安排JAR由两个应用程序都可见的产品级类加载器加载。