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)