NPE in RewritePhaseListener.handlePhaseOperation

Splash Forums Rewrite Users NPE in RewritePhaseListener.handlePhaseOperation

This topic contains 30 replies, has 4 voices, and was last updated by  Lincoln Baxter III 2 years, 7 months ago.

Viewing 15 posts - 1 through 15 (of 31 total)
  • Author
    Posts
  • #25410

    Luke
    Participant

    I am seeing an occasional Failed to handle PhaseOperation exception in RewritePhaseListener.handPhaseOperation caused by an NPE at line 134. Curiously, I cannot reproduce the failure using Chrome or IE 10. It occurs only when using IE 9 or FireFox.

    My Configuration:
    JBoss 7.1.1
    JSF 2.1 Mojarra
    Rewrite 2.0.8.Final
    Java 7 update 25

    A typical rule that when executed randomly results in the exception being thrown:

                                  .addRule(Join.path("/project/actors/{id}").to("/actors.jsf"))
     .perform(PhaseOperation.enqueue(new IgnorePostbackOperation(Invoke.binding(El.retrievalMethod("actorAction.load"))))
    .after(PhaseId.RESTORE_VIEW).and(Forward.to("/actors.jsf")))                                .where("id")                              .bindsTo(PhaseBinding.to(El.property("actorAction.id")).after(PhaseId.RESTORE_VIEW))
    

    What would cause this null pointer exception?

    #25414

    Could you please post the full stacktrace? I think this will help to identify the root cause of the problem.

    #25415

    And could you also post your web.xml?

    #25419

    Luke
    Participant

    The web descriptor used:

    
    <?xml version="1.0"?>
    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    	<display-name>captor</display-name>
    	<context-param>
    		<param-name>javax.faces.PROJECT_STAGE</param-name>
    		<param-value>Development</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.FACELETS_DEVELOPMENT</param-name>
    		<param-value>true</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    		<param-value>2</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    		<param-value>true</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    		<param-value>.xhtml</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    		<param-value>server</param-value>
    	</context-param>
    	<context-param>
    		<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
    		<param-value>true</param-value>
    	</context-param>
    	<context-param>
    		<param-name>primefaces.THEME</param-name>
    		<param-value>#{authUser.theme}</param-value>
    	</context-param>
    	
    		<filter>
    		<filter-name>OCPsoft Rewrite Filter</filter-name>
    		<filter-class>org.ocpsoft.rewrite.servlet.RewriteFilter</filter-class>
    		<async-supported>true</async-supported>
    	</filter>
    	<filter-mapping>
    		<filter-name>OCPsoft Rewrite Filter</filter-name>
    		<url-pattern>/*</url-pattern>
    		<dispatcher>FORWARD</dispatcher>
    		<dispatcher>REQUEST</dispatcher>
    		<dispatcher>INCLUDE</dispatcher>
    		<dispatcher>ASYNC</dispatcher>
    		<dispatcher>ERROR</dispatcher>
    	</filter-mapping>	
    	
    	<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>*.jsf</url-pattern>
    	</servlet-mapping>
    	<filter>
    		<filter-name>PrimeFaces FileUpload Filter</filter-name>
    		<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>PrimeFaces FileUpload Filter</filter-name>
    		<servlet-name>Faces Servlet</servlet-name>
    		<dispatcher>FORWARD</dispatcher>
    	</filter-mapping>
    
    	<servlet>
    		<servlet-name>imageServlet</servlet-name>
    		<servlet-class>com.sfs.captor.view.ImageServlet</servlet-class>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>imageServlet</servlet-name>
    		<url-pattern>/image/*</url-pattern>
    	</servlet-mapping>
    
    	<!-- Welcome File List -->
    	<welcome-file-list>
    		<welcome-file>index.html</welcome-file>
    	</welcome-file-list>
    
    	<session-config>
    		<session-timeout>60</session-timeout>
    	</session-config>
    
    	<login-config>
    		<auth-method>FORM</auth-method>
    		<realm-name>JDBCRealm</realm-name>
    		<form-login-config>
    			<form-login-page>/home.xhtml</form-login-page>
    			<form-error-page>/error.xhtml</form-error-page>
    		</form-login-config>
    	</login-config>
    	<security-role>
    		<role-name>Admin</role-name>
    	</security-role>
    	<security-role>
    		<role-name>Manager</role-name>
    	</security-role>
    	<security-role>
    		<role-name>User</role-name>
    	</security-role>
    	<security-role>
    		<role-name>Guest</role-name>
    	</security-role>
    	<security-constraint>
    		<web-resource-collection>
    			<web-resource-name>Raw XHTML Pages</web-resource-name>
    			<description />
    			<url-pattern>*.xhtml</url-pattern>
    		</web-resource-collection>
    	</security-constraint>
    
    </web-app>
    
    #25422

    Your web.xml looks good.

    Could your remove .and(Forward.to("/actors.jsf")) from your configuration. I don’t think it is necessary because the Join already forwards to this URL.

    If this doesn’t help, could you include the full stacktrace?

    #25425

    Luke
    Participant

    I removed the rule:.and(Forward.to("/actors.jsf")) and the same exception is still being thrown.

    The stacktrace:

    21:33:51,008 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) org.ocpsoft.rewrite.exception.RewriteException: Failed to handle PhaseOperation [org.ocpsoft.rewrite.faces.config.PhaseOperation$1@11f9834d]
    21:33:51,008 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.faces.RewritePhaseListener$1.performInSubflow(RewritePhaseListener.java:147)
    21:33:51,009 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.servlet.event.SubflowTask.perform(SubflowTask.java:61)
    21:33:51,009 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.faces.RewritePhaseListener.handlePhaseOperation(RewritePhaseListener.java:125)
    21:33:51,010 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.faces.RewritePhaseListener.handleAfterPhaseOperations(RewritePhaseListener.java:108)
    21:33:51,010 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.faces.RewritePhaseListener.afterPhase(RewritePhaseListener.java:63)
    21:33:51,011 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189)
    21:33:51,011 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107)
    21:33:51,011 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    21:33:51,012 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    21:33:51,012 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    21:33:51,013 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
    21:33:51,013 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    21:33:51,014 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:98)
    21:33:51,014 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    21:33:51,015 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    21:33:51,015 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:200)
    21:33:51,015 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    21:33:51,016 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    21:33:51,016 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:840)
    21:33:51,017 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:622)
    21:33:51,017 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:560)
    21:33:51,018 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:488)
    21:33:51,018 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.servlet.impl.HttpRewriteResultHandler.handleResult(HttpRewriteResultHandler.java:38)
    21:33:51,019 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.servlet.RewriteFilter.rewrite(RewriteFilter.java:263)
    21:33:51,019 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:188)
    21:33:51,020 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
    21:33:51,020 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
    21:33:51,020 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
    21:33:51,021 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    21:33:51,021 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:397)
    21:33:51,022 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
    21:33:51,022 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
    21:33:51,023 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
    21:33:51,023 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    21:33:51,024 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    21:33:51,024 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
    21:33:51,024 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
    21:33:51,025 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
    21:33:51,025 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
    21:33:51,026 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at java.lang.Thread.run(Thread.java:722)
    21:33:51,027 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) Caused by: java.lang.NullPointerException
    21:33:51,027 ERROR [stderr] (http-localhost-127.0.0.1-8080-3) 	at org.ocpsoft.rewrite.faces.RewritePhaseListener$1.performInSubflow(RewritePhaseListener.java:134)
    
    #25426

    Hmmm. That’s really weird. That shouldn’t happen. Looks like the exception is thrown from this statement:

    List<RewriteResultHandler> resultHandlers = ((HttpRewriteLifecycleContext) ((HttpServletRewrite) rewriteEvent)
             .getRequest().getAttribute(RewriteLifecycleContext.LIFECYCLE_CONTEXT_KEY))
             .getResultHandlers();
    

    My guess is that request.getAttribute(RewriteLifecycleContext.LIFECYCLE_CONTEXT_KEY) returns null, but actually I don’t see a reason why this is happening. This attribute is set by the filter and I see no reason why it could be absent.

    Any chance that you could try to debug this in your IDE. It would be interesting to see what is null here. This should be possible with an exception breakpoint.

    Or could you perhaps provide a minimal sample app that reproduces this?

    #25435

    Luke
    Participant

    I did isolate this NPE problem to a single application. I have several similar applications using rewrite 2.0.8.Final and only one is experiencing the condition. So, I compared the security-constraint url-pattern value and they differ.

    I modified the url-pattern to:
    <url-pattern>/*</url-pattern>
    The application is no longer throwing the NPE. I believe I was specifying an overly restrictive pattern causing the request object to be null. Does that make sense to you? While it may be obvious to you, it might be useful to mention in the configuration guide.

    #25441

    Hmmmm. So you say that changing *.xhtml to /* fixed the issue for you? I would be very surprised if the request object could get null.

    #25442

    Ah, now I got it. With *.xhtml your security constraint was _not_ matching the incoming request URL but the forwarded URL. Yeah, this may lead to some weird problems. I guess this should be added to the FAQ.

    #25448

    Luke
    Participant

    I still seeing the exception occasionally now. It seems like a timing issue. The error does not occur on a consistent basis. I will have to put a local copy in place and debug it more. I will update you with my findings. Thanks.

    #25466

    Luke
    Participant

    So I grabbed your source code and built 2.0.9.Final-SNAPSHOT.

    I added log messages to RewritePhaseListener:

    
                    @Override
                      public void performInSubflow(ServletRewrite<?, ?> rewriteEvent, EvaluationContext context)
                      {
                         try {
                            operation.performOperation((HttpServletRewrite) rewriteEvent, context);
    System.out.println("rewrite.getRequest = " + rewriteEvent.getRequest());
    System.out.println("rewrite.getRequest.getAttribute = " + rewriteEvent.getRequest().getAttribute(RewriteLifecycleContext.LIFECYCLE_CONTEXT_KEY));
                            List<RewriteResultHandler> resultHandlers = ((HttpRewriteLifecycleContext) ((HttpServletRewrite) rewriteEvent)
                                     .getRequest().getAttribute(RewriteLifecycleContext.LIFECYCLE_CONTEXT_KEY))
                                     .getResultHandlers();
    System.out.println("resultHandlers = " + resultHandlers);
                            int handlerCount = resultHandlers.size();
                            for (int i = 0; i < handlerCount; i++)
                            {
                              RewriteResultHandler handler = resultHandlers.get(i);
                               System.out.println("operation.getEvent = " + operation.getEvent());
                               if (handler.handles(operation.getEvent()))
                                  handler.handleResult(operation.getEvent());
                            }
                         }
                         catch (Exception e) {
                                     if (e instanceof NullPointerException) {
                                                                    System.err.println("NullPointerException caught");
                                     }
                                     else { 
                                    throw new RewriteException("Failed to handle PhaseOperation [" + operation + "]", e);
                          }
                         }
                      }
    
                   });
          return flow;
       }
    

    The debug output indicates the InboundRewrite POST causes the NullPointerException to be thrown. If I catch the NPE (and not rethrow it), application navigations work correctly. I am not sure what is null. I assume the NPE is bubbling up from the handler methods. I hope this helps. I still contend this is a timing problem, because I never get an error on weblogic 12c apps. The tomcat derivatives like JBoss and Glassfish throw the errors. Also, IE 11 never causes the NPE to be thrown regardless of server.

    
    
    23:58:31,363 INFO  [stdout] (http-localhost-127.0.0.1-8080-2) rewrite.getRequest = http://localhost:8080/captor/glossary.jsf
    
    23:58:31,363 INFO  [stdout] (http-localhost-127.0.0.1-8080-2) rewrite.getRequest.getAttribute = org.ocpsoft.rewrite.servlet.impl.HttpRewriteContextImpl@682e8f6
    
    23:58:31,363 INFO  [stdout] (http-localhost-127.0.0.1-8080-2) resultHandlers = [org.ocpsoft.rewrite.servlet.impl.HttpRewriteResultHandler@7a9b0ccb]
    
    23:58:31,363 INFO  [stdout] (http-localhost-127.0.0.1-8080-2) operation.getEvent = InboundRewrite [POST url=http://localhost:8080/captor/project/2/glossary?cid=4, flow=UN_HANDLED, dispatchResource=/glossary.jsf]
    
    23:58:31,363 ERROR [stderr] (http-localhost-127.0.0.1-8080-2) NullPointerException caught
    
    #25467

    Thanks for these details. It would have bean really interesting to see the e.printStacktrace() for this exception. Because it doesn’t look like it is thrown from the code I posted at first. Any chance that you could create such a stack trace?

    Unfortunately something like this is really difficult to reproduce without a sample webapp that shows this behavior. Nearly every application I’m developing includes Rewrite and I didn’t see something like this before.

    #25468

    I think this failure probably occurs because RewritePhaseListener expects rewrite to be active in the request, but it is not, hence the list of providers is null.

    #25470

    We could solve this with null checking, but I think we should probably instead add some type of lifecycle awareness to the RewritePhaseListener.

Viewing 15 posts - 1 through 15 (of 31 total)

You must be logged in to reply to this topic.

Comments are closed.