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.

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

Reply via email to