You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Daniel Sun (JIRA)" <ji...@apache.org> on 2019/05/03 13:45:00 UTC
[jira] [Comment Edited] (GROOVY-9081) CLONE - Fix warning "An
illegal reflective access operation has occurred"
[ 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:44 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
was (Author: daniel_sun):
I am inclined to clone another issue to represent 2.1, 2.2, 2.3
> 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)