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