question on exports to

Alex Buckley alex.buckley at oracle.com
Tue May 31 21:23:33 UTC 2016


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.

> Now some advanced questions ;)
>
> assuming MyOtherLib also requires YetAnotherLib and has the exports-to
> in the module descriptor... does it automatically imply readability For
> GeneralInvoker on YetAnotherLib (only exported parts of course)?
>
> Assuming this is not the case... can I use Module#addReads, with the
> caller being from GeneralInvoker and the other Module being
> YetAnotherLib, to create that readability?

Accessibility is a two-part check: i) does the accessing module read the 
accessed module, and ii) does the accessed module export the right 
package to at least the accessing module?

When you use the Core Reflection API, the answer to (i) is always "yes". 
You never need to call Module::addReads. That is, when code in module M 
manipulates a Class/Field/Method object, it's as if M reads whichever 
module holds <<the class corresponding to the Class object>>/<<the class 
declaring the field corresponding to the Field object>>/<<the class 
declaring the method corresponding to the Executable object>>. The 
accessibility question depends solely on (ii) -- whether that module 
exports the right package to at least M.

> And even more difficult:
>
> Assuming TheInvoker spawns a new class loader and a class within that to
> do the actual method invocation. So far I assume the module of that
> class would the unnamed module. As such I have access to the exports of
> MyOtherLib and YetAnotherLib.

The class in the new loader is indeed in the unnamed module of that 
loader. That unnamed module can certainly read the module MyOtherLib, 
but I'm confused why you say "the exports of MyOtherLib" since you said 
MyOtherLib has no exports.

> But how do I establish that class to be able to access
> my.lib.SomeClassOfTheLibrary?

SomeClassOfTheLibrary has to grant the access.

> I would have assumed Layers can do it, but I don't see how the API gives
> me that. Having another exports-to in the module descriptor of
> MyOtherLib will I think not work, since even if I define a naming
> convention, this module does not exist at compile time.
>
> Or should I trick Java by creating a dummy module with a certain name,
> that MyOtherLib can export-to, but is used at compile time only?
>
> Here I might be able to use Layer to define my module... unless the JVM
> expects that module to exists7find when it loads MyOtherLib, in which
> case I am stuck again.
>
> So what am I missing or is this final part really not possible?

I think you're trying to do the same thing as Nashorn -- spin dynamic 
modules with privileged access to framework internals. For now , I 
recommend looking at Sundar's mail today on "RFR 8158131: Nashorn should 
not use jdk.internal.module.Modules API". We plan to write up the 
techniques because they're useful for all frameworks.

Alex


More information about the jigsaw-dev mailing list