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

Reply via email to