2016-10-04 2 views
1

Wir aktualisieren eine J2EE-Anwendung (EJB 2.0) von WebLogic Service 8.1 auf 12c (12.2.1.1.0). Wir erstellen eine explodierte EAR in einem Verzeichnis im Domänenverzeichnis. Eine Webanwendung (struts) führt eine Suche in JNDI durch und erhält eine Referenz auf eine EJB und gibt eine Home-Klasse zurück. Das Problem, das wir haben, ist, dass es nicht auf die Schnittstelle umgewandelt werden kann.WebLogic-Klasse auf EJB-Home-Schnittstelle

Mit Reflection können wir sehen, dass die zurückgegebene Klasse die erwartete Schnittstelle implementiert, aber es wirft immer eine java.lang.ClassCastException, wenn wir versuchen, es zu werfen.

Die Arbeitstheorie ist, dass ein Klassenladeprogramm verwendet wird, um die EJBs im Container zu unterstützen, und ein anderer nicht relatiertes Klassenladeprogramm die Servlets bedient, sodass die zurückgegebene Klasse nicht von einem anderen Klassenladeprogramm in die Interface-Klasse umgewandelt werden kann. Wir können dies nicht bestätigen, aber wir vermuten, dass die Hierarchie der Klassenlader zwischen WLS 8.1 und 12c geändert wurde. Wenn das der Fall ist, können wir keinen Weg finden.

Wir haben begonnen, das WebLogic Classloader Analysis Tool zu verwenden, aber es zeigt keine Probleme mit irgendeiner Klasse an, die in diesem speziellen Fall beteiligt ist.

Die Kernfrage ist, was wir ändern müssen, damit der Cast wie WebLogic 8.1 funktioniert, damit wir den vorhandenen Code nicht umstrukturieren können?

Um klar zu sein, funktioniert der Code in WebLogic Server 8.1, aber nicht in WebLogic Server 12c. Die EJB-Deployment-Deskriptoren wurden mit weblogic.DDConverter aktualisiert, aber dieses Problem trat auch vor der Konvertierung auf.

Dies ist, wie wir die EJB in der JndiHelper Klasse Lookup (dies funktioniert mit 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; 
} 

Hier ist der Code, der die oben ruft, macht die Besetzung und Diagnoseinformationen druckt, wenn es scheitert :

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()))); 
} 

Hier ist ein Beispiel für die angezeigten Diagnoseinformationen. Beachten Sie die Vererbungsliste enthält Typen und Schnittstellen mit dem Suffix "(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:[email protected] 
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) 

In unserer WEB-INF \ weblogic.xml haben wir folgendes:

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

Jede Hilfe wäre sehr geschätzt.

Antwort

0

Wir lösen dieses Problem, indem <prefer-application-packages> von weblogic.xml zu entfernen, die die weblogic.utils.classloaders.ChangeAwareClassLoader verursacht wurde seine eigene Version der Schnittstelle zusammen mit seinen Eltern die weblogic.utils.classloaders.GenericClassLoader, die die Anwendung unterstützt zu laden. Da die Webanwendung versuchte, auf eine Version der Schnittstelle zu konvertieren, die nicht mit der in der EJB durch einen anderen Klassenlader aufgelösten Version übereinstimmte, war die Umwandlung nicht zulässig.

Verwandte Themen