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
+ '''
}
}