ObjectRendererService fails to render objects with fields defined in a superclass #659

Open
facboy opened this Issue Oct 5, 2016 · 1 comment

Projects

None yet

2 participants

@facboy
facboy commented Oct 5, 2016

Issue description

The ObjectRenderService fails to render objects (eg beans) with fields defined in a superclass, it fails with a MissingFieldException.

How to reproduce

I encountered the issue using Intellij's test runner but I believe it's a general issue. Run the spec in the project below and then <Click to see difference> on one of the bean sub-class tests. You get the following error in the window:

Failed to render value due to:

groovy.lang.MissingFieldException: No such field: integer for class: org.facboy.MySubBean
    at groovy.lang.MetaClassImpl.getAttribute(MetaClassImpl.java:2823)
    at groovy.lang.MetaClassImpl.getAttribute(MetaClassImpl.java:3759)
    at org.codehaus.groovy.runtime.InvokerHelper.getAttribute(InvokerHelper.java:147)
    at org.spockframework.runtime.GroovyRuntimeUtil.getAttribute(GroovyRuntimeUtil.java:295)
    at org.spockframework.runtime.condition.DiffedObjectAsBeanRenderer.render(DiffedObjectAsBeanRenderer.java:28)
    at org.spockframework.runtime.condition.ObjectRendererService.render(ObjectRendererService.java:45)
    at org.spockframework.runtime.JUnitSupervisor.renderValue(JUnitSupervisor.java:148)
    at org.spockframework.runtime.JUnitSupervisor.convertToComparisonFailure(JUnitSupervisor.java:135)
    at org.spockframework.runtime.JUnitSupervisor.error(JUnitSupervisor.java:86)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:483)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:464)
    at org.spockframework.runtime.BaseSpecRunner.runFeatureMethod(BaseSpecRunner.java:406)
    at org.spockframework.runtime.BaseSpecRunner.doRunIteration(BaseSpecRunner.java:324)
    at org.spockframework.runtime.BaseSpecRunner$6.invoke(BaseSpecRunner.java:309)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:481)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:464)
    at org.spockframework.runtime.BaseSpecRunner.runIteration(BaseSpecRunner.java:288)
    at org.spockframework.runtime.BaseSpecRunner.initializeAndRunIteration(BaseSpecRunner.java:278)
    at org.spockframework.runtime.BaseSpecRunner.runSimpleFeature(BaseSpecRunner.java:269)
    at org.spockframework.runtime.BaseSpecRunner.doRunFeature(BaseSpecRunner.java:263)
    at org.spockframework.runtime.BaseSpecRunner$5.invoke(BaseSpecRunner.java:246)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:481)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:464)
    at org.spockframework.runtime.BaseSpecRunner.runFeature(BaseSpecRunner.java:238)
    at org.spockframework.runtime.BaseSpecRunner.runFeatures(BaseSpecRunner.java:188)
    at org.spockframework.runtime.BaseSpecRunner.doRunSpec(BaseSpecRunner.java:98)
    at org.spockframework.runtime.BaseSpecRunner$1.invoke(BaseSpecRunner.java:84)
    at org.spockframework.runtime.BaseSpecRunner.invokeRaw(BaseSpecRunner.java:481)
    at org.spockframework.runtime.BaseSpecRunner.invoke(BaseSpecRunner.java:464)
    at org.spockframework.runtime.BaseSpecRunner.runSpec(BaseSpecRunner.java:76)
    at org.spockframework.runtime.BaseSpecRunner.run(BaseSpecRunner.java:67)
    at org.spockframework.runtime.Sputnik.run(Sputnik.java:63)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Link to a gist or similar (optional)

https://github.com/facboy/spock-bug

Additional Environment information

Java/JDK

java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

Build tool version

Apache Maven

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T16:41:47+00:00)
Maven home: /opt/java/apache-maven
Java version: 1.8.0_102, vendor: Oracle Corporation
Java home: /usr/java/jdk1.8.0_102/jre
Default locale: en_GB, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-327.36.1.el7.x86_64", arch: "amd64", family: "unix"

Operating System

Distributor ID: CentOS
Description:    CentOS Linux release 7.2.1511 (Core)
Release:        7.2.1511
Codename:       Core

IDE

IntelliJ IDEA Ultimate 2016.2.4

Build-tool dependencies used

see git repo above

@leonard84
Contributor

Yes the problem is that GroovyRuntimeUtil.getAttribute can access private fields, but it does not traverse the inheritance chain upwards. However, DiffedObjectAsBeanRenderer checks all declared fields from parents as well. If we want to support that then we will have to resort to reflection.

https://stackoverflow.com/questions/35991804/field-access-in-groovy-for-super-class

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment