Details
-
Improvement
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.4.11, 2.4.15
Description
This cloned issue is to cover the rest part of GROOVY-9081.
Case 2, 8, 9 are illegal access and have to be fixed by changing user's code(including the implementation of some AST Transformations)
2) Sub-class derives the protected members from public class,
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.
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:
@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) } } }
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
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)
8) Access invisible members or explicitly invoke setAccessible (Truely illegal access, we should fix our code), e.g.
9) Avoid use java.math.BigInteger.multiply(long), and use BigInteger.multiply(BigInteger) instead*(Truely illegal access)*, e.g.
https://github.com/apache/groovy/blob/master/src/test/groovy/transform/stc/STCAssignmentTest.groovy#L692
More examples:
1G * 2 // emits illegal access warnings 1G * 2G // Recommend to append "G" to the number to represent BigInteger, no illegal access warnings
We make Groovy a bit smarter by find the proper method, i.e. BigInteger.multiply(BigInteger)
Attachments
Issue Links
- is a clone of
-
GROOVY-9081 CLONE - Fix warning "An illegal reflective access operation has occurred"
- Closed
- is cloned by
-
GROOVY-9144 Fix warning "An illegal reflective access operation has occurred"
- Closed
- is related to
-
GROOVY-9217 Fix warning "An illegal reflective access operation has occurred" when setting property
- Closed
- relates to
-
GROOVY-10931 Remove $getLookup method generation (Groovy 4+)
- Closed
- links to