Better tools for adjusting to strong encapsulation
Claes Redestad
claes.redestad at oracle.com
Thu Mar 23 00:16:57 UTC 2017
On 2017-03-22 22:07, Jochen Theodorou wrote:
> On 22.03.2017 12:23, Alan Bateman wrote:
> [...]
>> I assume your interest is Groovy where there are indeed some warnings
>> that look like Groovy is to blame. For example, I get the following with
>> a trivial script containing`println "Hello world!"` :
>>
>> $ groovy hello.groovy
>> NOTE: Picked up the following options via JDK_JAVA_OPTIONS:
>> --permit-illegal-access
>> WARNING: --permit-illegal-access will be removed in the next major
>> release
>> WARNING: Illegal access by org.codehaus.groovy.reflection.CachedClass
>> (file:/groovy-2.4.10/lib/groovy-2.4.10.jar) to method
>> java.lang.Object.finalize() (permitted by --permit-illegal-access)
>> WARNING: Illegal access by org.codehaus.groovy.reflection.CachedClass
>> (file:/groovy-2.4.10/lib/groovy-2.4.10.jar) to method
>> java.lang.Object.clone() (permitted by --permit-illegal-access)
>> WARNING: Illegal access by org.codehaus.groovy.reflection.CachedClass
>> (file:/groovy-2.4.10/lib/groovy-2.4.10.jar) to method
>> java.lang.Object.registerNatives() (permitted by --permit-illegal-access)
>> WARNING: Illegal access by org.codehaus.groovy.vmplugin.v7.Java7$1
>> (file:/groovy-2.4.10/lib/groovy-2.4.10.jar) to constructor
>> java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int) (permitted by
>> --permit-illegal-access)
>> Hello world!
>>
>> The user's script is innocent but maybe you are saying that if Groovy
>> spins code and that code calls back into the Groovy runtime to do its
>> dirty work then Groovy will be blamed?
>
> the warnings you are seeing are from the groovy runtime trying to
> determine - in a pre JDK9 compatible way - if it is allowed to call the
> methods on Objecz. This happens in a first step by setAccessible on all
> methods using the array version, and if that fails by using the normal
> setAccessible on each method (which will contribute to much longer
> startup times). At no point our runtime or the program you wrote are
> trying to call finalize, clone or registerNatives.
For determining capabilities in this manner it might be possible to
use the new AccessibleObject.canAccess[1], which should avoid any
warnings?
/Claes
[1]
http://download.java.net/java/jdk9/docs/api/java/lang/reflect/AccessibleObject.html#canAccess-java.lang.Object-
>
> The only one we are to be blamed for is
> MethodHandles$Lookup(java.lang.Class,int), for which I haven´t
> implemented the alternative yet
>
> If you did other programs... like for example running a gradle build...
> you would see many many more such lines
>
>> On the question of performance then it may have an impact, it might not
>> as it depends on how much illegal access is going on. We see some
>> libraries doing some hacking with setAccessible(true) at startup and
>> then re-using the AccessibleObject over and over, they will hardly
>> notice anything.
>
> So it will not be on a invocation base with some kind of check if that
> has been locked already? Then I misunderstood
>
>> In the case of Groovy then running with
>> JDK_JAVA_OPTIONS="-Dsun.reflect.debugModuleAccessChecks=true" reveals
>> several places where InaccessibleObjectException is being thrown and
>> silently ignored, e.g:
>
> silently and purposely ignored.
>
>> java.lang.reflect.InaccessibleObjectException: Unable to make private
>> java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int) accessible:
>> module java.base does not "opens java.lang.invoke" to unnamed module
>> @43bd930a
>> at
>> java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
>>
>>
>> at
>> java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:281)
>>
>>
>> at
>> java.base/java.lang.reflect.Constructor.checkCanSetAccessible(Constructor.java:192)
>>
>>
>> at
>> java.base/java.lang.reflect.Constructor.setAccessible(Constructor.java:185)
>>
>> at org.codehaus.groovy.vmplugin.v7.Java7$1.run(Java7.java:53)
>> at java.base/java.security.AccessController.doPrivileged(Native
>> Method)
>> at org.codehaus.groovy.vmplugin.v7.Java7.<clinit>(Java7.java:50)
>> at
>> java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
>>
>> Method)
>> at
>> java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
>>
>>
>> at
>> java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
>>
>>
>> at
>> java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
>> at java.base/java.lang.Class.newInstance(Class.java:558)
>> at
>> org.codehaus.groovy.vmplugin.VMPluginFactory.createPlugin(VMPluginFactory.java:59)
>>
>>
>> at
>> org.codehaus.groovy.vmplugin.VMPluginFactory.<clinit>(VMPluginFactory.java:40)
>>
>>
>> at
>> org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:102)
>>
>>
>> at
>> org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.<init>(MetaClassRegistryImpl.java:74)
>>
>>
>> at groovy.lang.GroovySystem.<clinit>(GroovySystem.java:36)
>> at
>> org.codehaus.groovy.runtime.InvokerHelper.<clinit>(InvokerHelper.java:66)
>> at
>> groovy.lang.GroovyObjectSupport.<init>(GroovyObjectSupport.java:34)
>> at groovy.lang.Binding.<init>(Binding.java:35)
>> at groovy.lang.GroovyShell.<init>(GroovyShell.java:74)
>> at groovy.ui.GroovyMain.processOnce(GroovyMain.java:651)
>> at groovy.ui.GroovyMain.run(GroovyMain.java:384)
>> at groovy.ui.GroovyMain.process(GroovyMain.java:370)
>> at groovy.ui.GroovyMain.processArgs(GroovyMain.java:129)
>> at groovy.ui.GroovyMain.main(GroovyMain.java:109)
>> at
>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
>> Method)
>> at
>> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>>
>>
>> at
>> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>
>>
>> at java.base/java.lang.reflect.Method.invoke(Method.java:563)
>> at
>> org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109)
>>
>> at
>> org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131)
>> Hello world!
>>
>> So it might be that the cost of these exceptions is already high and
>> that doing illegal access (with --permit-illegal-access) will not be
>> noticed while the issues are being fixed.
>
> So you tell me that if I add an add-opens to java.base for all unnamed
> modules, I will still pay a performance penalty here? on each method
> invocation or only once?
>
> Also... be assured that people will notice, even if that means only that
> Groovy is much slower on JDK9 compared to JDK8
>
> bye Jochen
>
More information about the jigsaw-dev
mailing list