Automodules
Robert Scholte
rfscholte at apache.org
Mon Feb 13 20:54:57 UTC 2017
On Mon, 13 Feb 2017 16:59:44 +0100, David M. Lloyd
<david.lloyd at redhat.com> wrote:
> On 02/11/2017 10:18 AM, Robert Scholte wrote:
>> There are clearly 2 kinds of jars in play here: dependencies and
>> end-products.
>>
>> To have a reliable end-product you want to specify *every* requirement
>> and in this case it doesn't matter that a dependency has no official
>> module name, as long as you can specify and refer to it as a
>> requirement.
>>
>> To have a reliable dependency you can only depend on named modules. Up
>> until now it is required to specify all requirements or do some command
>> line argument magic to compile or run such project.
>>
>> What I would like to achieve is to have a situation where end-products
>> can never be used as a dependency, because that would allow auto
>> modules, which makes it again unreliable as dependency.
>
> We accomplished exactly these goals in jboss-modules, simply by having
> multiple "worlds": The module world itself (of course), and separated
> worlds for the modularized class path or -jar command line.
>
> In the raw class path situation, we create a single module for the
> entire class path. This is essentially an "unnamed" blob, which can
> consume available modules but cannot in turn be consumed by them. This
> allows a first step into the module world by allowing (over time) the
> user to move modules from the class path into the module space as their
> dependencies can be correctly and specifically analyzed (in other words,
> it's one step from sloppy class path to constrained/clean module).
> Classpath JARs could also be separated into modules which have a mutual
> dependency mesh (assuming that circular dependencies are allowed),
> allowing for a better diagnostic identity than just "classpath" (for
> example).
>
> In the -jar situation, we create a module per JAR using the JAR's
> Class-Path MANIFEST.MF header as the linking mechanism. In the
> container we also support the old extensions mechanism (which it turns
> out is actually a pretty good basic module system in its own right). In
> this way, JARs are isolated from one another, consuming only what is
> explicitly declared. In the Java EE container, these dependencies are
> usually transitive due to some unfortunate specification language, but
> on the command-line they are not, which further improves isolation. In
> this case as well JARs can depend on modules but not vice-versa.
> Circularity is also historically allowed in this situation.
>
> I have found these mechanisms to be more than adequate for providing an
> easy on ramp for modularization, and neither one requires module name
> fudging; in fact, mangling of names is harmful since it takes the
> intuitive "my-project-1.3.3.jar" that would appear in diagnostics, which
> can be copied and pasted into a "find" command for example, and turns it
> into something rather unintuitive. Having a modular classpath in fact
> is the easiest possible "small" step because it allows code to run under
> the new module accessibility and (service) loading rules without
> otherwise affecting class loading behavior in any way.
>
> This is why I'm frustrated with automatic modules: they just don't seem
> necessary, and have several proven problems which also seems to make
> them insufficient.
>
Nice to know that my thoughts are confirmed with an existing modular
system.
And the "small" step as adding one requirement at the time to a named
module fits very well with the Maven eco system.
thanks,
Robert
>> Specifying a dependency is done by referring to the name of a module.
>> So what if we say that a end-product doesn't have a name anymore or that
>> it is not a module anymore. In that case it cannot be used as dependency
>> AND we could allow automodules in such case.
>>
>> In case of a dependency or named module you can only refer to other
>> named modules. All other required jars should be picked up from the
>> classpath, preferably by default.
>>
>> This is just a start, but would probably match most requirements from
>> both camps.
>>
>> So an example of the end-product jar:
>>
>> final myapp { // 'module' replaced with 'final'
>> requires mylib; // a named module, assume part of Maven
>> multimodule project
>> requires java.base; // a named module, part of Java
>> requires java.sql; // a named module, part of Java
>> requires jackson.core; // an unnamed module, name extract from
>> filename (jackson-core-2.6.2.jar)
>> requires jackson.databind; // an unnamed module, name extract from
>> filename (jackson-databind-2.6.2.jar)
>> }
>>
>> or
>>
>> module { // remove the name, so can never refer to it
>> requires mylib; // a named module, assume part of Maven
>> multimodule project
>> requires java.base; // a named module, part of Java
>> requires java.sql; // a named module, part of Java
>> requires jackson.core; // an unnamed module, name extract from
>> filename (jackson-core-2.6.2.jar)
>> requires jackson.databind; // an unnamed module, name extract from
>> filename (jackson-databind-2.6.2.jar)
>> }
>>
>> An example of the dependency jar
>>
>> module org.joda.convert {
>> // requires ??guava??; no named module yet, will be picked up from
>> classpath
>> }
>>
>> other projects could already refer to org.joda.convert if they want to.
>> Once guava is a named module, org.joda.convert can specify it.
>>
>> regards,
>> Robert
More information about the jpms-spec-experts
mailing list