[ 
https://issues.apache.org/jira/browse/GROOVY-11144?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17836812#comment-17836812
 ] 

Pavel Lobodinský edited comment on GROOVY-11144 at 4/13/24 11:56 AM:
---------------------------------------------------------------------

[~emilles] This piece of code was the simplest one I could come up with to 
demonstrate the problem. I suppose the catch-all mechanism was implemented in 
Groovy 4, was it? Because the code had worked in Groovy 3.

Anyway, the problem I am facing happens in Kafka tests. The test below verifies 
the content of a retrieved Kafka record.

In my project, the {{SimpleKafkaRecord}} is auto-generated from an AVRO schema. 
Because the {{SpecificRecordBase}} class implements
{code:groovy}
public Object get(String fieldName) { ... }
{code}
all the assertions referencing static fields have to be qualified with 
{{{}this{}}}. This was not the case with Groovy 3.

This is an example Kafka test:
{code:groovy}
import org.apache.avro.Schema
import org.apache.avro.specific.SpecificRecordBase
import spock.lang.Specification

class StaticPropertyIssueSpec extends Specification {

    static def tenantId = UUID.randomUUID()

    def "Verifies kafka record content"() {
        when:
        def simpleKafkaRecord = new SimpleKafkaRecord(id: tenantId, value: 
"Hello")

        then:
        verifyAll(simpleKafkaRecord) {
            id == tenantId
            value == "Hello"
        }
    }
}

class SimpleKafkaRecord extends SpecificRecordBase {
    UUID id
    String value

    private static def schema = new 
Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Data\",\"namespace\":\"foo.bar\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"value\",\"type\":\"string\"}]}")

    @Override Schema getSchema() { return schema }
    @Override Object get(int field) { return null }
    @Override void put(int field, Object value) { }
}
{code}
The returned assertion error looks like this:
{code:groovy}
Condition failed with Exception:

id == tenantId
|     |
|     org.apache.avro.AvroRuntimeException: Not a valid schema field: tenantId
|       at 
org.apache.avro.specific.SpecificRecordBase.get(SpecificRecordBase.java:71)
|       at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
|       at core.sim.mapper.StaticPropertyIssueSpec.Verifies kafka record 
content_closure1(StaticPropertyIssueSpec.groovy:17)
|       at spock.lang.Specification.verifyAll(Specification.java:281)
|       at core.sim.mapper.StaticPropertyIssueSpec.Verifies kafka record 
content(StaticPropertyIssueSpec.groovy:16)
5ce158e1-d0d5-4a55-af96-e262e624926c
{code}
The worst thing was the misleading error message and it took me a quite some 
time to figure the root cause out.


was (Author: JIRAUSER304862):
[~emilles] This piece of code was the simplest one I could come up with to 
demonstrate the problem. I suppose the catch-all mechanism was implemented in 
Groovy 4, was it? Because the code had worked in Groovy 3.

Anyway, the problem I am facing happens in Kafka tests. The test below verifies 
the content of a retrieved Kafka record.

In my project, the {{SimpleKafkaRecord}} is auto-generated from an AVRO schema. 
Because the {{SpecificRecordBase}} class implements
{code:groovy}
public Object get(String fieldName) { ... }
{code}
all the assertions referencing static fields have to be qualified with 
{{{}this{}}}. This was not the case with Groovy 3.

This is an example Kafka test:
{code:groovy}
import org.apache.avro.Schema
import org.apache.avro.specific.SpecificRecordBase
import spock.lang.Specification

class StaticPropertyIssueSpec extends Specification {

    static def tenantId = UUID.randomUUID()

    def "Verifies kafka record content"() {
        when:
        def simpleKafkaRecord = new SimpleKafkaRecord(id: tenantId, value: 
"Hello")

        then:
        verifyAll(simpleKafkaRecord) {
            id == tenantId
            value == "Hello"
        }
    }
}

class SimpleKafkaRecord extends SpecificRecordBase {
    UUID id
    String value

    private static def schema = new 
Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Data\",\"namespace\":\"foo.bar\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"value\",\"type\":\"string\"}]}")

    @Override Schema getSchema() { return schema }
    @Override Object get(int field) { return null }
    @Override void put(int field, Object value) { }
}
{code}
The worst thing was the misleading error message and it took me a quite some 
time to figure the root cause out.

The returned error looks like this:
{code:groovy}
Condition failed with Exception:

id == tenantId
|     |
|     org.apache.avro.AvroRuntimeException: Not a valid schema field: tenantId
|       at 
org.apache.avro.specific.SpecificRecordBase.get(SpecificRecordBase.java:71)
|       at groovy.lang.GroovyObject.getProperty(GroovyObject.java:50)
|       at core.sim.mapper.StaticPropertyIssueSpec.Verifies kafka record 
content_closure1(StaticPropertyIssueSpec.groovy:17)
|       at spock.lang.Specification.verifyAll(Specification.java:281)
|       at core.sim.mapper.StaticPropertyIssueSpec.Verifies kafka record 
content(StaticPropertyIssueSpec.groovy:16)
5ce158e1-d0d5-4a55-af96-e262e624926c
{code}

> MissingPropertyEx when accessing private static field in closure of same class
> ------------------------------------------------------------------------------
>
>                 Key: GROOVY-11144
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11144
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 4.0.13
>         Environment: Windows 10, Groovy 4.0.13, Java 17.0.8
>            Reporter: Andreas Turban
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 5.0.0-alpha-1
>
>         Attachments: Test.groovy
>
>
> When accessing a private static final field from a Closure within the same 
> class Groovy 4 throws a MissingPropertyException. The code works in Groovy 
> 2.5.22 & 3.0.18.
> The real instance of the object needs to be a subtype of the class containing 
> the constant.
> See attached code to reproduce.
> *Expected behavior:*
> The code runs without error
> *Actual behavior:*
> Groovy 4 throws:
> {{groovy.lang.MissingPropertyException: No such property: field for class: 
> FirstEvent}}
> {{    at BaseEvent$_init_closure1.doCall(Test.groovy:7)}}
> {{    at BaseEvent.init(Test.groovy:7)}}
> {{    at Test.run(Test.groovy:15)}}
> *Notes:*
> Interestingly if you remove the static keyword from {color:#0033b3}private 
> static final {color}{color:#000000}String {color}{color:#871094}field 
> {color}= {color:#067d17}"name"{color}
> it fails in all three versions 2.5.22, 3.0.18 & 4.0.13 with a 
> {{{}MissingPropertyException{}}}.
> I would expect that the code should also work for these cases.
>  
> The problem came up in a discussion about a Spock issue 
> [#1544|https://github.com/spockframework/spock/issues/1544].



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to