【问题标题】:Java EE and JSF NullPointerExceptionJava EE 和 JSF NullPointerException
【发布时间】:2014-02-10 21:54:10
【问题描述】:

我正在尝试创建一个超级简单的 Web 应用程序,其中包含在 Apache TomEE 上运行的 Java EE 日志记录。这样做时,我在我认为是一个愚蠢的简单页面上遇到了归因于 java.lang.NullPointerException 的 javax.servlet.ServletException。

一些系统和库信息:

- CentOS 6.5
- Eclipse Kepler IDE for Java EE Developers
- JRE System Library [java-1.7.0-openjdk-1.7.0.45.x86_64]
- Apache Tomcat v7.0
- Apache TomEE 1.6.0 JAX-RS
- JSF Mojara 2.2 (javax.faces.jar)
- log4j 1.2.17 (log4j-1.2.17.jar)

非常简单的页面(home.xhtml):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>LogTest Home</title>
    </h:head>

    <h:body>
        <h1>Testing:</h1>
        <h:outputText value="#{logTest.foo()}"/>
    </h:body>
</html>

支持 bean (logTest.java):

package test.pack;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.apache.log4j.Logger;

@ManagedBean(name="logTest")
@SessionScoped
public class logTest {

    private static final Logger LOGGER = Logger.getLogger(logTest.class);

    private String statusMsg = "Default status";

    public String getStatusMsg() {
        return statusMsg;
    }

    public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
    }

    public String foo() {
        LOGGER.info("Currently executing method foo()");
        setStatusmsg("Hello foo()!");
        return "foo() executed successfully!";
    }
}

/WEB-INF/classes目录下的log4j.properties文件

log4j.rootLogger = TRACE, toConsole, toFile

#Test File Logs
log4j.appender.toFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.toFile=/opt/tommee/logs/log4jWebapp.log
log4j.appender.toFile.DatePattern='.'yyyy-MM-dd
log4j.appender.toFile.layout=org.apache.log4j.PatternLayout
log4j.appender.toFile.layout.ConversionPattern=%d %5p [%t] - %c%M - %m%n

#Test Console Logs
log4j.appender.toConsole=org.apache.log4j.ConsoleAppender
log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.toConsole.layout.ConversionPattern=%d %5p [%t] - %c%M - %m%n

部署描述符(web.xml)

<?xml version"1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://wwww.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaaee/web-app_3_0.xsd"
    version="3.0">

    <display-name>log4jTEst</display-name>

    <welcome-file-list>
        <welcome-filee>faces/home.xhtml</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <context-param>
        <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
        <param-value>client</param-value>
    </context-param>
    <context-param>
        <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
        <param-value>resources.application</param-value>
    </context-param>

    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>

</web-app>

现在,当我在我设置的服务器上运行它时,我会从 Eclipse 浏览器中得到它:

HTTP Status 500-

type - Exception report

message

description - The server encountered an internal error that prevented it from fulfilling this request.

exception -

javax.servlet.ServletException
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
    org.apachee.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

root cause -

java.lang.NullPointerException
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    org.apachee.el.parser.AstValue.getValue(AstValue.java:173)
    org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.jaava:109)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    javax.faces.component.UIOutput.getValue(UIOutput.java:174)
    com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
    javax.faces.component.UIComponentBase.encodeEnd(UIComponent.java:924)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1863)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

note - the full stack trace of the root cause is available in the Apache Tomcat (TomEE)/7.00.47 (1.6.0) logs

这是启动后的服务器日志:

Feb 10, 2014 4:40:29 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/home.xhtml]
java.lang.NullPointerException
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    org.apachee.el.parser.AstValue.getValue(AstValue.java:173)
    org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.jaava:109)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    javax.faces.component.UIOutput.getValue(UIOutput.java:174)
    com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
    javax.faces.component.UIComponentBase.encodeEnd(UIComponent.java:924)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1863)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    org.apache.catalina.core.StandardContextValve.invoke(StadnardContextValve.java:123)
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:744)

Feb 10, 2014 4:40:29 PM org.apache.catalina.core.StandaardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with hpath [/log4jTest] threw exception [null] with root cause
java.lang.NullPointerExpression
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    javax.el.CompositeELResolver.invoke(CompositeELResolver.java:255)
    org.apachee.el.parser.AstValue.getValue(AstValue.java:172)
    org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.jaava:109)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    javax.faces.component.UIOutput.getValue(UIOutput.java:174)
    com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
    com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
    javax.faces.component.UIComponentBase.encodeEnd(UIComponent.java:924)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1863)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    javax.faces.component.UIComponent.encodeALL(UIComponent.java:1859)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:443)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    org.apache.catalina.core.StandardContextValve.invoke(StadnardContextValve.java:123)
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    java.lang.Thread.run(Thread.java:744)

所以,我需要一些东西: A- 解决这个 nullPointerException(我相信这是由于我自己对 Java EE 缺乏了解,因此对平台的一些滥用。 B- 有关我如何正确或错误地使用 Java EE 的信息,以及可以帮助我改进的信息/资源。主要是对这个简单的应用程序的更正。

对我的奖励,在撰写此帮助请求时,我偶然发现了有关设置日志记录的问题的答案。显然我现在让它工作了,这很好,但是上面的问题在我的调整中仍然存在。

感谢阅读,感谢任何建议、更正和支持!

【问题讨论】:

  • 修复方法public String setStatusMsg() { this.statusMsg = statusMsg; } => 应该是public void setStatusMsg(String statusMsg) { this.statusMsg = statusMsg; }
  • 我在帖子中修复了它,但这就是我在代码中的方式。让错字通过是我的错,抱歉。
  • TomEE 附带 MyFaces,但您通过 webapp 发送 Mojarra。这些将与“奇怪”的例外冲突。去掉 webapp 中的javax.faces.jar(只有在部署到没有捆绑 JSF 的服务器时才需要,比如 Tomcat),依靠 TomEE 自己的 MyFaces 并重试。

标签: jakarta-ee el jsf-2.2 apache-tomee


【解决方案1】:

所以,当您的页面上有&lt;h:outputText value="#{logTest.foo()}"/&gt; 时,处理器读取的是:

  1. 在该托管 bean 中可能有一个名为 foo 的变量
  2. 根据 JavaBean 方法命名标准,该托管 bean 中将有一个名为 getFoo() 的方法。

您的课程在这两个方面都失败了,因此出现了错误。


&lt;h:outputText/&gt; 期望值绑定,即类上实际属性的 getter,而不是只返回值(不带参数)的方法。所以预期的是:

public class logTest {

   private static final Logger LOGGER = Logger.getLogger(logTest.class);

   private String statusMsg = "Default status";

   private String foo = "TheFoo" //There should be a named variable

      public String getStatusMsg() {
        return statusMsg;
      }

      public void setStatusMsg(String statusMsg) {
        this.statusMsg = statusMsg;
      }

      public String getFoo(){
        LOGGER.info("Currently executing method getFoo()");
        return this.foo;
      }

      public String foo() {
        LOGGER.info("Currently executing method foo()");
        setStatusmsg("Hello foo()!");
        return "foo() executed successfully!";
      }
}

更多信息:

【讨论】:

  • 虽然这是一种不好的做法,但您实际上应该能够在 EL-2.2 及更高版本中调用值表达式的方法,请参阅BalusC's answer。不过,我无法解释 NPE。也许logTest 类本身没有被实例化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-27
  • 2012-05-01
  • 1970-01-01
  • 2014-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多