Java Platform Module System: Requirements

DRAFT 2

Mark Reinhold

2015/3/25 15:13 -0700 [77b4626c886e]

The overall goal of this JSR is to define an approachable yet scalable module system for the Java Platform. It will be approachable, i.e., easy to learn and easy to use, so that developers can use it to construct and maintain libraries and large applications for both the Java SE and Java EE Platforms. It will be scalable so that it can be used to modularize the Java SE Platform itself, and its implementations.

As outlined in the JSR, the specific goals are to provide and enable:

This document expands the above goals into a set of sub-goals, or requirements, and also some non-requirements, which identify goals that are beyond the scope of this JSR. Each (non-)requirement is shown as

Motivational or explanatory comments sometimes follow a requirement, in non-indented text.

The intent of this document is to serve as a set of guideposts for the deliberations of this JSR’s Expert Group. The specification will, ultimately, satisfy all of these requirements. Revisions may be proposed after we finalize this document, but the bar for accepting them will be relatively high.

The terms “must,” “must not,” “required,” “shall,” “shall not,” “should,” “should not,” “recommended,” “may,” and “optional” in this document are to be interpreted as described in RFC 2119.

Contents

Modules · Dependences · Resolution · Exports · Encapsulation · Non-interference · Resource encapsulation · Services · Binding · Selective binding · Fidelity across all phases · Protection domains · Compatible Java Platform modularization · Refactoring · Interoperation

Medium-grained modularization · Qualified exports · Upgradeable modules · Referential integrity · Preserve performance

Gradual migration of applications · Integrate smoothly with existing tools · Multi-mode artifacts · White-box testing · Reflection, debugging, and tools · Readable artifacts · Efficient annotation detection

Linking tool · Link-time optimization

OS-specific module packaging · OS-specific application packaging

Version strings · Non-prescriptive version strings · Version strings in reflective APIs

Basic dynamic configuration · Run-time augmentation of platform modules · Multiple dynamic configurations · Isolated dynamic configurations · Composable dynamic configurations · Alternate module versions in dynamic configurations · Control of class loaders

Modularize the Java Language Specification · Modularize the Java Virtual Machine Specification · Multiple versions · Version selection

Fundamentals

Like a package, class, or interface, a module has both a specification and one or more implementations. It is a large-grained unit of compilation, packaging, release, transport, and re-use.

In this context the invoking agent might be a developer, via command-line flags or build-system configuration settings, or it might be an application that dynamically loads modules, via an appropriate API.

Modularizing the Java SE Platform

A module that exports one or more packages of the Java SE Platform will hereinafter be referred to as a “platform module.”

Development

This will allow library developers to continue to produce a single artifact for both class-path and module-based applications.

One potential approach is to augment a module’s definition with an index of the annotations that are present in the module, together with an indication of the elements to which each annotation applies. To limit the size of the index, only annotations which themselves are annotated with a new meta-annotation, say @Indexed, would be included.

Linking

The result of the linking process may be a minimal Java run-time system integrated tightly with a single application and its libraries, an entire Java development environment, or something in between these two extremes.

Packaging

This requirement does not apply to operating systems that do not have built-in, general-purpose packaging systems, such as Windows and Mac OS.

If the target system is expected already to include the necessary platform modules then they need not be included in the application package.

Versioning

Dynamic Configuration

The requirements for dynamic configuration are motivated by applications with plug-in or container architectures such as IDEs, test harnesses, and application servers. For the Java EE Platform, in particular, the goal is to enable a future modular war-file standard in which the components in a war file can be modules.

This will allow a container application to load additional platform modules in order to satisfy the needs of the applications that it hosts.

A canonical example of using multiple versions of an upgradeable module in a Java EE environment is that of a web application requiring a different version of the JAX-WS stack than is already available to the web container.

Non-Requirements

A particular JVM implementation may, of course, have its own internal modular structure, but there is no compelling need to subdivide either the language or the VM specifications.

Most applications are not containers and, since they currently rely upon the class path, do not require the ability to load multiple versions of a module. Container-type applications can achieve this, when needed, via dynamic configuration, as outlined above.

In other words, this specification need not define yet another dependency-management mechanism. Maven, Ivy, and Gradle have all tackled this difficult problem. We should leave it to these and other build tools, and container applications, to discover and select a set of candidate modules for a given library or application. The module system need only validate that the set of selected modules satisfies each module’s dependences.