You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/09/16 04:49:17 UTC

[groovy] 01/03: GROOVY-8284: getMetaClass should be annotated as (JavaBeans) transient (closes #1365)

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit cd6851945d3224ea3023385377c50ce1c15eb78f
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri Sep 11 20:56:02 2020 +1000

    GROOVY-8284: getMetaClass should be annotated as (JavaBeans) transient (closes #1365)
---
 src/main/java/groovy/lang/GroovyObjectSupport.java |  2 ++
 .../org/codehaus/groovy/classgen/Verifier.java     |  4 +++
 .../groovy/classgen/TransientMetaClassTest.groovy} | 37 ++++++++--------------
 3 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/src/main/java/groovy/lang/GroovyObjectSupport.java b/src/main/java/groovy/lang/GroovyObjectSupport.java
index 6c48cf3..4cfbfd4 100644
--- a/src/main/java/groovy/lang/GroovyObjectSupport.java
+++ b/src/main/java/groovy/lang/GroovyObjectSupport.java
@@ -20,6 +20,7 @@ package groovy.lang;
 
 import org.codehaus.groovy.runtime.InvokerHelper;
 
+import java.beans.Transient;
 import java.util.Optional;
 
 /**
@@ -31,6 +32,7 @@ public abstract class GroovyObjectSupport implements GroovyObject {
     private transient MetaClass metaClass = getDefaultMetaClass();
 
     @Override
+    @Transient
     public MetaClass getMetaClass() {
         return this.metaClass;
     }
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index c6ad11e..f6e5ff6 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -73,6 +73,7 @@ import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 
+import java.beans.Transient;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -145,6 +146,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
 
     private static final Class<?> GENERATED_ANNOTATION = Generated.class;
     private static final Class<?> INTERNAL_ANNOTATION = Internal.class;
+    private static final Class<?> TRANSIENT_ANNOTATION = Transient.class;
 
     // NOTE: timeStamp constants shouldn't belong to Verifier but kept here for binary compatibility
     public static final String __TIMESTAMP = "__timeStamp";
@@ -411,6 +413,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
         boolean shouldAnnotate = classNode.getModule().getContext() != null;
         AnnotationNode generatedAnnotation = shouldAnnotate ? new AnnotationNode(ClassHelper.make(GENERATED_ANNOTATION)) : null;
         AnnotationNode internalAnnotation = shouldAnnotate ? new AnnotationNode(ClassHelper.make(INTERNAL_ANNOTATION)) : null;
+        AnnotationNode transientAnnotation = shouldAnnotate ? new AnnotationNode(ClassHelper.make(TRANSIENT_ANNOTATION)) : null;
 
         if (!node.hasMethod("getMetaClass", Parameter.EMPTY_ARRAY)) {
             metaClassField = setMetaClassFieldIfNotExists(node, metaClassField);
@@ -457,6 +460,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
             if (shouldAnnotate) {
                 methodNode.addAnnotation(generatedAnnotation);
                 methodNode.addAnnotation(internalAnnotation);
+                methodNode.addAnnotation(transientAnnotation);
             }
         }
 
diff --git a/src/main/java/groovy/lang/GroovyObjectSupport.java b/src/test/org/codehaus/groovy/classgen/TransientMetaClassTest.groovy
similarity index 53%
copy from src/main/java/groovy/lang/GroovyObjectSupport.java
copy to src/test/org/codehaus/groovy/classgen/TransientMetaClassTest.groovy
index 6c48cf3..18265cf 100644
--- a/src/main/java/groovy/lang/GroovyObjectSupport.java
+++ b/src/test/org/codehaus/groovy/classgen/TransientMetaClassTest.groovy
@@ -16,31 +16,22 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package groovy.lang;
+package org.codehaus.groovy.classgen
 
-import org.codehaus.groovy.runtime.InvokerHelper;
+import groovy.test.GroovyTestCase
 
-import java.util.Optional;
+class TransientMetaClassTest extends GroovyTestCase {
+    // GROOVY-8284
+    void testGetMetaClassMethodIsDeemedTransient() {
+        assertScript '''
+            def gcl = new GroovyClassLoader()
+            def fooClass = gcl.parseClass('class Foo {}')
+            def fooInfo = java.beans.Introspector.getBeanInfo(fooClass)
+            assert fooInfo.propertyDescriptors.find{ it.name == 'metaClass' }.transient
 
-/**
- * Base class for Java objects wishing to be Groovy objects.
- */
-public abstract class GroovyObjectSupport implements GroovyObject {
-
-    // never persist the MetaClass
-    private transient MetaClass metaClass = getDefaultMetaClass();
-
-    @Override
-    public MetaClass getMetaClass() {
-        return this.metaClass;
-    }
-
-    @Override
-    public void setMetaClass(/*@Nullable*/ final MetaClass metaClass) {
-        this.metaClass = Optional.ofNullable(metaClass).orElseGet(this::getDefaultMetaClass);
-    }
-
-    private MetaClass getDefaultMetaClass() {
-        return InvokerHelper.getMetaClass(this.getClass());
+            Closure c = { -> }
+            def cInfo = java.beans.Introspector.getBeanInfo(c.getClass())
+            assert cInfo.propertyDescriptors.find{ it.name == 'metaClass' }.transient
+        '''
     }
 }