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

Reply via email to