[ http://issues.apache.org/jira/browse/MYFACES-1148?page=comments#action_12367216 ]
Adam Brod commented on MYFACES-1148: ------------------------------------ Ok, I did some additional debugging into the Weblogic ClassLoader. The root of the problem stems from the weblogic Weblogic drops the classloader and then reinitiales the webapp. 1) Weblogic calls destroy() on FacesServlet (old classloader) 2) Weblogic takes all of the variables in the ServletContext. serializes them and then deserializes them into the new classloader 3) Weblogic calls init() on FacesServlet (new classloader) Since none of the JSF objects that are stored in the ServletContext are serializable, weblogic just silently deletes them. That's why FacesServlet.init() throws the IllegalStateException - it can't find any of the variables that were set up by the StartupServletContextListener since they didn't make the transition to the new classloader. >From what I know, I only see a few options: 1) Make all of the objects stored in the ServletContext serializable 2) Put in a hook in FacesServlet.init() such that if the factories aren't there, it reloads them 3) Put some other ServletContextListener or ServletContextAttributeListener(s) to listen for events and reload the factories 4) Put some ServletFilter in that before any Faces request is processed checks to ensure everything is initialized. If it is initialized, then it does nothing. Otherwise, it initializes the required objects. I have a hacked together version of this working so-so in my local dev env now. I'm not sure of the best way is to move forward on this issue. It is obviously very tricky and could get very messy with all of this Weblogic-Servlet-specific initialization code. However, since Weblogic is a major appserver, I really hope the issue won't be dropped. > Weblogic Classloader problems during development (FactoryFinder) > ---------------------------------------------------------------- > > Key: MYFACES-1148 > URL: http://issues.apache.org/jira/browse/MYFACES-1148 > Project: MyFaces Core > Type: Bug > Components: Implementation > Versions: 1.1.1 > Environment: Weblogic 9.0, 8.1, etc. Windows XP Pro sp2. > Reporter: Adam Brod > > Like most weblogic users, our team develops using the exploded war format. > That means that each time we deploy a new version of a class, weblogic > automatically picks it up. The way Weblogic implements this is that when it > detects a new class, it drops the classloader for that class, as well as the > Servlet and all helper classes that are loaded by the Servlet. That means > FacesServlet is dropped and reloaded. > The problem is that FactoryFinder stores the Factory classes in a Map where > the key is the current classloader. That works fine until I deploy a new > class to my webapp. At that point, weblogic drops the classloader and > creates a new one with the new class definition. Now when > FacesServlet.init() calls FactoryFinder.getFactory() (in the new > classloader), an IllegalStateException is generated (see below) because the > current classloader is not a valid key for the _registeredFactoryNames Map. > One possible solution that I can see to this is to change the key for the > Factory map to use the ServletContext's getServletContextName() as the key. > I am 95% sure this same problem exists in Weblogic 7.0, 8.1 and 9.1 since > they all use almost the same Servlet redeployment mechanism. I have only > tried this on Weblogic 9.0. > <Feb 20, 2006 5:38:07 PM EST> <Error> <HTTP> <BEA-101017> <[EMAIL PROTECTED] > - name: 'ma-web-1.0-SNAPSHOT > ', context-path: '/ma'] Root cause of ServletException. > java.lang.IllegalStateException: No Factories configured for this Application > - typically this is because a context listener is not setup in yo > ur web.xml. > A typical config looks like this; > <listener> > > <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class> > </listener> > at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:84) > at javax.faces.webapp.FacesServlet.init(FacesServlet.java:84) > at > weblogic.servlet.internal.StubSecurityHelper$ServletInitAction.run(StubSecurityHelper.java:265) > at > weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) > at > weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121) > at > weblogic.servlet.internal.StubSecurityHelper.createServlet(StubSecurityHelper.java:61) > at > weblogic.servlet.internal.StubLifecycleHelper.createOneInstance(StubLifecycleHelper.java:58) > at > weblogic.servlet.internal.StubLifecycleHelper.<init>(StubLifecycleHelper.java:48) > at > weblogic.servlet.internal.ServletStubImpl.prepareServlet(ServletStubImpl.java:502) > at > weblogic.servlet.internal.ServletStubImpl.checkForReload(ServletStubImpl.java:429) > at > weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:221) > at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26) > at > weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42) > at > oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._invokeDoFilter(AdfFacesFilterImpl.java:367) > at > oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl._doFilterImpl(AdfFacesFilterImpl.java:336) > at > oracle.adfinternal.view.faces.webapp.AdfFacesFilterImpl.doFilter(AdfFacesFilterImpl.java:196) > at > oracle.adf.view.faces.webapp.AdfFacesFilter.doFilter(AdfFacesFilter.java:87) > at > weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42) > at > org.apache.myfaces.component.html.util.ExtensionsFilter.doFilter(ExtensionsFilter.java:122) > at > weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42) > at > weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3020) > at > weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321) > at > weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121) > at > weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:1925) > at > weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:1848) > at > weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1288) > at weblogic.work.ExecuteThread.execute(ExecuteThread.java:207) > at weblogic.work.ExecuteThread.run(ExecuteThread.java:179) > > -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira
