Glassfish JSP空指针异常

时间:2010-01-15 20:11:25

标签: spring glassfish

我目前正在将Spring应用程序从JBoss J2EE容器迁移到Sun的Glassfish J2EE容器,尽管它是相同的代码,但我在应用程序的特定点上遇到了一个令人困惑的错误。每次我的控制器重定向(使用redirect关键字)到spring web flow处理的页面时,都会发生错误。我已经编辑了应该呈现的jsp,因此它只是测试文本(因此我无法想象我的错误来自JSP编译)。我已经发布了从我的服务器日志中提取的堆栈跟踪。由于我自己的类都没有在堆栈跟踪中,所以我不确定其他哪些信息对我来说是有用的。我应该提一下,我在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)
|#]

看来错误来自生成的exception_jsp.java文件中的以下调用:

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

以下是导致空指针的完整exception_jsp.java文件:

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:seqsupport@fstrf.org'>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("seqsupport@fstrf.org,seqdev@fstrf.org"));
            message.addFrom(InternetAddress.parse("fstrf.labdivprgmng@fstrf.org"));
            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);
    }
  }
}

3 个答案:

答案 0 :(得分:4)

使用GlassFish,行:

response.setStatus(((Integer)request.getAttribute("javax.servlet.error.status_code")).intValue());
JSP编译器会自动为任何具有以下内容的JSP生成

<%@page isErrorPage="true"%>

此处,由于未知原因,在重定向期间未设置或丢失"javax.servlet.error.status_code"请求属性,因此使用<%@page isErrorPage="true"%>会导致NPE。这可能是您的代码,GlassFish或Sping中的错误(或根本不存在),但如果没有关于页面流的更多详细信息,则无法说明您的代码。

this thread中讨论了一个非常相似的问题(类似,不相同,根本原因不是相同的IMO)。建议的解决方法是不使用isErrorPage指令并使用以下EL代码来访问错误信息:

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

正如我所说,我不能说这是GlassFish中的错误,在Spring中,还是根本不是bug。但无论如何,也许在GlassFish问题跟踪系统中打开ticket。您可以获得更准确的答案(并帮助社区)。

答案 1 :(得分:2)

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

此行导致问题。将其注释掉并尝试输出值 request.getAttribute("javax.servlet.error.status_code")(未投出或intValue()

可能是null

仅在出现错误时才设置

javax.servlet.error.status_code。因此,如果您自己重定向到exception.jsp,而不是将其用作错误页面,则没有设置状态代码,因此 - NullPointerException

答案 2 :(得分:1)

该jsp页面是否设置为错误页面?

<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>
<!-- ..... -->

规则中的servlet可以接收以下三个属性:

* 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