[ 
https://issues.apache.org/jira/browse/GROOVY-9081?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16832504#comment-16832504
 ] 

Daniel Sun edited comment on GROOVY-9081 at 5/3/19 1:49 PM:
------------------------------------------------------------

I am inclined to clone another issue to represent 2.1, 2.2, 2.3 as they are 
illegal access and have to be fixed by changing user's code(including the 
implementation of some AST Transformations)


was (Author: daniel_sun):
I am inclined to clone another issue to represent 2.1, 2.2, 2.3 as they are 
illegal access and have to be fixed by changing user's code

> 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.
>  _*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) Favor the {{private}} field over {{public}} getter method, e.g.
> [https://github.com/apache/groovy/blob/master/src/test/groovy/transform/ThreadInterruptTest.groovy#L66]
>  {{java.lang.reflect.Field::getModifiers}} should be access, but 
> {{java.lang.reflect.Field#modifiers}} is actually accessed.
> h4. 7) 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. 8) 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}}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to