On Aug 23, 2013, at 5:25 PM, Mark Thomas <ma...@apache.org> wrote: > On 20/08/2013 16:46, Daniel Mikusa wrote: >> Hello, >> >> I'm seeing some perplexing errors with a couple simple EL test. > > Dan, > > These look like bugs. > > I've taken a quick look at the first and it is fixable if we copy the > smarter method finding code from ReflectionUtil in the implementation to > the Util class in the API. I'd like to avoid that much copying if I can > but I don't see an immediate way around it without creating unwanted > dependencies. > > The second issue will require a little more work as there isn't an > equivalent constructor finding method that can just be copied. > > It will probably be possible to share rather than duplicate code for the > method and the constructor matching. > > To add to the fun, I recall some sensitivities in the EL TCK around the > method matching. We are going to have to tread carefully. > > Please can you create a Bugzilla issue for these.
Certainly. Here's a link. https://issues.apache.org/bugzilla/show_bug.cgi?id=55483 Thanks Dan > > Thanks, > > Mark > >> >> 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. >> >> Anyone have any thoughts on this? On the surface, it seems like bug, but >> the paramTypes are being set to null in two different locations which makes >> me think that could be done for a specific reason. >> >> Thanks >> >> Dan >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org >> For additional commands, e-mail: users-h...@tomcat.apache.org >> > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org