0

I'm trying to create a super simple web application with logging in Java EE that runs on Apache TomEE. When doing so, I run into a javax.servlet.ServletException attributed to a java.lang.NullPointerException on what I thought was a stupidly simple page.

Some system and library info:

- 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)

Stupidly Simple Page (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>

The backing 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!";
    }
}

log4j.properties file in /WEB-INF/classes directory

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

Deployment Descriptor (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>

Now when I run this on the server I have set up, I get back this from the Eclipse browser:

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

Here's the server log right after startup:

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)

So, I need a few things: A- To address this nullPointerException (I believe it's coming from my own lack of knowledge about Java EE and therefore some misuse of the platform. B- Information about how I may be using Java EE either correctly or incorrectly, and information/resources that can help me improve. Mainly corrections to this simple application.

Bonus for me, In writing up this help request, I stumbled across the answer to a question I had about setting up logging. Apparently I got it to work now, which is good, however the issue above is persisting through my tweaks.

Thanks for reading, and I appreciate any advice, corrections, and support!

Bruno Borges
  • 853
  • 7
  • 24
Paraparity
  • 71
  • 1
  • 3
  • 7
  • Repair method `public String setStatusMsg() { this.statusMsg = statusMsg; }` => it should be `public void setStatusMsg(String statusMsg) { this.statusMsg = statusMsg; }` – Vasil Lukach Feb 11 '14 at 01:33
  • I fixed that in the post, but that's how I had it in the code. It was my bad letting the typo through, sorry. – Paraparity Feb 11 '14 at 14:17
  • TomEE ships with MyFaces yet you're shipping Mojarra via webapp. Those will conflict with "weird" exceptions. Get rid of `javax.faces.jar` in webapp (that's only necessary when you're deploying to a server which doesn't have JSF bundled, such as Tomcat), rely on TomEE's own MyFaces and retry. – BalusC Mar 06 '16 at 12:39

1 Answers1

0

So, when you have <h:outputText value="#{logTest.foo()}"/> on your page, what the processor reads is:

  1. There is probably a variable called foo in that managed bean
  2. There will be a method called getFoo() in that managed bean, per the JavaBean method naming standards.

Your class fails on both counts, hence the error.


The <h:outputText/> is expecting a value binding i.e. a getter for an actual attribute on the class, rather than a method that just returns a value (without taking an argument). So what is expected is :

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!";
      }
}

For more information:

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • While it is bad practice, you actually should be able to call methods for a value expression in EL-2.2 and above, see [BalusC's answer](http://stackoverflow.com/a/10202001/785663). I'm unable to explain the NPE, though. Maybe the `logTest` class itself doesn't get instantiated? – mabi Feb 18 '14 at 19:24