Merge pull request #461 from apache/WW-5063-null-check

[WW-5063] Adds null check for ActionInvocation
diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
index 06ab021..595107f 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
@@ -202,6 +202,10 @@
      * @param invocation the DefaultActionInvocation calling the action call stack
      */
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         ValueStack stack = invocation.getInvocationContext().getValueStack();
         String finalNamespace = this.namespace != null
                 ? TextParseUtil.translateVariables(namespace, stack)
diff --git a/core/src/main/java/com/opensymphony/xwork2/Result.java b/core/src/main/java/com/opensymphony/xwork2/Result.java
index e92467b..8c1687e 100644
--- a/core/src/main/java/com/opensymphony/xwork2/Result.java
+++ b/core/src/main/java/com/opensymphony/xwork2/Result.java
@@ -45,6 +45,6 @@
      * @param invocation  the invocation context.
      * @throws Exception can be thrown.
      */
-    public void execute(ActionInvocation invocation) throws Exception;
+    void execute(ActionInvocation invocation) throws Exception;
 
 }
diff --git a/core/src/main/java/org/apache/struts2/result/HttpHeaderResult.java b/core/src/main/java/org/apache/struts2/result/HttpHeaderResult.java
index 39395ab..a5d63b7 100644
--- a/core/src/main/java/org/apache/struts2/result/HttpHeaderResult.java
+++ b/core/src/main/java/org/apache/struts2/result/HttpHeaderResult.java
@@ -172,8 +172,12 @@
      * @throws Exception if an error occurs when re-setting the headers.
      */
     public void execute(ActionInvocation invocation) throws Exception {
-        HttpServletResponse response = ServletActionContext.getResponse();
-        ValueStack stack = ActionContext.getContext().getValueStack();
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
+        HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
+        ValueStack stack = invocation.getStack();
 
         if (status != -1) {
             response.setStatus(status);
diff --git a/core/src/main/java/org/apache/struts2/result/PlainResult.java b/core/src/main/java/org/apache/struts2/result/PlainResult.java
index b398b93..172f6b6 100644
--- a/core/src/main/java/org/apache/struts2/result/PlainResult.java
+++ b/core/src/main/java/org/apache/struts2/result/PlainResult.java
@@ -45,6 +45,10 @@
 
     @Override
     default void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         LOG.debug("Executing plain result");
         ResponseBuilder builder = new ResponseBuilder();
         write(builder);
diff --git a/core/src/main/java/org/apache/struts2/result/PostbackResult.java b/core/src/main/java/org/apache/struts2/result/PostbackResult.java
index 261404d..1fc8c6e 100644
--- a/core/src/main/java/org/apache/struts2/result/PostbackResult.java
+++ b/core/src/main/java/org/apache/struts2/result/PostbackResult.java
@@ -110,6 +110,10 @@
 
     @Override
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         String postbackUri = makePostbackUri(invocation);
         setLocation(postbackUri);
         super.execute(invocation);
diff --git a/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java b/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java
index ed6825b..dc6ac21 100644
--- a/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java
+++ b/core/src/main/java/org/apache/struts2/result/ServletActionRedirectResult.java
@@ -158,6 +158,10 @@
      * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)
      */
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         actionName = conditionalParse(actionName, invocation);
         parseLocation = false;
         if (namespace == null) {
diff --git a/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java b/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java
index 9d7b461..d59214b 100644
--- a/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java
+++ b/core/src/main/java/org/apache/struts2/result/ServletRedirectResult.java
@@ -143,6 +143,10 @@
     }
 
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         if (anchor != null) {
             anchor = conditionalParse(anchor, invocation);
         }
diff --git a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
index 9b82fd4..d310a6d 100644
--- a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
+++ b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
@@ -146,6 +146,10 @@
     }
 
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         long startTime = System.currentTimeMillis();
         String location = getStylesheetLocation();
 
