views:

648

answers:

3

I'm currently migrating a Spring application from the JBoss J2EE container to Sun's Glassfish J2EE container and although it is the same code, I am getting a confusing error during a specific point in my application. The error occurs every time my controller redirects (using the redirect keyword) to a page handled by spring web flow. I've edited the jsp that should be rendered so that it is simply test text (and therefore I can't imagine my error is coming from JSP compilation). I've posted the stack trace pulled from my server log below. Due to the fact that none of my own classes are in the stack trace at all I'm not sure what other information would be useful for me to post. I should mention that I do not get this error at all in JBoss

[#|2010-01-15T14:59:06.334-0500|SEVERE|sun-appserver2.1|javax.enterprise.system.container.web|_ThreadID=18;_ThreadName=httpSSLWorkerThread-8080-3;_RequestID=ee69c2b0-30df-437f-ab22-fd8777dbf826;|StandardWrapperValve[burq]: PWC1406: Servlet.service() for servlet burq threw exception
java.lang.NullPointerException
    at org.apache.jsp.WEB_002dINF.jsp.exception_jsp._jspService(exception_jsp.java:33)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:333)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at com.sun.identity.agents.filter.AmAgentBaseFilter.allowRequestToContinue(AmAgentBaseFilter.java:126)
    at com.sun.identity.agents.filter.AmAgentBaseFilter.doFilter(AmAgentBaseFilter.java:75)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:873)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:723)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:558)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:490)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:382)
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:240)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:252)
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1173)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:901)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:333)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at com.sun.identity.agents.filter.AmAgentBaseFilter.allowRequestToContinue(AmAgentBaseFilter.java:126)
    at com.sun.identity.agents.filter.AmAgentBaseFilter.doFilter(AmAgentBaseFilter.java:75)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:246)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:313)
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
    at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
    at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
    at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
    at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
    at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
    at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
|#]

It appears the error is coming from the following call in the generated exception_jsp.java file:

response.setStatus(((Integer)request.getAttribute("javax.servlet.error.status_code")).intValue());

Here is the full exception_jsp.java file that is causing the null pointer:

package org.apache.jsp.WEB_002dINF.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.Transport;
import java.util.Properties;
import org.apache.commons.lang.exception.ExceptionUtils;

public final class exception_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.Vector _jspx_dependants;

  private org.apache.jasper.runtime.ResourceInjector _jspx_resourceInjector;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);
    response.setStatus(((Integer)request.getAttribute("javax.servlet.error.status_code")).intValue());
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html");
      response.setHeader("X-Powered-By", "JSP/2.1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;
      _jspx_resourceInjector = (org.apache.jasper.runtime.ResourceInjector) application.getAttribute("com.sun.appserv.jsp.resource.injector");

      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("<html lang=\"en\">\r\n");
      out.write("\r\n");
      out.write("\t<head>\r\n");
      out.write("\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"/j2ee/shared/css/common.css\" />\r\n");
      out.write("\t\t<script type=\"text/javascript\" language=\"javascript\" src=\"/j2ee/shared/js/base.js\"></script>\r\n");
      out.write("\t</head>\t\t\r\n");
      out.write("\t\r\n");
      out.write("\t<body>\r\n");
      out.write("\t\t<h1 title=\"BSS Update Retrieval and Query System 1.0.0\">BSS Update Retrieval and Query System</h1>\r\n");
      out.write("\t\t\t\r\n");
      out.write("\t      ");

          try {
            Throwable ex = exception;
            if(ex == null){
                ex = ((Exception) request.getAttribute("exception"));
            }
            out.println("<p class='exception'>");
            out.println("An error occured while running the BSS Update Request and Query system:- " + "<br/>");
            out.println(ex.getMessage() + "<br/>");
            out.println("Please contact " +"<a href='mailto:[email protected]'>Sequencing Support</a>" + " for help.");
            out.println("</p>");

            out.println("<br><div style='display:none'>" + ExceptionUtils.getFullStackTrace(ex) + "</div><br/>");
            Message message = new MimeMessage(Session.getInstance(new Properties()));
            message.addRecipients(Message.RecipientType.TO, InternetAddress.parse("[email protected],[email protected]"));
            message.addFrom(InternetAddress.parse("[email protected]"));
            message.setSubject("Error - BSS Update Request and Query system");
            StringBuffer content = new StringBuffer();
            content.append("An exception occured while running the BSS Update Request and Query system: " + "\n");
            content.append(ExceptionUtils.getFullStackTrace(ex));
            message.setText(content.toString());
            Transport.send(message);
          }
          catch(Exception e){
              out.println(e.getMessage());
          }

      out.write("\r\n");
      out.write("\t</body>\t\t\t\t\r\n");
      out.write("</html>\r\n");
      out.write("\r\n");
      out.write("\r\n");
      out.write("\r\n");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          out.clearBuffer();
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}
+1  A: 
response.setStatus(((Integer)request.getAttribute("javax.servlet.error.status_code")).intValue());

this line is causing the problem. comment it out and try outputting the value of request.getAttribute("javax.servlet.error.status_code") (without casting or intValue())

It is perhaps null

javax.servlet.error.status_code is only set if there has been an error. So if you are redirecting to the exception.jsp yourself, and not using it as an error-page, then there is no status code set, and hence - the NullPointerException

Bozho
what made you downvote it? What have I missed / written wrong?
Bozho
while that's correct, he has only identified the line (by the stacktrace), not the fact that this part of the row returns null. And I'm sure you've noticed that NPE is not always well understood.
Bozho
+1  A: 

Is that jsp page set as error page?

<web-app>
<!-- ..... -->
<error-page>
    <error-code>
        404
    </error-code>
    <location>
        /404.html
    </location>
</error-page>
<error-page>
    <exception-type>
        javax.servlet.ServletException
    </exception-type>
    <location>
        /servlet/ErrorDisplay
    </location>
</error-page>
<!-- ..... -->

A servlet in the for an rule could receive the following three attributes:

* javax.servlet.error.status_code : An Integer telling the error status code, if any
* javax.servlet.error.exception_type : A Class instance indicating the type of exception that caused the error, if any
* javax.servlet.error.message : A String telling the exception message, passed to the exception constructor
Teja Kantamneni
+2  A: 

With GlassFish, the line:

response.setStatus(((Integer)request.getAttribute("javax.servlet.error.status_code")).intValue());

is automatically generated by the JSP compiler for any JSP that has:

<%@page isErrorPage="true"%>

Here, for an unknown reason, the "javax.servlet.error.status_code" request attribute is not set or lost during the redirect so using <%@page isErrorPage="true"%> results in the NPE. This may be a bug in your code, in GlassFish, or in Sping (or not at all), but it is impossible to say without more details on your page flow, on your code.

There is a discussion in this thread about a very similar problem (similar, not identical, the root cause is not the same IMO) though. The suggested workaround is to not use the isErrorPage directive and to use the following EL code to access the error information:

${pageContext.errorData.throwable}
${pageContext.errorData.statusCode}
${pageContext.errorData.requestURI}
${pageContext.errorData.servletName}

As I said, I can't say if this is a bug in GlassFish, in Spring, or not a bug at all. But maybe open a ticket in GlassFish issue tracking system anyway. You may get a more precise answer (and help the community).

Pascal Thivent
While technically this wasn't the "answer" to my problem, this answer did provide the background to better understand how I might troubleshoot my issue. This, coupled with the above idea to turn my logging to 'debug' led me to find the bug in my Java code that was causing this.
TimmyJ