[ 
https://issues.apache.org/jira/browse/TAP5-2127?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Howard M. Lewis Ship closed TAP5-2127.
--------------------------------------

    Resolution: Won't Fix

Unfortunately, Groovy appears to be creating bytecode that does not work with 
Tapestry when it generates closures. Tapestry is reliant on being able to see 
access to fields inside top-level and inner-classes; it rewrites field access 
into read and write methods. 

In development mode, the closure is able to read the field because Tapestry 
purposely leaves values inside the fields for debugging purposes.  In a 
production application, the page instances are shared across many threads, so 
this is turned off (it is also a potential memory leak).
                
> Access of Groovy field varies with configured production mode when accessing 
> field inside closure 
> --------------------------------------------------------------------------------------------------
>
>                 Key: TAP5-2127
>                 URL: https://issues.apache.org/jira/browse/TAP5-2127
>             Project: Tapestry 5
>          Issue Type: Bug
>          Components: plastic
>    Affects Versions: 5.3.7
>            Reporter: Uriah Carpenter
>            Priority: Critical
>
> Create a Groovy page class that contains a field that has private access. 
> Within a method, set the field to an initial value; use a Groovy closure to 
> access the field.
> When running with production-mode = FALSE everything works correctly.
> When running with production-mode = TRUE an NPE will be thrown when accessing 
> the field from inside the closure.
> This commit shows the an example of the problem: 
> https://github.com/Widen/tapestry5-idea/commit/9cb5be82db6ea917238aaf7e7b3f3e6067681913
> You can download and run the example from 
> https://github.com/Widen/tapestry5-idea
> Tested with Groovy version 2.0.8 and Tapestry 5.3.7
> The error stack trace is:
> <code>
> Caused by: java.lang.NullPointerException: Cannot invoke method leftShift() 
> on null object
>       at 
> org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:77) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:32) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> com.example.plaid.pages.PersistBug$_getOutput_closure1.doCall(PersistBug.groovy:32)
>  ~[tapestry5-idea/:na]
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
> ~[na:1.6.0_45]
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
> ~[na:1.6.0_45]
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>  ~[na:1.6.0_45]
>       at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_45]
>       at 
> org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at groovy.lang.Closure.call(Closure.java:412) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at groovy.lang.Closure.call(Closure.java:425) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1326)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1298)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at org.codehaus.groovy.runtime.dgm$148.invoke(Unknown Source) 
> ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at 
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
>  ~[groovy-all-2.0.8.jar:2.0.8]
>       at com.example.plaid.pages.PersistBug.getOutput(PersistBug.groovy:27) 
> ~[tapestry5-idea/:na]
>       at $InternalPropertyConduit_13053058e1131f47.get(Unknown Source) 
> ~[na:na]
>       at 
> org.apache.tapestry5.internal.bindings.PropBinding.get(PropBinding.java:59) 
> ~[tapestry-core-5.3.7.jar:na]
> </code>

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to