2 Replies Latest reply on Mar 9, 2009 2:59 PM by peterj

    servlet init hangs reading /WEB-INF/web.xml 5.0.1

    mlybarger

      I have a very simple servlet which hangs on the servlet init method. Another similar example I have throws an OOM excetpion doing the same thing. All the code is doing is trying to parse the web.xml using the commons digester.

      I hope this isn't too much code to paste. I'm running a default 5.0.1 (same behavior on 5.0.0, but this code runs fine on the 4.2.2 server) server with 1.6.0.11 jdk.

      This code originates from the struts 1.1 ActionServlet. There is a problem with the digester.parse() call. Does this have something to do with VFS perhaps?

      package org.test;
      
      import java.io.IOException;
      import java.io.InputStream;
      import java.net.URL;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      
      import org.apache.commons.digester.Digester;
      import org.apache.commons.logging.Log;
      import org.apache.commons.logging.LogFactory;
      import org.apache.struts.Globals;
      import org.xml.sax.SAXException;
      
      public class TestServlet extends HttpServlet {
      
       public TestServlet() {
       super();
       // TODO Auto-generated constructor stub
       }
      
       protected static Log log = LogFactory.getLog(TestServlet.class);
       protected String registrations[] = {
       "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
       "/org/apache/struts/resources/struts-config_1_0.dtd",
       "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
       "/org/apache/struts/resources/struts-config_1_1.dtd",
       "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
       "/org/apache/struts/resources/web-app_2_2.dtd",
       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
       "/org/apache/struts/resources/web-app_2_3.dtd"
       };
      
       protected String servletMapping = null;
       protected String servletName = null;
      
       /**
       * @see Servlet#init(ServletConfig)
       */
       protected void initServlet() throws ServletException
       {
      
       // Remember our servlet name
       this.servletName = getServletConfig().getServletName();
      
       // Prepare a Digester to scan the web application deployment descriptor
       Digester digester = new Digester();
       digester.push(this);
       digester.setNamespaceAware(true);
       digester.setValidating(false);
      
       // Register our local copy of the DTDs that we can find
       for (int i = 0; i < registrations.length; i += 2) {
       URL url = this.getClass().getResource(registrations[i+1]);
       if (url != null) {
       digester.register(registrations, url.toString());
       }
       }
      
       // Configure the processing rules that we need
       digester.addCallMethod("web-app/servlet-mapping",
       "addServletMapping", 2);
       digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
       digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
      
       // Process the web application deployment descriptor
       if (log.isDebugEnabled()) {
       log.debug("Scanning web.xml for controller servlet mapping");
       }
      
       InputStream input =
       getServletContext().getResourceAsStream("/WEB-INF/web.xml");
      
       try {
       digester.parse(input);
      
       } catch (IOException e) {
       log.error("io error", e);
       throw new ServletException(e);
      
       } catch (SAXException e) {
       log.error("error", e);
       throw new ServletException(e);
      
       } finally {
       if (input != null) {
       try {
       input.close();
       } catch (IOException e) {
       log.error("error", e);
       throw new ServletException(e);
       }
       }
       }
      
       // Record a servlet context attribute (if appropriate)
       if (log.isDebugEnabled()) {
       log.debug("Mapping for servlet '" + servletName + "' = '" +
       servletMapping + "'");
       }
      
       if (servletMapping != null) {
       getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);
       }
      
       }
      
       public void init() throws ServletException {
       log.info("start - init()");
       initServlet();
       log.info("done - init()");
       }
      
       }
      


      web.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
      <web-app>
       <display-name>jbtest</display-name>
       <servlet>
       <servlet-name>ActionServlet</servlet-name>
       <servlet-class>org.test.TestServlet</servlet-class>
       <load-on-startup>-1</load-on-startup>
       </servlet>
       <servlet-mapping>
       <servlet-name>ActionServlet</servlet-name>
       <url-pattern>/do/eforms-client</url-pattern>
       </servlet-mapping>
      </web-app>
      


      It's been over 5 minutes sitting there with the cpu spiked and the init method didn't finish. My log only shows the start log, not the stop.


        • 1. Re: servlet init hangs reading /WEB-INF/web.xml 5.0.1
          mlybarger

          ok, finally an exception was thrown. here's the stack

          07:49:36,529 INFO [TestServlet] start - init()
          08:01:21,136 WARN [ClassLoaderManager] Unexpected error during load of:org.xml.sax.XMLReader
          java.lang.OutOfMemoryError: Java heap space
           at java.util.zip.InflaterInputStream.<init>(InflaterInputStream.java:71)
           at java.util.zip.ZipFile$1.<init>(ZipFile.java:212)
           at java.util.zip.ZipFile.getInputStream(ZipFile.java:212)
           at java.util.zip.ZipFile.getInputStream(ZipFile.java:180)
           at org.jboss.virtual.plugins.context.zip.ZipFileWrapper.openStream(ZipFileWrapper.java:214)
           at org.jboss.virtual.plugins.context.zip.ZipEntryContext.openStream(ZipEntryContext.java:1066)
           at org.jboss.virtual.plugins.context.zip.ZipEntryHandler.openStream(ZipEntryHandler.java:153)
           at org.jboss.virtual.VirtualFile.openStream(VirtualFile.java:230)
           at org.jboss.classloading.spi.vfs.policy.VFSClassLoaderPolicy.getResourceAsStream(VFSClassLoaderPolicy.java:483)
           at org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:508)
           at org.jboss.classloader.spi.base.BaseClassLoader$2.run(BaseClassLoader.java:506)
           at java.security.AccessController.doPrivileged(Native Method)
           at org.jboss.classloader.spi.base.BaseClassLoader.loadClassLocally(BaseClassLoader.java:504)
           at org.jboss.classloader.spi.base.BaseClassLoader.loadClassLocally(BaseClassLoader.java:481)
           at org.jboss.classloader.spi.base.BaseDelegateLoader.loadClass(BaseDelegateLoader.java:134)
           at org.jboss.classloader.spi.filter.FilteredDelegateLoader.loadClass(FilteredDelegateLoader.java:131)
           at org.jboss.classloader.spi.base.ClassLoadingTask$ThreadTask.run(ClassLoadingTask.java:452)
           at org.jboss.classloader.spi.base.ClassLoaderManager.nextTask(ClassLoaderManager.java:258)
           at org.jboss.classloader.spi.base.ClassLoaderManager.process(ClassLoaderManager.java:152)
           at org.jboss.classloader.spi.base.BaseClassLoaderDomain.loadClass(BaseClassLoaderDomain.java:259)
           at org.jboss.classloader.spi.base.BaseClassLoaderDomain.loadClass(BaseClassLoaderDomain.java:1102)
           at org.jboss.classloader.spi.base.BaseClassLoader.loadClassFromDomain(BaseClassLoader.java:772)
           at org.jboss.classloader.spi.base.BaseClassLoader.loadClass(BaseClassLoader.java:415)
           at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
           at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
           at org.apache.commons.digester.Digester.getXMLReader(Digester.java:905)
           at org.apache.commons.digester.Digester.parse(Digester.java:1567)
           at org.test.TestServlet.initServlet(TestServlet.java:76)
           at org.test.TestServlet.init(TestServlet.java:111)
           at javax.servlet.GenericServlet.init(GenericServlet.java:212)
           at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1048)
           at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:777)
          
          


          • 2. Re: servlet init hangs reading /WEB-INF/web.xml 5.0.1
            peterj

            Looks like a possible bug in VFS - it appears that it could be unpacking the war file multiple times while the Digester is parsing the web.xml.

            Is the serer/xxx/temp directory filling up?

            Taking some thread dumps while the CPU usage is at 100% might shed some light on what it is doing because it is apparently looping somewhere.

            Does the same thing happen if you deploy the WAR as an exploded directory?

            Since this is something that worked in 4.2.x but is broke in 5.0, you might want to post a question in the JossAS5 forum linking back to this topic.