使用反射,我们可以看到返回的类确实实现了预期的接口,但当我们尝试强制转换时,它总是抛出java.lang.ClassCastException。
工作原理是,一个类加载器用于支持容器中的EJB,另一个不相关的类加载者为servlet提供服务,因此返回的类不能从另一个类加载程序转换到接口类中。我们无法确认这一点,但我们怀疑类加载器层次结构在WLS 8.1和12c之间发生了变化。如果是这样的话,我们就找不到解决办法。
我们已经开始使用WebLogic类加载器分析工具,但它并没有指出与此特定情况有关的任何类的问题。
要明确的是,该代码在WebLogic Server 8.1中工作,但在WebLogicServer 12c中不工作。EJB部署描述符已使用weblogic进行了更新。DDConverter,但我们在转换之前也遇到了这个问题。
这是我们在JndiHelper类中查找EJB的方式(这适用于WLS8):
public static EJBHome getHome( String ejbHomeName ) throws NamingException {
EJBHome home = null;
String sENCHome = JNDI_ENC_EJB_CONTEXT + "/" + ejbHomeName;
Object objRef = new InitialContext().lookup( sENCHome );
home = (EJBHome)PortableRemoteObject.narrow( objRef, EJBHome.class );
return home;
}
下面是调用上述代码、进行cast并在失败时打印诊断信息的代码:
EJBHome home = null;
try {
home = JndiHelper.getHome( JndiConstants.USER_HANDLER_EJB );
UserHandlerHome userHandlerHome = (UserHandlerHome)home; // throws class cast exception here
UserHandler userHandler = userHandlerHome.create();
adminInd = userHandler.isAdmin( userId );
} catch ( ClassCastException e ) {
StringBuffer b = new StringBuffer( "ClassCastException: " );
b.append( e.getMessage() );
b.append( "\r\nThe JNDI lookup for '" );
b.append( JndiConstants.USER_HANDLER_EJB );
b.append( "' returned a bean of unexpected type.\r\nValue:" );
b.append( home );
b.append( "\r\nReturned bean's inheritance:\r\n" );
b.append( Reflector.getInheritanceDump( home ) );
b.append( "\r\n" );
b.append( UserHandlerHome.class.getName() );
b.append( " expected.\r\nFull Stack Trace:\r\n" );
b.append( ExceptionUtil.stackTrace( e ) );
Logger.error( this, b.toString() );
errors.add( ActionErrors.GLOBAL_ERROR, new WebActionError( MessageConstants.NON_DESCRIPT_ERROR, WebActionError.makePopUp( b.toString() ) ) );
}
以下是显示的诊断信息示例。注意继承列表包含后缀为“(I)”的类型和接口:
ERROR com.myapp.admin.controller.UserHelper - ClassCastException: com.myapp.admin.model.UserHandler_8cwrmw_HomeImpl cannot be cast to com.myapp.admin.model.UserHandlerHome
The JNDI lookup for 'UserHandler' returned a bean of unexpected type.
Value:com.myapp.admin.model.UserHandler_8cwrmw_HomeImpl@5f938f12
Returned bean's inheritance:
com.myapp.admin.model.UserHandler_8cwrmw_HomeImpl
weblogic.ejb.container.internal.StatelessEJBHome
weblogic.ejb.container.internal.BaseEJBHome
java.lang.Object
weblogic.ejb.container.interfaces.BaseEJBRemoteHomeIntf(I)
weblogic.ejb.container.interfaces.BaseEJBHomeIntf(I)
weblogic.ejb.spi.BaseEJBHomeIntf(I)
weblogic.ejb20.interfaces.RemoteHome(I)
javax.ejb.EJBHome(I)
java.rmi.Remote(I)
weblogic.ejb.spi.RemoteHome(I)
weblogic.rmi.SupportsInterfaceBasedCallByReference(I)
com.myapp.admin.model.UserHandlerHome(I)
com.myapp.admin.model.UserHandlerHome expected.
Full Stack Trace:
java.lang.ClassCastException: com.myapp.admin.model.UserHandler_8cwrmw_HomeImpl cannot be cast to com.myapp.admin.model.UserHandlerHome
at com.myapp.admin.controller.UserHelper.isAdmin(UserHelper.java:82)
at com.myapp.framework.controller.login.LoginAction.doAction(LoginAction.java:278)
at com.myapp.framework.controller.AfgAction.perform(AfgAction.java:268)
at org.apache.struts.action.ActionServlet.processActionPerform(ActionServlet.java:1888)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1654)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:526)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3679)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3649)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2433)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2281)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2259)
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1686)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1646)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:640)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:406)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
在WEB-INF\weblogic中。xml我们有以下内容:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app>
<jsp-descriptor>
<keepgenerated>true</keepgenerated>
<backward-compatible>true</backward-compatible>
</jsp-descriptor>
<container-descriptor>
<prefer-application-packages>
<!-- Resolves finding Log4J classes (Issue T9) -->
<package-name>org.apache.log4j.*</package-name>
<package-name>org.apache.log4j.pattern.*</package-name>
<package-name>org.apache.log4j.net.*</package-name>
<package-name>org.apache.log4j.jmx.*</package-name>
<package-name>org.apache.log4j.jdbc.*</package-name>
<package-name>org.apache.log4j.helpers.*</package-name>
<package-name>org.apache.log4j.config.*</package-name>
<!-- Recommended by the Classloader Analysis Tool to resolve reported conflicts -->
<package-name>com.myapp.admin.*</package-name>
<package-name>com.myapp.framework.*</package-name>
<package-name>com.myapp.om.*</package-name>
<package-name>com.sun.mail.*</package-name>
<package-name>javax.mail.*</package-name>
<package-name>javax.mail.event.*</package-name>
<package-name>javax.mail.internet.*</package-name>
<package-name>javax.mail.search.*</package-name>
<package-name>javax.wsdl.*</package-name>
<package-name>javax.wsdl.extensions.*</package-name>
<package-name>javax.wsdl.factory.*</package-name>
<package-name>javax.wsdl.xml.*</package-name>
<package-name>javax.xml.rpc.*</package-name>
<package-name>org.apache.commons.*</package-name>
</prefer-application-packages>
</container-descriptor>
</weblogic-web-app>
任何帮助都将不胜感激。