java.lang.IllegalArgumentException: Request cannot be null

Apereo Issues | Tony Hughes | 8 years ago
  1. 0

    There seems to be a threading issue (in v2.6.1) which can cause "java.lang.IllegalArgumentException: Request cannot be null". ie: WARN [http-443-Processor6] portal.ChannelManager.[] (ChannelManager.java:571) - Replacing channel [org.jasig.portal.channels.portlet.CPortletAdapter@14ac54], which had subscribeId [n58] with error channel because of error code Render time exception message: IChannelRenderer.completeRendering() threw and throwable [java.lang.IllegalArgumentException: Request cannot be null] java.lang.IllegalArgumentException: Request cannot be null at javax.servlet.ServletRequestWrapper.<init>(ServletRequestWrapper.java:51) at javax.servlet.http.HttpServletRequestWrapper.<init>(HttpServletRequestWrapper.java:43) at org.jasig.portal.container.servlet.AttributeRequestWrapper.<init>(AttributeRequestWrapper.java:26) at org.jasig.portal.container.servlet.ServletRequestImpl.<init>(ServletRequestImpl.java:49) at org.jasig.portal.channels.portlet.CPortletAdapter.setRuntimeData(CPortletAdapter.java:426) at org.jasig.portal.ChannelRenderer$Worker.execute(ChannelRenderer.java:483) at org.jasig.portal.utils.threading.BaseTask.run(BaseTask.java:27) at edu.emory.mathcs.backport.java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.run(FutureTask.java:178) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575) at java.lang.Thread.run(Thread.java:595) BACKGROUND ================= PortalControlStructures (pcs) uses thread local storage to store each rendering thread's reference to the HttpServletRequest/HttpServletResponse objects inside pcs. But, in addition to the thread local storage, there are also member variables in pcs (req/res) which store references to the HttpServletRequest/HttpServletResponse objects. The comments in pcs state that "the class member variables are still used as a fallback if needed". And, as suggested by this comment, pcs.getHttpServletRequest/Response( ) will return the member var, if there is no value for the current thread in the thread local storage. ================= PROBLEM ================= The problem arises when pcs.getHttpServletRequest( ) is called AND there is no value for the current thread in the thread local storage (reqLocal) AND the member var (req) is null. I haven't spotted the circumstances which can mean there is nothing stored in the pcs' thread local storage for a particular renderer thread at the time it is calling pcs.getHttpServletRequest( ), from CPortletAdapter.setRuntimeData( ). [I should add that I am unfamiliar with the Executor Framework and indeed with uPortal. So familiarity with the Executor Framework and/or more time invested in looking at the uPortal source may enlighten me.] But I can see that the member var (req) of a particular pcs is set to null every time a renderer thread (with a ref to that pcs) executes the finally block of ChannelRenderer.Worker.execute( ). [So one renderer thread executing the finally block can set the pcs member var to null at the "wrong time" for another thread (which refs the same pcs). ie After the other thread has started ChannelRenderer.Worker.execute( ) and called pcs.setHttpServletRequest( ) BUT before it has called pcs.getHttpServletRequest( ), from CPortletAdapter.setRuntimeData( ).] ================= RESOLUTION ================= To resolve the problem, we can avoid setting the member var to null in the finally block in ChannelRenderer.Worker.execute( ). My suggested solution is to introduce a new method, clearThreadState( ), to PortalControlStructures. The role of this method being to clear the thread state stored in pcs for the currently executing thread, without affecting the req/res member vars. And then to call this method from the finally block in ChannelRenderer.Worker.execute( ) instead of the calls to pcs.setHttpServletRequest/Response( ). (The calls to pcs.setHttpServletRequest/Response( ) from ChannelManager.finishedRenderingCycle( ) are untouched.) ================= PATCH ================= Patch attached. =================

    Apereo Issues | 8 years ago | Tony Hughes
    java.lang.IllegalArgumentException: Request cannot be null
  2. 0

    There seems to be a threading issue (in v2.6.1) which can cause "java.lang.IllegalArgumentException: Request cannot be null". ie: WARN [http-443-Processor6] portal.ChannelManager.[] (ChannelManager.java:571) - Replacing channel [org.jasig.portal.channels.portlet.CPortletAdapter@14ac54], which had subscribeId [n58] with error channel because of error code Render time exception message: IChannelRenderer.completeRendering() threw and throwable [java.lang.IllegalArgumentException: Request cannot be null] java.lang.IllegalArgumentException: Request cannot be null at javax.servlet.ServletRequestWrapper.<init>(ServletRequestWrapper.java:51) at javax.servlet.http.HttpServletRequestWrapper.<init>(HttpServletRequestWrapper.java:43) at org.jasig.portal.container.servlet.AttributeRequestWrapper.<init>(AttributeRequestWrapper.java:26) at org.jasig.portal.container.servlet.ServletRequestImpl.<init>(ServletRequestImpl.java:49) at org.jasig.portal.channels.portlet.CPortletAdapter.setRuntimeData(CPortletAdapter.java:426) at org.jasig.portal.ChannelRenderer$Worker.execute(ChannelRenderer.java:483) at org.jasig.portal.utils.threading.BaseTask.run(BaseTask.java:27) at edu.emory.mathcs.backport.java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) at edu.emory.mathcs.backport.java.util.concurrent.FutureTask.run(FutureTask.java:178) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575) at java.lang.Thread.run(Thread.java:595) BACKGROUND ================= PortalControlStructures (pcs) uses thread local storage to store each rendering thread's reference to the HttpServletRequest/HttpServletResponse objects inside pcs. But, in addition to the thread local storage, there are also member variables in pcs (req/res) which store references to the HttpServletRequest/HttpServletResponse objects. The comments in pcs state that "the class member variables are still used as a fallback if needed". And, as suggested by this comment, pcs.getHttpServletRequest/Response( ) will return the member var, if there is no value for the current thread in the thread local storage. ================= PROBLEM ================= The problem arises when pcs.getHttpServletRequest( ) is called AND there is no value for the current thread in the thread local storage (reqLocal) AND the member var (req) is null. I haven't spotted the circumstances which can mean there is nothing stored in the pcs' thread local storage for a particular renderer thread at the time it is calling pcs.getHttpServletRequest( ), from CPortletAdapter.setRuntimeData( ). [I should add that I am unfamiliar with the Executor Framework and indeed with uPortal. So familiarity with the Executor Framework and/or more time invested in looking at the uPortal source may enlighten me.] But I can see that the member var (req) of a particular pcs is set to null every time a renderer thread (with a ref to that pcs) executes the finally block of ChannelRenderer.Worker.execute( ). [So one renderer thread executing the finally block can set the pcs member var to null at the "wrong time" for another thread (which refs the same pcs). ie After the other thread has started ChannelRenderer.Worker.execute( ) and called pcs.setHttpServletRequest( ) BUT before it has called pcs.getHttpServletRequest( ), from CPortletAdapter.setRuntimeData( ).] ================= RESOLUTION ================= To resolve the problem, we can avoid setting the member var to null in the finally block in ChannelRenderer.Worker.execute( ). My suggested solution is to introduce a new method, clearThreadState( ), to PortalControlStructures. The role of this method being to clear the thread state stored in pcs for the currently executing thread, without affecting the req/res member vars. And then to call this method from the finally block in ChannelRenderer.Worker.execute( ) instead of the calls to pcs.setHttpServletRequest/Response( ). (The calls to pcs.setHttpServletRequest/Response( ) from ChannelManager.finishedRenderingCycle( ) are untouched.) ================= PATCH ================= Patch attached. =================

    Apereo Issues | 8 years ago | Tony Hughes
    java.lang.IllegalArgumentException: Request cannot be null
  3. Speed up your debug routine!

    Automated exception search integrated into your IDE

  4. 0

    java.lang.IllegalArgumentException: Request cannot be null

    Oracle Community | 1 decade ago | 843810
    java.lang.IllegalArgumentException: Request cannot be null
  5. 0

    Why does my Mockito mock object use real the implementation

    Stack Overflow | 6 years ago | auramo
    java.lang.IllegalArgumentException: Request must not be null.

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. java.lang.IllegalArgumentException

      Request cannot be null

      at javax.servlet.ServletRequestWrapper.<init>()
    2. JavaServlet
      HttpServletRequestWrapper.<init>
      1. javax.servlet.ServletRequestWrapper.<init>(ServletRequestWrapper.java:51)
      2. javax.servlet.http.HttpServletRequestWrapper.<init>(HttpServletRequestWrapper.java:43)
      2 frames
    3. org.jasig.portal
      BaseTask.run
      1. org.jasig.portal.container.servlet.AttributeRequestWrapper.<init>(AttributeRequestWrapper.java:26)
      2. org.jasig.portal.container.servlet.ServletRequestImpl.<init>(ServletRequestImpl.java:49)
      3. org.jasig.portal.channels.portlet.CPortletAdapter.setRuntimeData(CPortletAdapter.java:426)
      4. org.jasig.portal.ChannelRenderer$Worker.execute(ChannelRenderer.java:483)
      5. org.jasig.portal.utils.threading.BaseTask.run(BaseTask.java:27)
      5 frames
    4. Backport of JSR 166
      ThreadPoolExecutor$Worker.run
      1. edu.emory.mathcs.backport.java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
      2. edu.emory.mathcs.backport.java.util.concurrent.FutureTask.run(FutureTask.java:178)
      3. edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
      4. edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
      4 frames
    5. Java RT
      Thread.run
      1. java.lang.Thread.run(Thread.java:595)
      1 frame