Combining a custom modular run-time image with a third party plugin system
Hello EG, I posted this question to StackOverflow [1], however this mailinglist might be the more appropriate place for it: Based on this [2] twitter post, I am going to assume that Jigsaw will be a
part of Java 9.
When reading about Jigsaw, I asked myself a question: What happens when I release my application with a custom modular run-time image, but a third party module requires additional JRE modules which were not released with the application, because they were not required by the application?
Imagine an application that wants to benefit from the modularization. It provides a service interface that can be implemented by a third party module. The application loads all the third party modules which provide an implementation of the service interface when the application is starting. In my opinion, this is a great and easy way to provide a public API for third party plugins and I can imagine using this by myself quite frequently.
Now, there is also a tool called jlink which allows one to create a release of an application which does not only contain the application modules but also the requires JRE modules. This is called a custom modular run-time image. The great thing is, that the release only contains the JRE modules which are actually used by the application, which prevents the release from growing very big in size. Currently, jlink will figure out which modules have to be included by itself. However, service implementation providing modules have to be included explicitly by the developer, see [3]. I think this is also great for many applications where the developer does not want to require the user to install a JRE.
The problem arises when we try to use both in a single application: The custom modular run-time image only contains the JRE modules which are used by the application. However, a plugin might use JRE modules which have not been used by the application and thus these modules are not available at run-time. Thus, the plugin will not work.
Here is the only solution that I can think of, however it is far from perfect:
Include the missing JRE modules into the third party plugin. While this might seem to be a simple solution at first, it actually come with quite some issues.
First, this requires the plugin developer to know which JRE modules are included in the application. If this is unknown they might include a JRE module which is already available in the application itself, which might cause problems. Thus, it becomes a part of the public API which modules are used by the application. I think this is not desirable, because it is an implementation detail. Also, it might change quite frequently.
Second, since the available JRE modules are a part of the public API, they need to be specified somehow. While this might work via documentation, I think it should be specified via formal code. For example, it might work to use a requires public clause in the application module for all JRE modules which should be available to the plugin module. This makes these JRE modules available to the plugin, because the plugin will require the application module.
Third, the question arises whether it is desirable to allow the plugin to use additional JRE modules. If it is not, there should probably an clause for the module-info.java to specify that the current module is a plugin for a given other module. For example, instead of using require for the application module, one would use plugs in to or another notation for that. This would prevent the module from requiring any JRE modules. However, this is probably not gonna work, since other third party modules which are required by the plugin module might require additional JRE modules. Thus, I think it is tough to offer support for such a mechanism.
Fourth, it is also tough to allow plugins to use additional JRE modules. This would either require the different JRE modules to be compatible in different versions or the plugin developer to always include the additional JRE modules in a version that is compatible to the version of the JRE modules in the application. I am not sure about whether the JRE modules are supposed to be compatible in different versions, but my assumption is that they are not supposed to be, because it would prevent many changes in the future.
Are some of my assumptions wrong? Maybe it works just fine to include a JRE module in the application and the plugin? Maybe the additional JRE modules in the plugin also don't have to be compatible with the JRE modules in the application? After all, they might not interact with each other.
How should we handle this architectural problem? Are there other languages with a modular and partly releasable run-time? How did they solve the problem?
Please note that similar problems might arise with commonly used libraries like Google guava or the Apache commons. However, this question should be mostly about the problems which arise from using a custom modular run-time image.
[1]: http://stackoverflow.com/questions/36388004/java-9-combining-a-custom-modula... [2]: https://twitter.com/mreinhold/status/713384458452226048 [3]: https://twitter.com/mreinhold/status/665122968851382273
Has this already been discussed? Any feedback is appreciated. Kind regards Stefan Dollase
participants (1)
-
Stefan Dollase