On 21/03/2017 20:36, Jochen Theodorou wrote:


that means we will get a lot of users asking us, why our runtime does this, even though it is the "fault" of the code using the runtime and not really ours. Because "type that invoked the reflective operation" is very likely again something caller sensitive, right? Well, that will point to our runtime, not to the real perpetrator. I think there is an annotation that could be used to exclude our methods from getting the caller information, but if memory serves me right this is no public api.

What will be the performance penalty of this?
There isn't an annotation or anything else in this proposal to report a caller from further up the stack but there are several debugging options to reveal the stack traces when you need it (these debugging options have been in JDK 9 for a long time and are very useful).

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?

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.

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:

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.

-Alan

Reply via email to