question on exports to

Alex Buckley alex.buckley at oracle.com
Wed Jun 1 00:37:39 UTC 2016


On 5/31/2016 5:09 PM, Jochen Theodorou wrote:
> On 31.05.2016 23:23, Alex Buckley wrote:
>> On 5/31/2016 1:40 PM, Jochen Theodorou wrote:
>>> named module GeneralInvoker, exports com.foo.gi.
>>>
>>> package com.foo.gi;
>>> public class TheInvoker{
>>>    public static Object invoke(Object receiver, String name, Object..
>>> args) {
>>>      Method m = receiver.getClass().getDeclaredMethod(name,
>>> toClass(args));
>>>     return m.invoke(args);
>>>    }
>>>     .....
>>> }
>>>
>>> named module MyOtherLib, requires GeneralInvoker, no exports
>>>
>>> package my.lib;
>>> public class SomeClassOfTheLibrary {
>>>    public void invokeBarOnArgument(Object x) {
>>>      TheInvoker.invoke(x, "bar");
>>>    }
>>>    ....
>>> }
>>>
>>> (obviously this is just an outline, not real classes)
>>>
>>> So if I see this right, then calling TheInvoker.invoke will fail,
>>> because my.lib.SomeClassOfTheLibrary is not accessible by
>>> com.foo.gi.TheInvoker. And am I right in that if MyOtherLib adds a
>>> "export my.lib to GeneralInvoker", this will then work?
>>
>> I assume you're talking about the body of
>> SomeClassOfTheLibrary::invokeBarOnArgument. The variable x could refer
>> to any object, so when TheInvoker::invoke gets hold of the reference (as
>> 'receiver') and tries to invoke the 'bar' method, the invocation might
>> work. Depends whether the class of the referenced object is exported at
>> all.
>
> yeah, sorry, that was not very clear.I mean that body, yes. Let x.class
> be any exported class MyOtherLib can read, or any class of MyOtherLib
> itself. Important here are two variants: (a) MyOtherLib does not export
> anything, (b) MyOtherLib exports my.lib to GeneralInvoker
>
> My expectation would be for
> Case (a) to fail for all classes of MyOtherLib and to fail for all
> classes from any Module GeneralInvoker does not have declared to
> require. Because I am under the impression, that just having module x
> somewhere in the system does imply readability for module y, only if
> they have a (transitive) exports-requires relationship (ignoring the
> service loader part here).

If x.class returns a class in module MyOtherLib, then since MyOtherLib 
does not export anything, code in module GeneralInvoker cannot 
instantiate the class with newInstance(), or access the class's fields 
with getField(..).get()/set(), or access the class's methods with 
getMethods(..).invoke().

If x.class returns a class in some module other than MyOtherLib, then 
whether code in module GeneralInvoker can reflect over the class depends 
on whether the class is exported to GeneralInvoker.

You mention module x having readability of module y only if they have a 
transitive exports-requires relationship ... but exports is nothing to 
do with readability. The two-sided relationship that matters is 
X-reads-Y + Y-exports-to-at-least-X, and what it matters for is 
accessibility, a higher level thing than readability. Have you watched 
my "Project Jigsaw: Under The Hood" video from JavaOne 2015?

> And for case (b) to work for all classes of MyOtherLib from my.lib, plus
> anything MyOtherLib can read.

If module MyOtherLib exports package my.lib to only module 
GeneralInvoker, then that's great but x.class can still be a class in 
some other module, which GeneralInvoker's code won't be able to 
reflectively access.

Alex


More information about the jigsaw-dev mailing list