You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2022/10/22 19:35:00 UTC
[jira] [Commented] (GROOVY-9771) STC: "putAt" shortcut notation to outer class private field from Closure leads to GroovyCastException
[ https://issues.apache.org/jira/browse/GROOVY-9771?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17622687#comment-17622687 ]
Eric Milles commented on GROOVY-9771:
-------------------------------------
https://github.com/apache/groovy/commit/29c485893478da32166dc01058a0b14fb20c90ea
> STC: "putAt" shortcut notation to outer class private field from Closure leads to GroovyCastException
> -----------------------------------------------------------------------------------------------------
>
> Key: GROOVY-9771
> URL: https://issues.apache.org/jira/browse/GROOVY-9771
> Project: Groovy
> Issue Type: Bug
> Components: Static compilation
> Affects Versions: 3.0.6
> Environment: openjdk version "1.8.0_265"
> OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_265-b01)
> OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.265-b01, mixed mode)
> Groovy 3.0.6
> Gradle 6.6.1
> JUnit 5.7.0
> ASM 9.0
> Reporter: Frédéric Chuong
> Assignee: Eric Milles
> Priority: Major
> Fix For: 3.0.7, 4.0.0-alpha-2, 2.5.15
>
> Time Spent: 50m
> Remaining Estimate: 0h
>
> Given the following usage of the "putAt" shortcut notation to alter an outer class private field:
> {code:Groovy}
> import groovy.transform.CompileStatic
> import org.junit.jupiter.api.Test
> import org.objectweb.asm.ClassReader
> import org.objectweb.asm.util.TraceClassVisitor
> @CompileStatic
> class Bar {
> private Map<String, Boolean> map = [:]
> @Test
> void test() {
> { ->
> // troubleshooting only
> printClass(new Exception().stackTrace[0].className)
> map['foo'] = true // line 16
> }.call()
> }
> static void printClass(String className) {
> new ClassReader(className).accept(new TraceClassVisitor(new PrintWriter(System.err)), ClassReader.EXPAND_FRAMES)
> }
> }
> {code}
> With Groovy 3.0.6, execution leads to the following error:
> {noformat}
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'Bar$_test_closure1@2a65fe7c' with class 'Bar$_test_closure1' to class 'Bar'
> at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:415)
> at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:329)
> at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:243)
> at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:615)
> at Bar$_test_closure1.doCall(Bar.groovy:16)
> 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 org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
> at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
> at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
> at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1034)
> at groovy.lang.Closure.call(Closure.java:412)
> at groovy.lang.Closure.call(Closure.java:406)
> at Bar.test(Bar.groovy:12)
> {noformat}
> This does not fail with Groovy 3.0.5.
> The bytecode for line 16 is different between 3.0.5 and 3.0.6:
> {panel:title=Groovy 3.0.6|borderColor=red}
> {noformat}
> L1
> LINENUMBER 16 L1
> ICONST_1
> ISTORE 1
> LDC LBar$_test_closure1;.class
> ALOAD 0
> LDC LBar;.class
> INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.castToType (Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
> CHECKCAST Bar
> INVOKESTATIC Bar.pfaccess$0 (LBar;)Ljava/util/Map;
> LDC "putAt"
> CHECKCAST java/lang/String
> ICONST_2
> ANEWARRAY java/lang/Object
> DUP
> ICONST_0
> LDC "foo"
> AASTORE
> DUP
> ICONST_1
> ILOAD 1
> INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;
> AASTORE
> INVOKESTATIC org/codehaus/groovy/runtime/ScriptBytecodeAdapter.invokeMethodN (Ljava/lang/Class;Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
> POP
> ILOAD 1
> INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;
> ARETURN
> {noformat}
> {panel}
> {panel:title=Groovy 3.0.5, no error|borderColor=green}
> {noformat}
> L1
> LINENUMBER 16 L1
> ICONST_1
> ISTORE 1
> ALOAD 0
> LDC "map"
> INVOKEINTERFACE groovy/lang/GroovyObject.getProperty (Ljava/lang/String;)Ljava/lang/Object; (itf)
> LDC "foo"
> ILOAD 1
> INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;
> INVOKESTATIC org/codehaus/groovy/runtime/DefaultGroovyMethods.putAt (Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V
> ACONST_NULL
> POP
> ILOAD 1
> INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;
> ARETURN
> {noformat}
> {panel}
> There was a previously fixed issue, [GROOVY-9385] fixed in 3.0.1, having similar conditions (\@CompileStatic, closure, private member), I'm not sure whether it's related.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)