[ https://issues.apache.org/jira/browse/GROOVY-9081?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Daniel Sun updated GROOVY-9081: ------------------------------- Description: This cloned issue is to cover the rest part of case ② as mentioned in GROOVY-8339. h4. 1) Sub-class derives the public members from {{package-private}} class, but invoke the members on the sub class instances, e.g. *-1.0) Non-category-* [https://github.com/apache/groovy/blob/master/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy#L532] *-1.1) Category-* [https://github.com/apache/groovy/blob/master/src/spec/test/TraitsSpecificationTest.groovy#L835] h4. 2) Sub-class derives the {{protected}} members from public class, *2.0) Invoke the members on the sub class instances, e.g.* [https://github.com/apache/groovy/blob/master/subprojects/groovy-swing/src/test/groovy/groovy/beans/BindableSwingTest.groovy#L31-L40] We are considering to generate stub/bridge methods automatically. {color:#d04437}_*2.1) Clone array via {{clone}} method of {{java.lang.Object}} ( Note: the method is {{protected}}, truely illegal access, we should fix our code), e.g.*_{color} [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/ImmutableTransformTest.groovy#L163-L180] As we can see, {{groovy.transform.Immutable}} will generate the code to invoke {{clone}} on array object: {code:java} @groovy.transform.Generated public HasList(java.util.Map args) { metaClass = /*BytecodeExpression*/ if ( args == null) { args = [:] } org.codehaus.groovy.transform.ImmutableASTTransformation.checkPropNames(this, args) if ( args .letters == null) { this .letters = null } else { this .letters = ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .letters, 'clone', new java.lang.Object[][])) as java.lang.String[]) } if ( args .nums == null) { this .nums = null } else { if ( args .nums instanceof java.lang.Cloneable) { this .nums = ((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.SortedSet ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.SortedSet<E extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.SortedMap ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.Set ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Set<E extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.Map ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.List ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.List<E extends java.lang.Object>) : org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Collection)) as java.lang.Object) } else { this .nums = (( args .nums instanceof java.util.SortedSet ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.SortedSet<E extends java.lang.Object>) : args .nums instanceof java.util.SortedMap ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) : args .nums instanceof java.util.Set ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Set<E extends java.lang.Object>) : args .nums instanceof java.util.Map ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : args .nums instanceof java.util.List ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.List<E extends java.lang.Object>) : org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Collection)) as java.lang.Object) } } } {code} {color:#d04437}_*2.2) Access the overrided {{protected}} method of sub-class(Truely illegal access, we should fix our code), e.g.*_{color} [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy#L124] {{AppClassLoader}} derives {{ClassLoader}}, but {{Class<?> loadClass(String cn, boolean resolve)}} of {{AppClassLoader}} is still {{protected}}, we should not access it if we do not want warnings. {color:#d04437}_*2.3) Access the {{protected final}} method(Truely illegal access, we should fix our code), e.g.*_{color} [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/reflection/SecurityTest.java#L243-L258] {{protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, ProtectionDomain protectionDomain)}} of {{ClassLoader}} h4. -3) Access {{public}} members of {{private}} class, e.g.- [https://github.com/apache/groovy/blob/master/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ScriptToTreeNodeAdapter.groovy#L235] {{java.util.Collections.UnmodifiableMap::toString}} We should try to find the overrided member of its base class and access(virtual invocation will happen eventually) h4. -4) Access {{public}} members of {{package-private}} class, e.g.- [https://github.com/apache/groovy/blob/master/src/spec/test/gdk/WorkingWithIOSpecTest.groovy#L355] {{java.lang.ProcessImpl::waitFor}} We should try to find the overrided member of its base class and access(virtual invocation will happen eventually) h4. -5) Favor the method with more accurate parameter type even if it is not visible, e.g. {{EnumMap::equals(EnumMap<?,?>)}}- [https://github.com/apache/groovy/blob/master/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/ASTComparatorCategory.groovy#L271] When comparing two {{ClassNode}} instances, {{ClassNode.transformInstances}} will be compared, their type is {{EnumMap}} h4. 6) Get {{properties}} of objects(including {{private}} methods) [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy#L68] {{''.properties}} will access {{java.lang.String.isLatin1}}, which is {{private}} h4. 7) Access non-visible constructor when {{as}} type, e.g. [https://github.com/apache/groovy/blob/master/src/test/groovy/lang/MapOfClosureTest.groovy#L57] The constructor of {{TimerTask}} is {{protected}} h4. {color:#d04437}_8) Explicitly invoke {{setAccessible}} (Truely illegal access, we should fix our code), e.g._{color} [https://github.com/apache/groovy/blob/master/src/test/groovy/transform/ThreadInterruptTest.groovy#L65] was: This cloned issue is to cover the rest part of case ② as mentioned in GROOVY-8339. h4. 1) Sub-class derives the public members from {{package-private}} class, but invoke the members on the sub class instances, e.g. *-1.0) Non-category-* [https://github.com/apache/groovy/blob/master/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy#L532] *-1.1) Category-* [https://github.com/apache/groovy/blob/master/src/spec/test/TraitsSpecificationTest.groovy#L835] h4. 2) Sub-class derives the {{protected}} members from public class, *2.0) Invoke the members on the sub class instances, e.g.* [https://github.com/apache/groovy/blob/master/subprojects/groovy-swing/src/test/groovy/groovy/beans/BindableSwingTest.groovy#L31-L40] We are considering to generate stub/bridge methods automatically. _*2.1) Clone array via {{clone}} method of {{java.lang.Object}} ( Note: the method is {{protected}}, truely illegal access, we should fix our code), e.g.*_ [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/ImmutableTransformTest.groovy#L163-L180] As we can see, {{groovy.transform.Immutable}} will generate the code to invoke {{clone}} on array object: {code:java} @groovy.transform.Generated public HasList(java.util.Map args) { metaClass = /*BytecodeExpression*/ if ( args == null) { args = [:] } org.codehaus.groovy.transform.ImmutableASTTransformation.checkPropNames(this, args) if ( args .letters == null) { this .letters = null } else { this .letters = ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .letters, 'clone', new java.lang.Object[][])) as java.lang.String[]) } if ( args .nums == null) { this .nums = null } else { if ( args .nums instanceof java.lang.Cloneable) { this .nums = ((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.SortedSet ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.SortedSet<E extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.SortedMap ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.Set ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Set<E extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.Map ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof java.util.List ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.List<E extends java.lang.Object>) : org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as java.util.Collection)) as java.lang.Object) } else { this .nums = (( args .nums instanceof java.util.SortedSet ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.SortedSet<E extends java.lang.Object>) : args .nums instanceof java.util.SortedMap ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) : args .nums instanceof java.util.Set ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Set<E extends java.lang.Object>) : args .nums instanceof java.util.Map ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : args .nums instanceof java.util.List ? org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.List<E extends java.lang.Object>) : org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as java.util.Collection)) as java.lang.Object) } } } {code} _*2.2) Access the overrided {{protected}} method of sub-class(Truely illegal access, we should fix our code), e.g.*_ [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy#L124] {{AppClassLoader}} derives {{ClassLoader}}, but {{Class<?> loadClass(String cn, boolean resolve)}} of {{AppClassLoader}} is still {{protected}}, we should not access it if we do not want warnings. _*2.3) Access the {{protected final}} method(Truely illegal access, we should fix our code), e.g.*_ [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/reflection/SecurityTest.java#L243-L258] {{protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, ProtectionDomain protectionDomain)}} of {{ClassLoader}} h4. -3) Access {{public}} members of {{private}} class, e.g.- [https://github.com/apache/groovy/blob/master/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ScriptToTreeNodeAdapter.groovy#L235] {{java.util.Collections.UnmodifiableMap::toString}} We should try to find the overrided member of its base class and access(virtual invocation will happen eventually) h4. -4) Access {{public}} members of {{package-private}} class, e.g.- [https://github.com/apache/groovy/blob/master/src/spec/test/gdk/WorkingWithIOSpecTest.groovy#L355] {{java.lang.ProcessImpl::waitFor}} We should try to find the overrided member of its base class and access(virtual invocation will happen eventually) h4. -5) Favor the method with more accurate parameter type even if it is not visible, e.g. {{EnumMap::equals(EnumMap<?,?>)}}- [https://github.com/apache/groovy/blob/master/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/ASTComparatorCategory.groovy#L271] When comparing two {{ClassNode}} instances, {{ClassNode.transformInstances}} will be compared, their type is {{EnumMap}} h4. 6) Get {{properties}} of objects(including {{private}} methods) [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy#L68] {{''.properties}} will access {{java.lang.String.isLatin1}}, which is {{private}} h4. 7) Access non-visible constructor when {{as}} type, e.g. [https://github.com/apache/groovy/blob/master/src/test/groovy/lang/MapOfClosureTest.groovy#L57] The constructor of {{TimerTask}} is {{protected}} h4. _8) Explicitly invoke {{setAccessible}} (Truely illegal access, we should fix our code), e.g._ [https://github.com/apache/groovy/blob/master/src/test/groovy/transform/ThreadInterruptTest.groovy#L65] > CLONE - Fix warning "An illegal reflective access operation has occurred" > ------------------------------------------------------------------------- > > Key: GROOVY-9081 > URL: https://issues.apache.org/jira/browse/GROOVY-9081 > Project: Groovy > Issue Type: Improvement > Components: groovy-jdk > Affects Versions: 2.4.11, 2.4.15 > Environment: >gradle --version > Gradle 4.2 > Build time: 2017-09-20 14:48:23 UTC > Revision: 5ba503cc17748671c83ce35d7da1cffd6e24dfbd > Groovy: 2.4.11 > Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 > JVM: 9 (Oracle Corporation 9+181) > OS: Windows 10 10.0 amd64 > Reporter: Benjamin Roedell > Priority: Major > Time Spent: 1h 10m > Remaining Estimate: 0h > > This cloned issue is to cover the rest part of case ② as mentioned in > GROOVY-8339. > h4. 1) Sub-class derives the public members from {{package-private}} class, > but invoke the members on the sub class instances, e.g. > *-1.0) Non-category-* > > [https://github.com/apache/groovy/blob/master/subprojects/groovy-groovysh/src/main/groovy/org/codehaus/groovy/tools/shell/Groovysh.groovy#L532] > *-1.1) Category-* > > [https://github.com/apache/groovy/blob/master/src/spec/test/TraitsSpecificationTest.groovy#L835] > h4. 2) Sub-class derives the {{protected}} members from public class, > *2.0) Invoke the members on the sub class instances, e.g.* > > [https://github.com/apache/groovy/blob/master/subprojects/groovy-swing/src/test/groovy/groovy/beans/BindableSwingTest.groovy#L31-L40] > We are considering to generate stub/bridge methods automatically. > {color:#d04437}_*2.1) Clone array via {{clone}} method of > {{java.lang.Object}} ( Note: the method is {{protected}}, truely illegal > access, we should fix our code), e.g.*_{color} > > [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/ImmutableTransformTest.groovy#L163-L180] > As we can see, {{groovy.transform.Immutable}} will generate the code to > invoke {{clone}} on array object: > {code:java} > @groovy.transform.Generated > public HasList(java.util.Map args) { > metaClass = /*BytecodeExpression*/ > if ( args == null) { > args = [:] > } > > org.codehaus.groovy.transform.ImmutableASTTransformation.checkPropNames(this, > args) > if ( args .letters == null) { > this .letters = null > } else { > this .letters = > ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .letters, > 'clone', new java.lang.Object[][])) as java.lang.String[]) > } > if ( args .nums == null) { > this .nums = null > } else { > if ( args .nums instanceof java.lang.Cloneable) { > this .nums = > ((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, > 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof > java.util.SortedSet ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.SortedSet<E extends java.lang.Object>) : > ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, > 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof > java.util.SortedMap ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) > : ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, > 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof > java.util.Set ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.Set<E extends java.lang.Object>) : > ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, > 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof > java.util.Map ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : > ((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( args .nums, > 'clone', new java.lang.Object[][])) as java.lang.Object) instanceof > java.util.List ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.List<E extends java.lang.Object>) : > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable((((org.codehaus.groovy.runtime.ReflectionMethodInvoker.invoke( > args .nums, 'clone', new java.lang.Object[][])) as java.lang.Object)) as > java.util.Collection)) as java.lang.Object) > } else { > this .nums = (( args .nums instanceof java.util.SortedSet ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.SortedSet<E extends java.lang.Object>) : args .nums instanceof > java.util.SortedMap ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.SortedMap<K extends java.lang.Object, V extends java.lang.Object>) > : args .nums instanceof java.util.Set ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.Set<E extends java.lang.Object>) : args .nums instanceof > java.util.Map ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.Map<K extends java.lang.Object, V extends java.lang.Object>) : args > .nums instanceof java.util.List ? > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.List<E extends java.lang.Object>) : > org.codehaus.groovy.runtime.DefaultGroovyMethods.asImmutable(( args .nums) as > java.util.Collection)) as java.lang.Object) > } > } > } > {code} > {color:#d04437}_*2.2) Access the overrided {{protected}} method of > sub-class(Truely illegal access, we should fix our code), e.g.*_{color} > > [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/transform/classloading/TransformsAndCustomClassLoadersTest.groovy#L124] > {{AppClassLoader}} derives {{ClassLoader}}, but {{Class<?> loadClass(String > cn, boolean resolve)}} of {{AppClassLoader}} is still {{protected}}, we > should not access it if we do not want warnings. > {color:#d04437}_*2.3) Access the {{protected final}} method(Truely illegal > access, we should fix our code), e.g.*_{color} > > [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/reflection/SecurityTest.java#L243-L258] > {{protected final Class<?> defineClass(String name, java.nio.ByteBuffer b, > ProtectionDomain protectionDomain)}} of {{ClassLoader}} > h4. -3) Access {{public}} members of {{private}} class, e.g.- > [https://github.com/apache/groovy/blob/master/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ScriptToTreeNodeAdapter.groovy#L235] > {{java.util.Collections.UnmodifiableMap::toString}} > We should try to find the overrided member of its base class and > access(virtual invocation will happen eventually) > h4. -4) Access {{public}} members of {{package-private}} class, e.g.- > [https://github.com/apache/groovy/blob/master/src/spec/test/gdk/WorkingWithIOSpecTest.groovy#L355] > {{java.lang.ProcessImpl::waitFor}} > We should try to find the overrided member of its base class and > access(virtual invocation will happen eventually) > h4. -5) Favor the method with more accurate parameter type even if it is not > visible, e.g. {{EnumMap::equals(EnumMap<?,?>)}}- > [https://github.com/apache/groovy/blob/master/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/ASTComparatorCategory.groovy#L271] > When comparing two {{ClassNode}} instances, {{ClassNode.transformInstances}} > will be compared, their type is {{EnumMap}} > h4. 6) Get {{properties}} of objects(including {{private}} methods) > [https://github.com/apache/groovy/blob/master/src/test/org/codehaus/groovy/classgen/asm/sc/ArraysAndCollectionsStaticCompileTest.groovy#L68] > {{''.properties}} will access {{java.lang.String.isLatin1}}, which is > {{private}} > h4. 7) Access non-visible constructor when {{as}} type, e.g. > [https://github.com/apache/groovy/blob/master/src/test/groovy/lang/MapOfClosureTest.groovy#L57] > The constructor of {{TimerTask}} is {{protected}} > h4. {color:#d04437}_8) Explicitly invoke {{setAccessible}} (Truely illegal > access, we should fix our code), e.g._{color} > [https://github.com/apache/groovy/blob/master/src/test/groovy/transform/ThreadInterruptTest.groovy#L65] -- This message was sent by Atlassian JIRA (v7.6.3#76005)