Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spied object throws MissingMethodException when accessing a protected member of a superclass. #1608

Closed
jasongarrett opened this issue Mar 23, 2023 · 5 comments
Assignees
Labels
Milestone

Comments

@jasongarrett
Copy link

Describe the bug

If a class being spied accesses a protected property of a superclass, a MissingMethodException is thrown for the (nonexistent) synthetic getter.

To Reproduce

This example works correctly with Groovy 2.5 but fails with a MissingMethodException with Groovy 3 and Groovy 4.
https://gwc-experiment.appspot.com/?g=groovy_3_0&codez=eJxtT0sOgyAQ3XMKlrrxAE26adddadI1wliJCIQZ05rGu1etnxL7FgSY95mnW-8CcfRONpkR9pHlHqSutBSknWVMGoHIb_1FIFzn-5vxET44AkmgeOmcAWG5kBIQdWmAnzmFDtiwy79SeBFY9c9uNVEOsKg13l1oknQZTghAXfgNmSfDIaMApC0n6rKYKag41TDxooBnDfa0vSasW7d97vux03gmy1-6Eekgm-lZXGRflkXcD-B6dDM

Expected behavior

Protected superclass properties can be accessed normally.

Actual behavior

An attempt is made to use a generated getter and a MissingMethodException is thrown.

Java version

OpenJDK Runtime Environment Temurin-11.0.16.1+1 (build 11.0.16.1+1), and whatever version gwc-experiment.appspot.com using.

Buildtool version

Gradle 5.6.4 and gwc-experiment.appspot.com

What operating system are you using

Mac

Dependencies

"groovyVersion": "3.0.15",
"spockVersion": "2.3.0-groovy-3.0"

Additional context

No response

@leonard84
Copy link
Member

leonard84 commented Mar 28, 2023

Accessing the field directly works as expected, as well as accessing a protected method. It also works for statically compiled code.

@jasongarrett
Copy link
Author

jasongarrett commented Mar 28, 2023

It does not work for statically compiled code when access is in a closure. Accessing the field directly does still work in this case.

@jasongarrett
Copy link
Author

Access to the "log" member created by @slf4j does not work from within a closure in a spied class.

@AndreasTu
Copy link
Member

#1729 would fix this issue

@AndreasTu AndreasTu self-assigned this Aug 14, 2023
AndreasTu added a commit to AndreasTu/spock that referenced this issue Aug 25, 2023
The Groovy 3 & 4 runtime expects to have the @internal annotation on the MOP methods from GroovyObject.
That AbstractCallSite.createGroovyObjectGetPropertySite() processes it as GroovyObject.
So the ByteBuddyMockFactory now adds the @internal annotation to the intercepted MOP methods.

After that the "Unable to access protected constant when spying instances" problems are gone,
because we take the normal Groovy route.

Also some strange inconsistencies for Groovy  2 <=> 3,4 are now gone,
but a new inconsistency appeared Groovy 4 prefers is over get for boolean.
But this is not a Spock issue, because in Groovy only code the same thing happens.
See tests in JavaMocksForGroovyClasses.

The test "Access protected fields Issue spockframework#1452" covers the
"MissingMethodException when accessing fields without explicit @" issue.

This fixes spockframework#1145, spockframework#1452, spockframework#1501, spockframework#1608

Co-authored-by: Björn Kautler <Bjoern@Kautler.net>
AndreasTu added a commit to AndreasTu/spock that referenced this issue Aug 25, 2023
The Groovy 3 & 4 runtime expects to have the @internal annotation on the MOP methods from GroovyObject.
That AbstractCallSite.createGroovyObjectGetPropertySite() processes it as GroovyObject.
So the ByteBuddyMockFactory now adds the @internal annotation to the intercepted MOP methods.

After that the "Unable to access protected constant when spying instances" problems are gone,
because we take the normal Groovy route.

Also some strange inconsistencies for Groovy  2 <=> 3,4 are now gone,
but a new inconsistency appeared Groovy 4 prefers is over get for boolean.
But this is not a Spock issue, because in Groovy only code the same thing happens.
See tests in JavaMocksForGroovyClasses.

The test "Access protected fields Issue spockframework#1452" covers the
"MissingMethodException when accessing fields without explicit @" issue.

This fixes spockframework#1145, spockframework#1452, spockframework#1501, spockframework#1608

Co-authored-by: Björn Kautler <Bjoern@Kautler.net>
leonard84 added a commit that referenced this issue Sep 15, 2023
#1729)

The Groovy 3 & 4 runtime expects to have the `@Internal` annotation on the MOP methods from `GroovyObject`. That `AbstractCallSite.createGroovyObjectGetPropertySite()` processes it as `GroovyObject`. So the `ByteBuddyMockFactory` now adds the `@Internal` annotation to the intercepted MOP methods.

After that the "Unable to access protected constant when spying instances" problems are gone, because we take the normal Groovy route.

Also some strange inconsistencies for Groovy  2 <=> 3,4 are now gone, but a new inconsistency appeared Groovy 4 prefers is over get for boolean. But this is not a Spock issue, because in Groovy only code the same thing happens. See tests in JavaMocksForGroovyClasses.

This fixes #1501, #1452, #1608 and #1145.

Co-authored-by: Björn Kautler <Bjoern@Kautler.net>
Co-authored-by: Leonard Brünings <leonard.bruenings@gradle.com>
@AndreasTu
Copy link
Member

Was fixed by #1729

@AndreasTu AndreasTu added this to the 2.4 milestone Feb 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants