You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2019/07/22 04:22:02 UTC

[jira] [Closed] (GROOVY-9103) CLONE - CLONE - Fix warning "An illegal reflective access operation has occurred"

     [ https://issues.apache.org/jira/browse/GROOVY-9103?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Paul King closed GROOVY-9103.
-----------------------------

> CLONE - CLONE - Fix warning "An illegal reflective access operation has occurred"
> ---------------------------------------------------------------------------------
>
>                 Key: GROOVY-9103
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9103
>             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
>            Assignee: Daniel Sun
>            Priority: Major
>              Labels: breaking_change
>             Fix For: 3.0.0-beta-2
>
>          Time Spent: 1h 50m
>  Remaining Estimate: 0h
>
> This cloned issue is to cover the rest part of GROOVY-9081.
> {color:#d04437}*Case 2, 8, 9* are illegal access and have to be fixed by changing user's code(including the implementation of some AST Transformations){color}
> h4. _{color:#d04437}2) Sub-class derives the {{protected}} members from public class,{color}_
> {color:#d04437}_*2.1) Clone array via {{clone}} method of {{java.lang.Object}} , use {{Arrays.copyOf}} instead ( 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. -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}}
> We fix the case by filtering non-properties and allow illegal access properties for backward compatibility via switching on JVM option {{-Dgroovy.allow.illegal.access.properties=true}}(Note: {{false}} is the default value)
> h4. {color:#d04437}_8) Access invisible members or 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]
> h4. {color:#d04437}9) Avoid use {{java.math.BigInteger.multiply(long)}}, and use {{BigInteger.multiply(BigInteger)}} instead*(Truely illegal access)*, e.g.{color}
> [https://github.com/apache/groovy/blob/master/src/test/groovy/transform/stc/STCAssignmentTest.groovy#L692]
>  *More examples:*
> {code:java}
> 1G * 2 // emits illegal access warnings
> 1G * 2G // Recommend to append "G" to the number to represent BigInteger, no illegal access warnings
> {code}
>  We make Groovy a bit smarter by find the proper method, i.e. {{BigInteger.multiply(BigInteger)}}



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)