https://issues.apache.org/bugzilla/show_bug.cgi?id=55483
Bug ID: 55483
Summary: ELException when object has overloaded methods
Product: Tomcat 8
Version: trunk
Hardware: PC
OS: Mac OS X 10.4
Status: NEW
Severity: normal
Priority: P2
Component: EL
Assignee: [email protected]
Reporter: [email protected]
Included below are two test cases which fail. The first calls an overloaded
method on an object. The second calls an overloaded constructor. More details
below.
1.) Here's the first test.
@Test
public void test01() {
ELProcessor processor = new ELProcessor();
processor.defineBean("sb", new StringBuilder());
Assert.assertEquals("a", processor.eval("sb.append('a');
sb.toString()"));
}
This fails with the following stack trace.
javax.el.ELException: Cannot convert a of type class java.lang.String to long
at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:349)
at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:328)
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:450)
at
org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:48)
at javax.el.Util.buildParameters(Util.java:351)
at javax.el.BeanELResolver.invoke(BeanELResolver.java:173)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:84)
at org.apache.el.parser.AstValue.getValue(AstValue.java:157)
at org.apache.el.parser.AstSemicolon.getValue(AstSemicolon.java:35)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:188)
at javax.el.ELProcessor.getValue(ELProcessor.java:45)
at javax.el.ELProcessor.eval(ELProcessor.java:38)
at
org.apache.el.parser.TestAstMethodCalls.test01(TestAstMethodCalls.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Looking into this, it appears that the EL is having trouble because
StringBuilder's append method is overloaded. It is instructed to call append
with the character 'c', but instead is trying to coerce the character 'c' to a
long and call append with the long.
This chain of events seems to be kicked off in AstValue.getValue() line #157,
where it's calling resolver.invoke(..). The call to resolver.invoke() is
passing null as the paramTypes argument. This trickles down to
BeanELResolver.invoke(), which calls Util.findMethod(). Because paramTypes is
null, Util.findMethod() selects the first method it finds with the expected
number of arguments. In the case above, it selects StringBuilder.append(long),
which causes the problem above.
2.) Here's the second test.
@Test
public void test02() {
ELProcessor processor = new ELProcessor();
processor.getELManager().importClass("java.util.Date");
Date result = (Date) processor.eval("Date(86400)");
Assert.assertEquals(86400, result.getTime());
}
This one fails intermittently with the following stack trace.
javax.el.ELException: java.lang.IllegalArgumentException
at javax.el.StaticFieldELResolver.invoke(StaticFieldELResolver.java:118)
at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:84)
at org.apache.el.parser.AstFunction.getValue(AstFunction.java:138)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:188)
at javax.el.ELProcessor.getValue(ELProcessor.java:45)
at javax.el.ELProcessor.eval(ELProcessor.java:38)
at
org.apache.el.parser.TestAstMethodCalls.test02(TestAstMethodCalls.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalArgumentException
at java.util.Date.parse(Date.java:615)
at java.util.Date.<init>(Date.java:272)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at javax.el.StaticFieldELResolver.invoke(StaticFieldELResolver.java:111)
... 29 more
Looking into this error, it seems similar to #1. The difference is that
AstFunction.getValue() line #138 is calling invoke on the resolver and passing
null as the paramTypes. This trickles down to the
StaticFieldELResolver.invoke() method, which calls Util.findConstructor().
Again, because paramTypes is null, Util.findConstructor() searches the
available constructors for the one with the same number of arguments. The
reason that this intermittently fails is because on my system, the call to
Class.getConstructors() returns the list of constructs in an arbitrary order.
So it fails when Date(String) is listed first, but succeeds when Date(long) is
listed first.
--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]