You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2014/08/05 13:24:03 UTC

svn commit: r1615912 - in /tomcat/tc7.0.x/trunk: ./ java/javax/el/ java/org/apache/el/util/ test/org/apache/el/ webapps/docs/

Author: markt
Date: Tue Aug  5 11:24:03 2014
New Revision: 1615912

URL: http://svn.apache.org/r1615912
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56797
When matching a method in an EL expression, do not treat bridge methods as duplicates of the method they bridge to. In this case always call the target of the bridge method.

Modified:
    tomcat/tc7.0.x/trunk/   (props changed)
    tomcat/tc7.0.x/trunk/java/javax/el/Util.java
    tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java
    tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java
    tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java
    tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java
    tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml

Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
  Merged /tomcat/trunk:r1615911

Modified: tomcat/tc7.0.x/trunk/java/javax/el/Util.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/javax/el/Util.java?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/javax/el/Util.java (original)
+++ tomcat/tc7.0.x/trunk/java/javax/el/Util.java Tue Aug  5 11:24:03 2014
@@ -310,12 +310,13 @@ class Util {
                 return w;
             }
 
-            candidates.put(w, new MatchResult(exactMatch, assignableMatch, coercibleMatch));
+            candidates.put(w, new MatchResult(
+                    exactMatch, assignableMatch, coercibleMatch, w.isBridge()));
         }
 
         // Look for the method that has the highest number of parameters where
         // the type matches exactly
