You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "Howard M. Lewis Ship (JIRA)" <ji...@apache.org> on 2013/07/25 00:53:51 UTC

[jira] [Closed] (TAP5-2127) Access of Groovy field varies with configured production mode when accessing field inside closure

     [ 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