Scott Murphy Heiberg created GROOVY-12489:
---------------------------------------------

             Summary: Dynamic property access fails or bypasses 
getProperty/setProperty when the receiver class has no reflection metadata 
(GraalVM native image)
                 Key: GROOVY-12489
                 URL: https://issues.apache.org/jira/browse/GROOVY-12489
             Project: Groovy
          Issue Type: Bug
          Components: groovy-runtime
    Affects Versions: 6.0.0
            Reporter: Scott Murphy Heiberg


A dynamic property access that carries a sender has to know whether the 
receiver overrides the {{setProperty}} or {{getProperty}} that {{GroovyObject}} 
provides. Groovy answers this with {{Class.getMethod}} on every access:

* {{ScriptBytecodeAdapter.setProperty}}, {{setGroovyObjectProperty}} and 
{{getProperty}} let any exception from the lookup escape.
* The invokedynamic {{SetPropertySelector}} treats a failed lookup as an 
override.
* The invokedynamic {{PropertySelector}} goes to the meta-class instead, 
reading around the class's own {{getProperty}}.

Reflection over a class can fail while the class itself works. In a GraalVM 
native image without reflection metadata for the class, {{getMethod}} throws 
{{NoSuchMethodException}}. As a result, every write that carries a sender to 
such an object fails, and so does every read through the adapter. Reads through 
invokedynamic sites are answered by the meta-class instead, with a 
{{MissingPropertyException}}, or, when the meta-class knows the property 
through a registered superclass, with the wrong value and no error. 
Applications such as Grails register every Groovy class for reflection only so 
these checks can be answered. On the JVM, a public method naming a type absent 
at run time makes the lookups throw {{NoClassDefFoundError}}. And where 
reflection works, every access pays for a method search and a {{Method}} copy.

Proposed fix: cache each answer per class in a {{ClassValue}}, keeping the 
existing criteria, and when reflection cannot answer, treat the class as 
overriding so the access goes to the object's own method.

PR: https://github.com/apache/groovy/pull/3023



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to