@@ -154,12 +158,12 @@
         }
 
         if (parse) {
-            ValueStack stack = ActionContext.getContext().getValueStack();
+            ValueStack stack = invocation.getStack();
             location = TextParseUtil.translateVariables(location, stack);
         }
 
         try {
-            HttpServletResponse response = ServletActionContext.getResponse();
+            HttpServletResponse response = invocation.getInvocationContext().getServletResponse();
             response.setStatus(status);
             response.setCharacterEncoding(encoding);
             PrintWriter writer = response.getWriter();
diff --git a/core/src/site/resources/tags/action-attributes.html b/core/src/site/resources/tags/action-attributes.html
index c9e7e7c..7ff6035 100644
--- a/core/src/site/resources/tags/action-attributes.html
+++ b/core/src/site/resources/tags/action-attributes.html
@@ -67,6 +67,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/bean-attributes.html b/core/src/site/resources/tags/bean-attributes.html
index eca94fc..f079c8f 100644
--- a/core/src/site/resources/tags/bean-attributes.html
+++ b/core/src/site/resources/tags/bean-attributes.html
@@ -27,6 +27,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/date-attributes.html b/core/src/site/resources/tags/date-attributes.html
index 66b4414..38afc8f 100644
--- a/core/src/site/resources/tags/date-attributes.html
+++ b/core/src/site/resources/tags/date-attributes.html
@@ -51,6 +51,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/iterator-attributes.html b/core/src/site/resources/tags/iterator-attributes.html
index ffea921..fdc1cb7 100644
--- a/core/src/site/resources/tags/iterator-attributes.html
+++ b/core/src/site/resources/tags/iterator-attributes.html
@@ -59,6 +59,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/number-attributes.html b/core/src/site/resources/tags/number-attributes.html
index c98f6dd..73f91c2 100644
--- a/core/src/site/resources/tags/number-attributes.html
+++ b/core/src/site/resources/tags/number-attributes.html
@@ -99,6 +99,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/set-attributes.html b/core/src/site/resources/tags/set-attributes.html
index e52aded..1722cf3 100644
--- a/core/src/site/resources/tags/set-attributes.html
+++ b/core/src/site/resources/tags/set-attributes.html
@@ -19,7 +19,7 @@
             <td align="left" valign="top">action</td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">The scope in which to assign the variable. Can be <b>application</b>, <b>session</b>, <b>request</b>, <b>page</b>, or <b>action</b>.</td>
+            <td align="left" valign="top">The scope in which to assign the variable. Can be <b>application</b>, <b>session</b>, <b>request</b>, <b>page</b>, or <b>action</b> (action scope <em>also</em> adds it to the page scope).</td>
         </tr>
         <tr>
             <td align="left" valign="top">trimBody</td>
@@ -43,6 +43,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (default scope: action,<em>override</em> with the scope attribute).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/text-attributes.html b/core/src/site/resources/tags/text-attributes.html
index 97e7bf4..bce06e6 100644
--- a/core/src/site/resources/tags/text-attributes.html
+++ b/core/src/site/resources/tags/text-attributes.html
@@ -59,6 +59,6 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
 </table>
diff --git a/core/src/site/resources/tags/url-attributes.html b/core/src/site/resources/tags/url-attributes.html
index 843aec1..06e7d99 100644
--- a/core/src/site/resources/tags/url-attributes.html
+++ b/core/src/site/resources/tags/url-attributes.html
@@ -123,7 +123,7 @@
             <td align="left" valign="top"></td>
             <td align="left" valign="top">false</td>
             <td align="left" valign="top">String</td>
-            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td>
+            <td align="left" valign="top">Name used to reference the value pushed into the Value Stack (scope: action).</td>
         </tr>
         <tr>
             <td align="left" valign="top">windowState</td>
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionChainResultTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionChainResultTest.java
new file mode 100644
index 0000000..61fd363
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionChainResultTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.opensymphony.xwork2;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class ActionChainResultTest {
+
+    @Test
+    public void testPassingNullInvocation() throws Exception{
+        Result result = new ActionChainResult();
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/org/apache/struts2/result/HttpHeaderResultTest.java b/core/src/test/java/org/apache/struts2/result/HttpHeaderResultTest.java
index 4a79dd3..61a8f86 100644
--- a/core/src/test/java/org/apache/struts2/result/HttpHeaderResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/HttpHeaderResultTest.java
@@ -25,7 +25,6 @@
 import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsInternalTestCase;
-import org.apache.struts2.result.HttpHeaderResult;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
@@ -36,18 +35,19 @@
  */
 public class HttpHeaderResultTest extends StrutsInternalTestCase {
 
-    ActionInvocation invocation;
-    HttpHeaderResult result;
-    HttpServletResponse response;
-    Mock responseMock;
-    ReflectionProvider reflectionProvider;
+    private Mock invocationMock;
+    private ActionInvocation invocation;
+    private HttpHeaderResult result;
+    private HttpServletResponse response;
+    private Mock responseMock;
+    private ReflectionProvider reflectionProvider;
 
     public void testHeaderValuesAreNotParsedWhenParseIsFalse() throws Exception {
-        Map<String, String> params = new HashMap<String, String>();
+        Map<String, String> params = new HashMap<>();
         params.put("headers.foo", "${bar}");
         params.put("headers.baz", "baz");
 
-        Map<String, String> values = new HashMap<String, String>();
+        Map<String, String> values = new HashMap<>();
         values.put("bar", "abc");
         ActionContext.getContext().getValueStack().push(values);
 
@@ -61,11 +61,11 @@
     }
 
     public void testHeaderValuesAreParsedAndSet() throws Exception {
-        Map<String, String> params = new HashMap<String, String>();
+        Map<String, String> params = new HashMap<>();
         params.put("headers.foo", "${bar}");
         params.put("headers.baz", "baz");
 
-        Map<String, String> values = new HashMap<String, String>();
+        Map<String, String> values = new HashMap<>();
         values.put("bar", "abc");
         ActionContext.getContext().getValueStack().push(values);
 
@@ -113,12 +113,24 @@
         responseMock.verify();
     }
 
+    public void testPassingNullInvocation() throws Exception {
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
         result = new HttpHeaderResult();
         responseMock = new Mock(HttpServletResponse.class);
         response = (HttpServletResponse) responseMock.proxy();
-        invocation = (ActionInvocation) new Mock(ActionInvocation.class).proxy();
+        invocationMock = new Mock(ActionInvocation.class);
+        invocationMock.expectAndReturn("getInvocationContext", ActionContext.getContext());
+        invocationMock.expectAndReturn("getStack", ActionContext.getContext().getValueStack());
+        invocation = (ActionInvocation) invocationMock.proxy();
         reflectionProvider = container.getInstance(ReflectionProvider.class);
         ServletActionContext.setResponse(response);
     }
diff --git a/core/src/test/java/org/apache/struts2/result/PlainResultTest.java b/core/src/test/java/org/apache/struts2/result/PlainResultTest.java
index 4cd193c..3c4264f 100644
--- a/core/src/test/java/org/apache/struts2/result/PlainResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/PlainResultTest.java
@@ -19,6 +19,7 @@
 package org.apache.struts2.result;
 
 import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 import org.apache.struts2.StrutsException;
 import org.apache.struts2.StrutsInternalTestCase;
@@ -127,6 +128,16 @@
         }
     }
 
+    public void testPassingNullInvocation() throws Exception{
+        Result result = (PlainResult) response -> response.write("ignore");
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
     public void setUp() throws Exception {
         super.setUp();
         invocation = new MockActionInvocation();
diff --git a/core/src/test/java/org/apache/struts2/result/PostbackResultTest.java b/core/src/test/java/org/apache/struts2/result/PostbackResultTest.java
index 32c0cca..1cc6d24 100644
--- a/core/src/test/java/org/apache/struts2/result/PostbackResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/PostbackResultTest.java
@@ -21,6 +21,7 @@
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.util.ValueStack;
 import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.StrutsInternalTestCase;
@@ -32,7 +33,6 @@
 import static org.easymock.EasyMock.createControl;
 import static org.easymock.EasyMock.expect;
 
-
 public class PostbackResultTest extends StrutsInternalTestCase {
 
     public void testWithNoNamespace() throws Exception {
@@ -93,4 +93,15 @@
         control.verify();
     }
 
+    public void testPassingNullInvocation() throws Exception{
+        Result result = new PostbackResult();
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
+
 }
diff --git a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
index c6be2ab..321b3b5 100644
--- a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
@@ -23,6 +23,7 @@
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.config.entities.PackageConfig;
 import com.opensymphony.xwork2.config.entities.ResultConfig;
@@ -376,7 +377,7 @@
      * the desired log warning when an IllegalStateException is thrown for statusCode SC_FOUND.
      */
     public void testSendRedirectSCFoundIllegalStateException() {
-        HttpServletResponse httpServletResponseMock = (HttpServletResponse) createMock(HttpServletResponse.class);
+        HttpServletResponse httpServletResponseMock = createMock(HttpServletResponse.class);
         boolean iseCaught = false;
         view.setLocation("/bar/foo.jsp");
         view.setStatusCode(HttpServletResponse.SC_FOUND);
@@ -432,6 +433,16 @@
         }
     }
 
+    public void testPassingNullInvocation() throws Exception{
+        Result result = new ServletRedirectResult();
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
         configurationManager.getConfiguration().
diff --git a/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java b/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
index 0fc912f..ecc2b84 100644
--- a/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
+++ b/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
@@ -19,7 +19,9 @@
 package org.apache.struts2.views.xslt;
 
 import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionChainResult;
 import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 import com.opensymphony.xwork2.util.ClassLoaderUtil;
 import com.opensymphony.xwork2.util.ValueStack;
@@ -241,6 +243,16 @@
         assertEquals(actual, "ISO-8859-1");
     }
 
+    public void testPassingNullInvocation() throws Exception{
+        Result result = new XSLTResult();
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
         request = new MockHttpServletRequest();
diff --git a/plugins/gxp/src/main/java/org/apache/struts2/views/gxp/GxpResult.java b/plugins/gxp/src/main/java/org/apache/struts2/views/gxp/GxpResult.java
index 1e7eba6..701be88 100644
--- a/plugins/gxp/src/main/java/org/apache/struts2/views/gxp/GxpResult.java
+++ b/plugins/gxp/src/main/java/org/apache/struts2/views/gxp/GxpResult.java
@@ -104,9 +104,13 @@
     /**
      * Tells the GXP to write itself to the output stream.
      *
-     * @param actionInvocation the action invocation
+     * @param invocation the action invocation
      */
-    public void execute(ActionInvocation actionInvocation) {
+    public void execute(ActionInvocation invocation) {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         GxpResourceProvider provider = getProvider();
         try {
             getGxpClosure().write(provider.getWriter(), new GxpContext(provider.getLocale(), outputXml));
@@ -114,7 +118,7 @@
             throw new RuntimeException("Exception while rendering "
                     + getGxpName()
                     + " coming from "
-                    + actionInvocation.getAction().getClass().getName() + ".",
+                    + invocation.getAction().getClass().getName() + ".",
                     e);
         }
     }
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
index e1b83c7..2161ef0 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONResult.java
@@ -185,6 +185,10 @@
     }
 
     public void execute(ActionInvocation invocation) throws Exception {
+        if (invocation == null) {
+            throw new IllegalArgumentException("Invocation cannot be null!");
+        }
+
         ActionContext actionContext = invocation.getInvocationContext();
         HttpServletRequest request = actionContext.getServletRequest();
         HttpServletResponse response = actionContext.getServletResponse();
diff --git a/plugins/json/src/test/java/org/apache/struts2/json/JSONResultTest.java b/plugins/json/src/test/java/org/apache/struts2/json/JSONResultTest.java
index 5f6aef7..531f7ef 100644
--- a/plugins/json/src/test/java/org/apache/struts2/json/JSONResultTest.java
+++ b/plugins/json/src/test/java/org/apache/struts2/json/JSONResultTest.java
@@ -35,6 +35,7 @@
 
 import javax.servlet.http.HttpServletResponse;
 
+import com.opensymphony.xwork2.Result;
 import org.apache.struts2.StrutsStatics;
 import org.apache.struts2.StrutsTestCase;
 import org.apache.struts2.util.TestUtils;
@@ -713,6 +714,16 @@
         assertEquals("UTF-8", encoding);
     }
 
+    public void testPassingNullInvocation() throws Exception{
+        Result result = new JSONResult();
+        try {
+            result.execute(null);
+            fail("Exception should be thrown!");
+        } catch (IllegalArgumentException e) {
+            assertEquals("Invocation cannot be null!", e.getMessage());
+        }
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
diff --git a/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java b/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java
index 282f653..eaef67c 100644
--- a/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java
+++ b/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletActionRedirectResult.java
@@ -171,6 +171,10 @@
 	 * @see com.opensymphony.xwork2.Result#execute(com.opensymphony.xwork2.ActionInvocation)

 	 */

 	public void execute(ActionInvocation invocation) throws Exception {

+		if (invocation == null) {

+			throw new IllegalArgumentException("Invocation cannot be null!");

+		}

+

 		actionName = conditionalParse(actionName, invocation);

 		parseLocation = false;