Merge pull request #453 from apache/WW-3877-removes-alt-syntax

[WW-3877] Drops altSyntax option
diff --git a/core/pom.xml b/core/pom.xml
index f6038f6..5bb935f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -31,7 +31,7 @@
     <name>Struts 2 Core</name>
 
     <properties>
-        <tlib.version>2.3</tlib.version>
+        <tlib.version>2.6</tlib.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
 
diff --git a/core/src/main/java/org/apache/struts2/components/ActionComponent.java b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
index af1ebd2..7cc3f43 100644
--- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java
+++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java
@@ -150,10 +150,12 @@
     }
 
     @Inject
+    @Override
     public void setActionMapper(ActionMapper mapper) {
         this.actionMapper = mapper;
     }
 
+    @Override
     public boolean end(Writer writer, String body) {
         boolean end = super.end(writer, "", false);
         try {
diff --git a/core/src/main/java/org/apache/struts2/components/ActionError.java b/core/src/main/java/org/apache/struts2/components/ActionError.java
index 060c3c9..5e41b54 100644
--- a/core/src/main/java/org/apache/struts2/components/ActionError.java
+++ b/core/src/main/java/org/apache/struts2/components/ActionError.java
@@ -61,10 +61,12 @@
         super(stack, request, response);
     }
 
+    @Override
     protected String getDefaultTemplate() {
         return TEMPLATE;
     }
 
+    @Override
     protected void evaluateExtraParams() {
         boolean isEmptyList = true;
         Collection<String> actionMessages = (List) findValue("actionErrors");
diff --git a/core/src/main/java/org/apache/struts2/components/ActionMessage.java b/core/src/main/java/org/apache/struts2/components/ActionMessage.java
index 0f1680e..33a26cf 100644
--- a/core/src/main/java/org/apache/struts2/components/ActionMessage.java
+++ b/core/src/main/java/org/apache/struts2/components/ActionMessage.java
@@ -59,10 +59,12 @@
         super(stack, request, response);
     }
 
+    @Override
     protected String getDefaultTemplate() {
         return TEMPLATE;
     }
 
+    @Override
     protected void evaluateExtraParams() {
         boolean isEmptyList = true;
         Collection<String> actionMessages = (List) findValue("actionMessages");
diff --git a/core/src/main/java/org/apache/struts2/components/ClosingUIBean.java b/core/src/main/java/org/apache/struts2/components/ClosingUIBean.java
index 48cccb2..c9785cf 100644
--- a/core/src/main/java/org/apache/struts2/components/ClosingUIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/ClosingUIBean.java
@@ -46,6 +46,7 @@
         this.openTemplate = openTemplate;
     }
 
+    @Override
     public boolean start(Writer writer) {
         boolean result = super.start(writer);
         try {
diff --git a/core/src/main/java/org/apache/struts2/components/ContextBean.java b/core/src/main/java/org/apache/struts2/components/ContextBean.java
index 8628e3a..69f393a 100644
--- a/core/src/main/java/org/apache/struts2/components/ContextBean.java
+++ b/core/src/main/java/org/apache/struts2/components/ContextBean.java
@@ -38,7 +38,7 @@
         }
     }
     
-    @StrutsTagAttribute(description="Name used to reference the value pushed into the Value Stack")
+    @StrutsTagAttribute(description="Name used to reference the value pushed into the Value Stack (scope: action).")
     public void setVar(String var) {
         if (var != null) {
             this.var = findString(var);
diff --git a/core/src/main/java/org/apache/struts2/components/GenericUIBean.java b/core/src/main/java/org/apache/struts2/components/GenericUIBean.java
index 63bb131..fbf8776 100644
--- a/core/src/main/java/org/apache/struts2/components/GenericUIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/GenericUIBean.java
@@ -134,6 +134,7 @@
         return ContainUtil.contains(obj1, obj2);
     }
 
+    @Override
     protected String getDefaultTemplate() {
         return TEMPLATE;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/ListUIBean.java b/core/src/main/java/org/apache/struts2/components/ListUIBean.java
index 14cf74a..26484f2 100644
--- a/core/src/main/java/org/apache/struts2/components/ListUIBean.java
+++ b/core/src/main/java/org/apache/struts2/components/ListUIBean.java
@@ -62,6 +62,7 @@
         super(stack, request, response);
     }
 
+    @Override
     public void evaluateExtraParams() {
         Object value = null;
 
@@ -148,6 +149,7 @@
         return ContainUtil.contains(obj1, obj2);
     }
 
+    @Override
     protected Class getValueClassType() {
         return null; // don't convert nameValue to anything, we need the raw value
     }
diff --git a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
index b8b7a3c..a302e8a 100644
--- a/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
+++ b/core/src/main/java/org/apache/struts2/components/ServletUrlRenderer.java
@@ -49,6 +49,7 @@
     private ActionMapper actionMapper;
     private UrlHelper urlHelper;
 
+    @Override
     @Inject
     public void setActionMapper(ActionMapper mapper) {
         this.actionMapper = mapper;
@@ -62,6 +63,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void renderUrl(Writer writer, UrlProvider urlComponent) {
         String scheme = urlComponent.getHttpServletRequest().getScheme();
 
@@ -104,7 +106,8 @@
             if (StringUtils.isNotEmpty(var)) {
                 urlComponent.putInContext(result);
 
-                // add to the request and page scopes as well
+                // Note: Old comments stated that var was placed in the page scope, but interactive checks with EL on JSPs prove otherwise.
+                // Add the var attribute to the request scope as well.
                 urlComponent.getHttpServletRequest().setAttribute(var, result);
             } else {
                 try {
@@ -125,6 +128,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public void renderFormUrl(Form formComponent) {
         String namespace = formComponent.determineNamespace(formComponent.namespace, formComponent.getStack(), formComponent.request);
         String action;
@@ -233,6 +237,7 @@
     }
 
 
+    @Override
     public void beforeRenderUrl(UrlProvider urlComponent) {
         if (urlComponent.getValue() != null) {
             urlComponent.setValue(urlComponent.findString(urlComponent.getValue()));
@@ -298,7 +303,7 @@
 
     /**
      * Merge request parameters into current parameters. If a parameter is
-     * already present, than the request parameter in the current request and value atrribute
+     * already present, than the request parameter in the current request and value attribute
      * will not override its value.
      *
      * The priority is as follows:-
@@ -308,7 +313,7 @@
      *  <li>parameter from the param tag (most priority)</li>
      * </ul>
      *
-     * @param value the value attribute (url to be generated by this component)
+     * @param value the value attribute (URL to be generated by this component)
      * @param parameters component parameters
      * @param contextParameters request parameters
      */
diff --git a/core/src/main/java/org/apache/struts2/components/Set.java b/core/src/main/java/org/apache/struts2/components/Set.java
index ff1a27c..8cb1ca4 100644
--- a/core/src/main/java/org/apache/struts2/components/Set.java
+++ b/core/src/main/java/org/apache/struts2/components/Set.java
@@ -60,6 +60,8 @@
  *
  * <li>scope (String): 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>. By default it is <b>action</b>.</li>
+ * 
+ * <li>Note: With the <b>action</b> scope, the variable is <em>also</em> assigned to the <b>page</b> scope.
  *
  * </ul>
  *
@@ -88,6 +90,7 @@
         super(stack);
     }
 
+    @Override
     public boolean end(Writer writer, String body) {
         ValueStack stack = getStack();
 
@@ -113,6 +116,7 @@
         } else if ("page".equalsIgnoreCase(scope)) {
             stack.setValue("#attr['" + getVar() + "']", o, false);
         } else {
+            // Default scope is action.  Note: The action acope handling also adds the var to the page scope.
             stack.getContext().put(getVar(), o);
             stack.setValue("#attr['" + getVar() + "']", o, false);
         }
@@ -120,13 +124,15 @@
         return super.end(writer, body);
     }
 
-    @StrutsTagAttribute(required=true, description="Name used to reference the value pushed into the Value Stack")
+    @StrutsTagAttribute(required=true, description="Name used to reference the value pushed into the Value Stack (default scope: action," +
+                "<em>override</em> with the scope attribute).")
+    @Override
     public void setVar(String var) {
        super.setVar(var);
     }
 
     @StrutsTagAttribute(description="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>.", defaultValue="action")
+                ", <b>session</b>, <b>request</b>, <b>page</b>, or <b>action</b> (action scope <em>also</em> adds it to the page scope).", defaultValue="action")
     public void setScope(String scope) {
         this.scope = scope;
     }
diff --git a/core/src/main/java/org/apache/struts2/components/Text.java b/core/src/main/java/org/apache/struts2/components/Text.java
index 9f59e09..38cde39 100644
--- a/core/src/main/java/org/apache/struts2/components/Text.java
+++ b/core/src/main/java/org/apache/struts2/components/Text.java
@@ -52,6 +52,12 @@
  * tag will be used as default message. If no value is found, the key of the
  * message will not be written out.
  * </p>
+ * 
+ * <p>
+ * Note: If the <b>var</b> attribute is used with this tag, the tag's value will
+ * <em>not</em> be written out.  Instead the result will be saved into the
+ * action context (action scope).
+ * </p>
  * <!-- END SNIPPET: javadoc -->
  *
  * <!-- START SNIPPET: params -->
@@ -156,6 +162,7 @@
         this.escapeCsv = escapeCsv;
     }
 
+    @Override
     public boolean usesBody() {
         // overriding this to true such that EVAL_BODY_BUFFERED is return and
         // bodyContent will be valid hence, text between start & end tag will
@@ -163,6 +170,7 @@
         return true;
     }
 
+    @Override
     public boolean end(Writer writer, String body) {
         actualName = findString(name, "name", "You must specify the i18n key. Example: welcome.header");
         String defaultMessage;
@@ -189,10 +197,12 @@
         return super.end(writer, "");
     }
 
+    @Override
     public void addParameter(String key, Object value) {
         addParameter(value);
     }
 
+    @Override
     public void addParameter(Object value) {
         if (values.isEmpty()) {
             values = new ArrayList<>(4);
diff --git a/core/src/main/java/org/apache/struts2/util/AttributeMap.java b/core/src/main/java/org/apache/struts2/util/AttributeMap.java
index a6eebb4..ea088b4 100644
--- a/core/src/main/java/org/apache/struts2/util/AttributeMap.java
+++ b/core/src/main/java/org/apache/struts2/util/AttributeMap.java
@@ -52,26 +52,32 @@
         this.context = context;
     }
 
+    @Override
     public boolean isEmpty() {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public void clear() {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public boolean containsKey(Object key) {
         return (get(key) != null);
     }
 
+    @Override
     public boolean containsValue(Object value) {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public Set entrySet() {
         return Collections.EMPTY_SET;
     }
 
+    @Override
     public Object get(Object key) {
         PageContext pc = getPageContext();
 
@@ -88,9 +94,9 @@
                 return application.get(key);
             }
         } else {
-            try{
+            try {
                 return pc.findAttribute(key.toString());
-            }catch (NullPointerException npe){
+            } catch (NullPointerException npe) {
                 return null;
             }
         }
@@ -98,10 +104,12 @@
         return null;
     }
 
+    @Override
     public Set keySet() {
         return Collections.EMPTY_SET;
     }
 
+    @Override
     public Object put(Object key, Object value) {
         PageContext pc = getPageContext();
         if (pc != null) {
@@ -111,18 +119,22 @@
         return null;
     }
 
+    @Override
     public void putAll(Map t) {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public Object remove(Object key) {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public int size() {
         throw new UnsupportedOperationException(UNSUPPORTED);
     }
 
+    @Override
     public Collection values() {
         return Collections.EMPTY_SET;
     }
diff --git a/plugins/json/src/main/java/org/apache/struts2/json/JSONUtil.java b/plugins/json/src/main/java/org/apache/struts2/json/JSONUtil.java
index 8c443e5..f8c5683 100644
--- a/plugins/json/src/main/java/org/apache/struts2/json/JSONUtil.java
+++ b/plugins/json/src/main/java/org/apache/struts2/json/JSONUtil.java
@@ -35,6 +35,7 @@
 import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.zip.GZIPOutputStream;
+import java.util.Arrays;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -410,7 +411,9 @@
     public static Method[] listSMDMethods(Class clazz, boolean ignoreInterfaces) {
         final List<Method> methods = new LinkedList<>();
         if (ignoreInterfaces) {
-            for (Method method : clazz.getMethods()) {
+            Method[] classMethods = clazz.getMethods();
+            Arrays.sort(classMethods, (a, b) -> a.toString().compareTo(b.toString()));
+            for (Method method : classMethods) {
                 SMDMethod smdMethodAnnotation = method.getAnnotation(SMDMethod.class);
                 if (smdMethodAnnotation != null) {
                     methods.add(method);
@@ -421,7 +424,9 @@
             // order encountered
             JSONUtil.visitInterfaces(clazz, new JSONUtil.ClassVisitor() {
                 public boolean visit(Class aClass) {
-                    for (Method method : aClass.getMethods()) {
+                    Method[] classMethods = aClass.getMethods();
+                    Arrays.sort(classMethods, (a, b) -> a.toString().compareTo(b.toString()));
+                    for (Method method : classMethods) {
                         SMDMethod smdMethodAnnotation = method.getAnnotation(SMDMethod.class);
                         if ((smdMethodAnnotation != null) && !methods.contains(method)) {
                             methods.add(method);