-        MatchResult bestMatch = new MatchResult(0, 0, 0);
+        MatchResult bestMatch = new MatchResult(0, 0, 0, false);
         Wrapper match = null;
         boolean multiple = false;
         for (Map.Entry<Wrapper, MatchResult> entry : candidates.entrySet()) {
@@ -662,6 +663,7 @@ class Util {
         public abstract Object unWrap();
         public abstract Class<?>[] getParameterTypes();
         public abstract boolean isVarArgs();
+        public abstract boolean isBridge();
     }
 
 
@@ -686,6 +688,11 @@ class Util {
         public boolean isVarArgs() {
             return m.isVarArgs();
         }
+
+        @Override
+        public boolean isBridge() {
+            return m.isBridge();
+        }
     }
 
     private static class ConstructorWrapper extends Wrapper {
@@ -709,6 +716,11 @@ class Util {
         public boolean isVarArgs() {
             return c.isVarArgs();
         }
+
+        @Override
+        public boolean isBridge() {
+            return false;
+        }
     }
 
     /*
@@ -720,11 +732,13 @@ class Util {
         private final int exact;
         private final int assignable;
         private final int coercible;
+        private final boolean bridge;
 
-        public MatchResult(int exact, int assignable, int coercible) {
+        public MatchResult(int exact, int assignable, int coercible, boolean bridge) {
             this.exact = exact;
             this.assignable = assignable;
             this.coercible = coercible;
+            this.bridge = bridge;
         }
 
         public int getExact() {
@@ -739,6 +753,10 @@ class Util {
             return coercible;
         }
 
+        public boolean isBridge() {
+            return bridge;
+        }
+
         @Override
         public int compareTo(MatchResult o) {
             if (this.getExact() < o.getExact()) {
@@ -756,7 +774,11 @@ class Util {
                     } else if (this.getCoercible() > o.getCoercible()) {
                         return 1;
                     } else {
-                        return 0;
+                        // The nature of bridge methods is such that it actually
+                        // doesn't matter which one we pick as long as we pick
+                        // one. That said, pick the 'right' one (the non-bridge
+                        // one) anyway.
+                        return Boolean.compare(o.isBridge(), this.isBridge());
                     }
                 }
             }

Modified: tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java (original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java Tue Aug  5 11:24:03 2014
@@ -218,12 +218,13 @@ public class ReflectionUtil {
                 return getMethod(base.getClass(), m);
             }
             
-            candidates.put(m, new MatchResult(exactMatch, assignableMatch, coercibleMatch));
+            candidates.put(m, new MatchResult(
+                    exactMatch, assignableMatch, coercibleMatch, m.isBridge()));
         }
 
         // Look for the method that has the highest number of parameters where
         // the type matches exactly
-        MatchResult bestMatch = new MatchResult(0, 0, 0);
+        MatchResult bestMatch = new MatchResult(0, 0, 0, false);
         Method match = null;
         boolean multiple = false;
         for (Map.Entry<Method, MatchResult> entry : candidates.entrySet()) {
@@ -450,11 +451,13 @@ public class ReflectionUtil {
         private final int exact;
         private final int assignable;
         private final int coercible;
+        private final boolean bridge;
 
-        public MatchResult(int exact, int assignable, int coercible) {
+        public MatchResult(int exact, int assignable, int coercible, boolean bridge) {
             this.exact = exact;
             this.assignable = assignable;
             this.coercible = coercible;
+            this.bridge = bridge;
         }
 
         public int getExact() {
@@ -469,6 +472,10 @@ public class ReflectionUtil {
             return coercible;
         }
 
+        public boolean isBridge() {
+            return bridge;
+        }
+
         @Override
         public int compareTo(MatchResult o) {
             if (this.getExact() < o.getExact()) {
@@ -486,7 +493,11 @@ public class ReflectionUtil {
                     } else if (this.getCoercible() > o.getCoercible()) {
                         return 1;
                     } else {
-                        return 0;
+                        // The nature of bridge methods is such that it actually
+                        // doesn't matter which one we pick as long as we pick
+                        // one. That said, pick the 'right' one (the non-bridge
+                        // one) anyway.
+                        return Boolean.compare(o.isBridge(), this.isBridge());
                     }
                 }
             }

Modified: tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java Tue Aug  5 11:24:03 2014
@@ -476,4 +476,22 @@ public class TestMethodExpressionImpl {
         Integer result = (Integer) me.invoke(context, null);
         assertEquals(beanB.sayHello().length(), result.intValue());
     }
+
+
+    @Test
+    public void testBug56797a() {
+        MethodExpression me = factory.createMethodExpression(context,
+                "${beanAA.echo1('Hello World!')}", null , null);
+        Object r = me.invoke(context, null);
+        assertEquals("AA1Hello World!", r.toString());
+    }
+
+
+    @Test
+    public void testBug56797b() {
+        MethodExpression me = factory.createMethodExpression(context,
+                "${beanAA.echo2('Hello World!')}", null , null);
+        Object r = me.invoke(context, null);
+        assertEquals("AA2Hello World!", r.toString());
+    }
 }

Modified: tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java Tue Aug  5 11:24:03 2014
@@ -56,4 +56,12 @@ public class TesterBeanA {
     public void setValList(List<?> valList) {
         this.valList = valList;
     }
+
+    public CharSequence echo1(CharSequence cs) {
+        return "A1" + cs;
+    }
+
+    public CharSequence echo2(String s) {
+        return "A2" + s;
+    }
 }

Modified: tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java (original)
+++ tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java Tue Aug  5 11:24:03 2014
@@ -18,6 +18,14 @@
 package org.apache.el;
 
 public class TesterBeanAA extends TesterBeanA {
-    // No additional implementation - just need a class that extends A for
-    // testing EL methods calls
+
+    @Override
+    public String echo1(CharSequence cs) {
+        return "AA1" + cs.toString();
+    }
+
+    @Override
+    public String echo2(String s) {
+        return "AA2" + s;
+    }
 }

Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1615912&r1=1615911&r2=1615912&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Tue Aug  5 11:24:03 2014
@@ -84,6 +84,15 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="Jasper">
+    <changelog>
+      <fix>
+        <bug>56797</bug>: When matching a method in an EL expression, do not
+        treat bridge methods as duplicates of the method they bridge to. In this
+        case always call the target of the bridge method. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="WebSocket">
     <changelog>
       <fix>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1615912 - in /tomcat/tc7.0.x/trunk: ./ java/javax/el/ java/org/apache/el/util/ test/org/apache/el/ webapps/docs/

Posted by Mark Thomas <ma...@apache.org>.
On 05/08/2014 13:49, Konstantin Kolinko wrote:
> 2014-08-05 15:24 GMT+04:00  <ma...@apache.org>:
>> Author: markt
>> Date: Tue Aug  5 11:24:03 2014
>> New Revision: 1615912
>>
>> URL: http://svn.apache.org/r1615912
>> Log:
>> Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56797
>> When matching a method in an EL expression, do not treat bridge methods as duplicates of the method they bridge to. In this case always call the target of the bridge method.
>>
>> Modified:
>>     tomcat/tc7.0.x/trunk/   (props changed)
>>     tomcat/tc7.0.x/trunk/java/javax/el/Util.java
>>     tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java
>>     tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java
>>     tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java
>>     tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java
>>     tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
>>
> 
> in 2 classes Util.java and ReflectionUtil.java the following line does
> not compile with Java 6, because Boolean.compare() is @since 1.7.
> 
>> +                        return Boolean.compare(o.isBridge(), this.isBridge());

Thanks. I missed that as my IDE is configured to use Java 7 so WebSocket
compiles.

Mark


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: svn commit: r1615912 - in /tomcat/tc7.0.x/trunk: ./ java/javax/el/ java/org/apache/el/util/ test/org/apache/el/ webapps/docs/

Posted by Konstantin Kolinko <kn...@gmail.com>.
2014-08-05 15:24 GMT+04:00  <ma...@apache.org>:
> Author: markt
> Date: Tue Aug  5 11:24:03 2014
> New Revision: 1615912
>
> URL: http://svn.apache.org/r1615912
> Log:
> Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=56797
> When matching a method in an EL expression, do not treat bridge methods as duplicates of the method they bridge to. In this case always call the target of the bridge method.
>
> Modified:
>     tomcat/tc7.0.x/trunk/   (props changed)
>     tomcat/tc7.0.x/trunk/java/javax/el/Util.java
>     tomcat/tc7.0.x/trunk/java/org/apache/el/util/ReflectionUtil.java
>     tomcat/tc7.0.x/trunk/test/org/apache/el/TestMethodExpressionImpl.java
>     tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanA.java
>     tomcat/tc7.0.x/trunk/test/org/apache/el/TesterBeanAA.java
>     tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
>

in 2 classes Util.java and ReflectionUtil.java the following line does
not compile with Java 6, because Boolean.compare() is @since 1.7.

> +                        return Boolean.compare(o.isBridge(), this.isBridge());

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org