As described in the javadoc [1], Module::isOpen(String pn) returns true if this module has opened a package unconditionally. It returns true only if the module declares "opens pn;" unconditionally in module-info.java.  Since java.base does not open "java.io" unconditionally, so isOpen("java.io”) returns false.

Mandy
[1] http://download.java.net/java/jdk9/docs/api/java/lang/Module.html#isOpen-java.lang.String-

On 8/15/17 6:09 PM, Russell Gold wrote:
I am clearly missing something, here. Using build 180, I have variables:

Method method, Class callingClass.

I evaluate:

callingClass.getModule() -
                -> java.lang.Module@2940 “unnamed module @f973499”
method.getDeclaringClass()
                -> java.lang.Class “class java.io.ObjectInputStream”
method.getDeclaringClass().getModule()
                -> java.lang.Module @2949 “module java.base"
method.getDeclaringClass().getModule().isOpen("java.io”)
                -> false // which I read as saying that package “java.io” in 
module java.base is NOT open to the unnamed module

but:

method.getDeclaringClass().getModule().isOpen("java.io", 
callingClass.getModule())
                -> true  // which seems to say that it IS open to that 
particular unnamed module ?!

of course, method.setAccessible(true) gives me the warning.

What am I missing?

Thanks,
Russ

On Jul 11, 2017, at 6:11 AM, Alan Bateman <alan.bate...@oracle.com> wrote:

On 11/07/2017 10:16, Uwe Schindler wrote:
:
Sorry, I mixed up the parameters. So basically the "correct" code to check if 
something like java.lang.String is open to Groovy would be:

Module groovyModule = CachedClass.class.getModule(); // 
org.codehaus.groovy.reflection.CachedClass;
Class clazz = String.class; // to test if open
return clazz.getModule().isOpen(String.class.getPackage().getName(), 
groovyModule);

If I do this, it returns "true" for String, Object or any other class. So the 
behaviour is consistent.
Yes, it has to be consistent.

As an aside, you can replace getPackage().getName() with getPackageName() - 
it's more efficient and avoids the NPE when the class is an array or primitive.


I implemented this check as a single MethodHandle to a precompiled method that takes 
a Class<?> and returns true/false if the Class is open to Groovy's module: 
https://goo.gl/XvdCQK
By this it's possible to execute this without a Java 9 at compile time. 
Unfortunately, it doesn't help, because java.base is open to unnamed module
Right, although isOpen("java.lang") will return false because the package is 
not open to all modules.


But now it is impossible for us to check, if something is not open by default.
Module::getDescriptor will return the module descriptor for named modules. So 
in this case, Object.class.getModule().getDescriptor() returns the 
ModuleDescriptor for java.base so you can inspect the packages and which are 
exported and/or opened before being changed by runtime. So there is enough in 
the API to determine which packages have been opened at runtime (either via CLI 
options or APIs).

-Alan

Reply via email to