Non-exported vs restricted packages
forax at univ-mlv.fr
Fri Dec 4 09:10:07 UTC 2015
I think there is an issue with the current design of jigsaw that we should tackle.
The problem have been raised several times of the jigsaw-dev mailing list by different people and I think it's a valid point, currently the way encapsulation is specified doesn't match with the way people use/want to use modules in an application server. Don't get me wrong, I don't not want to have stronger encapsulation that we currently have, i just think we should recognize that the way people currently use modules is a valid use case.
So the problem is that most application servers use reflection to create instances of implementation of an interface and people want the implementation on that interface to be in a non-exported package. With Jigsaw only option if you want this configuration is to use a ServiceLoader to load the implementation.
But using a ServiceLoader requires coordination between the code that declares and uses the interface and code that implements that interface. Which mean that people will be able to use modules in an application server when the application server itself will use ServiceLoader, so not before JavaEE 9.
I think we should provide a way for people to use modules in a JavaEE 7/8 world.
The way to do that is to recognize that we should have a way to specify that we want packages that have implementations that are not accessible directly but that are accessible using reflection (with the right handsake). It doesn't mean we don't want stronger encapsulation for package like com.sum.foo, it means we also want to have a way to specify that a package can be non-exported but its implementations can be available by reflection if and only if setAccessbile is used.
This will ease the transition by allowing people to modulify there current code without waiting application servers to implement the JavaEE 9 spec because application server vendors can tweak the implementation of their dependency injection mechanism to use setAccessible when necessary*.
So I propose that the spec should specify three kind of packages "availability",
exported packages that make classes available by module that require the module containing the packages, non-exported packages that make classes non available but that can be used by reflection using setAccessible as an escape hatch and restricted packages that make the classes non-available even by using setAccessible.
Note that the question of which one should be the default is another question that can be decided after.
* we also need setAccessible to add a read edge automatically if the package not restricted.
More information about the jpms-spec-experts