You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2021/10/29 20:34:00 UTC

[jira] [Resolved] (GROOVY-7004) No such property error with a private constant

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

Eric Milles resolved GROOVY-7004.
---------------------------------
    Resolution: Duplicate

There are several tickets open for accessing private members from a closure.  This construct breaks down when the class is extended.  If the class in question, TestBase in this case, is tagged with {{@groovy.transform.ComileStatic}} then the necessary bridge methods are created and the private access is stable.

See GROOVY-9987, GROOVY-8905, GROOVY-8854, GROOVY-7375, GROOVY-6335, GROOVY-5438, GROOVY-5051 and GROOVY-2433

> No such property error with a private constant
> ----------------------------------------------
>
>                 Key: GROOVY-7004
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7004
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 2.3.6
>            Reporter: Mauro Molinari
>            Assignee: Eric Milles
>            Priority: Major
>
> Consider the following Groovy classes:
> {code}
> package test2
> import groovy.beans.Bindable;
> import groovy.transform.CompileStatic;
> class MyBean {
>   @Bindable
>   String foo
>   String bar
> }
> {code}
> {code}
> package test2
> import groovy.transform.CompileStatic
> import java.beans.PropertyChangeEvent
> class TestBase {
> 	private static final String CONSTANT = 'foo'
> 	MyBean mb = new MyBean()
> 	void doSomething() {
> 		mb.with {
> 			addPropertyChangeListener('foo') { PropertyChangeEvent event ->
> 				bar = (event.newValue == CONSTANT)? 'bar': null
> 			}
> 			foo = CONSTANT
> 		}
> 	}
> }
> {code}
> {code}
> package test2
> import groovy.transform.CompileStatic;
> class TestExt extends TestBase {
> 	static void main(String[] args) {
> 		TestBase b = new TestBase()
> 		b.doSomething()
> 		println b.mb.bar
> 		
> 		TestExt e = new TestExt()
> 		e.doSomething()
> 		println e.mb.bar
> 	}
> }
> {code}
> Run as a Groovy script. The output is this:
> {noformat}
> bar
> Caught: groovy.lang.MissingPropertyException: No such property: CONSTANT for class: test2.MyBean
> groovy.lang.MissingPropertyException: No such property: CONSTANT for class: test2.MyBean
> 	at test2.TestBase$_doSomething_closure1_closure2.doCall(TestBase.groovy:16)
> 	at com.sun.proxy.$Proxy4.propertyChange(Unknown Source)
> 	at java_beans_PropertyChangeSupport$firePropertyChange$0.call(Unknown Source)
> 	at test2.MyBean.firePropertyChange(MyBean.groovy)
> 	at test2.MyBean$firePropertyChange.callCurrent(Unknown Source)
> 	at test2.MyBean.setFoo(MyBean.groovy)
> 	at test2.MyBean.setProperty(MyBean.groovy)
> 	at test2.TestBase$_doSomething_closure1.doCall(TestBase.groovy:18)
> 	at test2.TestBase.doSomething(TestBase.groovy:14)
> 	at test2.TestBase$doSomething.call(Unknown Source)
> 	at test2.TestExt.main(TestExt.groovy:13)
> {noformat}
> If you then change the visibility of {{CONSTANT}} from private to protected, then the output is correct:
> {noformat}
> bar
> bar
> {noformat}
> It seems like the closure that implements the {{PropertyChangeListener}}, when executed from {{TestExt}}, is searching for {{TestExt.CONSTANT}} first, and then for {{MyBean.CONSTANT}}, and not seeing it because of the private modifier. However, I would expect it to refer to {{TestBase.CONSTANT}} in any case...



--
This message was sent by Atlassian Jira
(v8.3.4#803005)