Whitelisting modules in layers

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Whitelisting modules in layers

Mark Raynsford
Hello.

Is it possible to whitelist the modules available to a given layer?

I'm in the process of implementing a small experimental language that's
designed to be embedded in Java programs in a similar manner to the way
that Lua is embedded in C++ programs. The language has a module system
that I intend to map directly to Jigsaw/JPMS modules. The further
intention is that user programs are placed into their own module layer,
distinct from the host application layer (and that of the compiler).
I'd like to allow for whitelisting the modules available to user code.
Something like:

  Evaluator e =
    Evaluator.builder()
      .setModuleSearchPath(dir1, dir2, dir3)
      .setModuleWhitelist("java.base","com.example.m1","com.example.m2")
      .build();
  e.evaluate("[print \"hello\"]");

The user code passed to e.evaluate() would be compiled in its own module
and would only be able to create "reads" edges to java.base,
com.example.m1, and com.example.m2. Any other modules that happen to be
available to the host application would be invisible to the user's code.

I've played around with the ModuleFinder API a little, and came up
with the following:

  https://github.com/io7m/moduledemo-20171201/blob/master/src/main/java/com/io7m/moduledemo/WhitelistModuleDemo.java

However, the boot_layer.defineModulesWithOneLoader() call raises an
exception: "Class loader must be the boot class loader". Clearly I'm
not meant to use the API in this way!

--
Mark Raynsford | http://www.io7m.com

Reply | Threaded
Open this post in threaded view
|

Re: Whitelisting modules in layers

Alan Bateman
On 01/12/2017 18:47, Mark Raynsford wrote:

> :
>
> I've played around with the ModuleFinder API a little, and came up
> with the following:
>
>    https://github.com/io7m/moduledemo-20171201/blob/master/src/main/java/com/io7m/moduledemo/WhitelistModuleDemo.java
>
> However, the boot_layer.defineModulesWithOneLoader() call raises an
> exception: "Class loader must be the boot class loader". Clearly I'm
> not meant to use the API in this way!
It looks like this demo is attempting to create a module layer from a
configuration that contains java.base. The java.base module is in the
boot layer, alternative implementations of java.base are not allowed in
other layers (java.base is special in this regard and the
defineModulesXXX methods are all specified to throw
LayerInstaniationException if the configuration contains java.base).

If I understand your mail correctly then your "white list" is like the
`--limit-modules` CLI option in that it is trying to limit the
observability of the modules. One initial comment on this is that you
need to compute the transitive closure (or recursive enumeration in
resolution speak) of the set of modules for this to work. This will
become clear once you have a com.example.m* module that requires a
module other than java.base.

On your question then the module layer API doesn't provide a way to
"hide" modules in the parent layers. You can override any module (except
java.base) with an alternative implementation in the child layer but it
doesn't provide anyway to hide modules that you aren't overriding. This
may not be an issue for what you are doing. If you need to, then compute
the set of modules that you want to hide and make empty versions of each
of these observable via the "before" ModuleFinder that you specify to
resolve. You could use an intermediate module layer to do this if you want.

-Alan

Reply | Threaded
Open this post in threaded view
|

Re: Whitelisting modules in layers

Mark Raynsford
On 2017-12-02T09:32:37 +0000
Alan Bateman <[hidden email]> wrote:
>
> It looks like this demo is attempting to create a module layer from a
> configuration that contains java.base. The java.base module is in the
> boot layer, alternative implementations of java.base are not allowed in
> other layers (java.base is special in this regard and the
> defineModulesXXX methods are all specified to throw
> LayerInstaniationException if the configuration contains java.base).

Right, got it. I thought I was creating a layer that delegated to the
boot layer for java.base, but obviously not.

> On your question then the module layer API doesn't provide a way to
> "hide" modules in the parent layers. You can override any module (except
> java.base) with an alternative implementation in the child layer but it
> doesn't provide anyway to hide modules that you aren't overriding.

OK, thanks!

It occurs to me that I'm essentially trying to do the work that the
SecurityManager would have done in the past: Restrict access to
packages (or in this case, entire modules).

--
Mark Raynsford | http://www.io7m.com