A way to opt out of access restrictions on non-exported members.

Remi Forax forax at univ-mlv.fr
Wed Nov 18 12:18:37 UTC 2015


Hi Neil,

If you already have an instance of a non exported type, then there is no issue because applications only access this instance through an interface which is itself exported.

The main issue if how to create such instance, we need a factory which works in jigsaw mode.
You can not use reflection to automatically implement such factory because trying to call a constructor of a non exported class will be rejected by jigsaw.

Here, you have several solutions:
 - as Alan said, if you are a container you control the module configurations, so you control if package is exported or not but that's cheating,
   because the container changes the module configuration written by the user.
 - as you said you can use the mechanism of ServiceLoader or your favorite DI can use the ServiceLoader under the hood BTW,
 - you can re-implement a strawman version of the ServiceLoader by writing a code inside the implementation class that will add a factory
   (a lambda) inside a hashmap (a registry) which is globally accessible.
   
Or you can consider that an implementation that is globally available should be in an exported package because the configuration code (yes code, no XML and no annotation) should access it.

cheers,
Rémi

----- Mail original -----
> De: "Neil Bartlett" <njbartlett at gmail.com>
> À: "Alan Bateman" <Alan.Bateman at oracle.com>
> Cc: "jigsaw-dev" <jigsaw-dev at openjdk.java.net>
> Envoyé: Lundi 16 Novembre 2015 18:48:54
> Objet: Re: A way to opt out of access restrictions on non-exported members.
> 
> Alan,
> 
> In your consideration does the following declaration break encapsulation of a
> module, assuming that package “org.example.impl” is not exported?
> 
> 	module foo {
> 		provides org.example.api.ServiceInterface with
> 		org.example.impl.ServiceImpl;
> 	}
> 
> This appears to allow the ServiceLoader to punch through encapsulation and
> obtain instances of a non-exported type. How does this differ from a
> declaration that one might see in a Dependency Injection framework such as
> Spring? I.e. something like:
> 
> 	<bean class=“org.example.impl.ServiceImpl”> …
> 
> Regards,
> Neil
> 
> 
> > On 16 Nov 2015, at 16:45, Alan Bateman <Alan.Bateman at oracle.com> wrote:
> > 
> > 
> > 
> > On 16/11/2015 12:28, Stephen Colebourne wrote:
> >> Access to private members of classes by reflection is indeed very,
> >> very common. I agree that JDK 9 needs to be cautious around this.
> >> 
> >> 
> > I think this thread is just highlighting the obvious tension between
> > modules with encapsulation vs. serialization and other frameworks that
> > need to break encapsulation. At this time then explicit modules have to
> > opt-in to allow frameworks get access types in those packages. This can be
> > done in the module declaration or at run-time via the API. The alternative
> > is of course the all-powerful command line.
> > 
> > As regards setAccessible(true) then it would be nice to have it eventually
> > go away in some future release. This would clearly require coming up with
> > solutions to some difficult problems and use-cases.
> > 
> > -Alan
> 
> 


More information about the jigsaw-dev mailing list