Key Moments

Advanced Topics in Programming Languages Series: JSR 277 Java Module System

Google TalksGoogle Talks
Education6 min read66 min video
Aug 22, 2012|1,366 views|4
Save to Pod

Want to know something specific about what's covered?

We've already dissected every moment. Ask and we will deliver (with timestamps).

TL;DR

Java's old JAR file system leads to 'hells' like classpath hell and JAR hell. JSR 277 introduces modules with versioning and self-description to fix this, but faces complexity and interoperability challenges.

Key Insights

1

The Java Archive (JAR) file, originally for Java applets, lacks standard version control and makes dependency management difficult, leading to 'classpath hell', 'JAR hell', and 'extension hell'.

2

JSR 277 proposes a new module system with a 'JAM' file format that can bundle classes, resources, JAR files, and native libraries, incorporating metadata for self-description.

3

The module system introduces a new versioning scheme for modules, allowing for granular version specification (major, minor, micro, update, qualifier) and clearer dependency management.

4

Repositories are central to the module system, enabling storage of multiple module versions side-by-side and supporting various repository types like bootstrap, global, application, local, and URL.

5

Runtime class loading will involve a one-to-one correspondence with modules, leveraging new class loader support in Java 7 to handle cyclic dependencies, which are common in modular systems.

6

The system aims for seamless integration with the language (via JSR 294 'super package') and JVM, while also allowing for pluggable repository implementations and interoperability with existing module systems like OSGi.

The pervasive problems of the current Java packaging model

The foundational packaging format in Java, the Java Archive (JAR) file, established in the 1990s for distributing Java applets, has become a significant bottleneck for modern Java development. Its primary deficiency lies in the absence of robust version control for its contents and dependencies. This lack of versioning information makes it exceedingly difficult to manage dependencies between multiple JAR files, a common scenario in contemporary Java applications. Consequently, developers often resort to bundling all components into a monolithic JAR or creating custom installers to manage deployment. This situation has led to well-known issues collectively termed 'classpath hell', 'JAR hell', and 'extension hell', characterized by class loading conflicts, deployment complexities, and versioning nightmares that plague Java developers.

Introducing the Java Module System (JSR 277)

The JSR 277 specification aims to fundamentally address these long-standing issues by introducing a first-class module system directly into the Java SE platform. The core of this new system is the concept of a 'module', which is a unit of reuse, versioning, and packaging. A key innovation is the 'JAM' file format, designed to replace the traditional JAR. JAM files are capable of bundling not only classes and resources but also other JAR files and native libraries into a single, self-describing distribution unit. This self-description is facilitated by embedded metadata, making it easier for the Java Virtual Machine (JVM) and developers to understand module contents, dependencies, and versions without extensive scanning. This holistic approach promises to streamline the entire development and deployment lifecycle by providing built-in support for modularity.

Enhanced versioning and dependency management

A central pillar of JSR 277 is the introduction of a new, explicit versioning scheme for modules. Unlike the implicit versioning of JAR files which relies on naming conventions, JSR 277 allows developers to declare module versions directly. This versioning information includes a detailed structure comprising major, minor, micro, update numbers, and a qualifier string. Developers are expected to increment these numbers based on the extent of changes, providing a much clearer picture of module evolution. Furthermore, the module system enhances dependency management by enabling modules to declare their 'imports' – dependencies on other modules. While basic imports specify the required module name, advanced syntax will allow for version range constraints, ensuring that applications can precisely define the versions of their dependencies they are compatible with. This granular control over versions and dependencies is crucial for resolving conflicts and ensuring application stability.

The role of repositories in module distribution

The JSR 277 module system introduces a robust repository infrastructure crucial for storing and managing modules. Repositories serve as standardized storage locations where modules can be placed, allowing for multiple versions of the same module to coexist. This is essential for scenarios where different applications on the same system might require different versions of a shared library. The system defines various types of repositories, including a privileged 'bootstrap' repository for core Java SE packages, system-wide or per-user global repositories, automatically created application repositories for quick deployment, and local or URL repositories for easier sharing and network-optimized downloads. This layered repository architecture, combined with delegation mechanisms similar to classloaders, allows for sophisticated resolution of module dependencies, prioritizing trusted sources and ensuring that the correct module versions are selected based on defined constraints.

Bridging development and deployment experiences

JSR 277 is designed to provide a cohesive end-to-end experience for developers, from writing code to deploying applications. This integration is fostered by JSR 294, which defines 'super packages' as the linguistic unit of modularity within the Java language itself. Developers will be able to express modularity constructs, including module membership, exports, and imports, directly in their source code. Upon compilation, this super package construct will generate metadata that is used by the JSR 277 module system for deployment. This tight integration means that module information specified in the source code is authoritative and automatically propagated to the deployment metadata, simplifying the build process. Tools can even combine compilation and packaging into a single step, transforming super package source files directly into deployable module units. APIs will also be provided to inspect and interact with module system abstractions at runtime.

Runtime behavior and class loading

At runtime, the module system mandates a close correspondence between modules and class loaders, often a one-to-one mapping. This approach is necessary to enforce proper isolation and encapsulation between modules, especially to prevent class loading conflicts when different modules might depend on different versions of the same library. The system leverages enhanced class loader support, expected in Java 7, to handle cyclic dependencies between modules, which are a natural consequence of modular designs. A 'shallow validation' process is employed to ensure that for every imported class, exactly one provider exists among the module's dependencies, guaranteeing that resolution will succeed. This mechanism also underpins the potential for efficient runtime resolution and class loading, a significant improvement over the current classpath scanning. For backward compatibility, special modules like 'java.se' (containing all core SE packages) and 'java.classpath' (for legacy code) will be automatically created.

Extensibility and interoperability considerations

The architecture of the JSR 277 module system is deliberately designed to be pluggable and extensible. Third-party developers can create custom repository implementations, allowing for diverse backend storage solutions. Furthermore, the system aims for interoperability with existing module systems. This includes efforts to integrate with established frameworks like OSGi and NetBeans modules, enabling them to expose their modules as JSR 277-compatible units. The presentation acknowledges that achieving perfect interoperability is challenging due to differing design constraints, but the goal is to provide a degree of interoperability with minimal restrictions. The discussion also touched on advanced mechanisms for controlling import resolution, such as custom import policies, visibility policies, and override policies, primarily aimed at expert users and administrators to manage complex dependency scenarios.

Current status and future outlook

As of the presentation in 2007, JSR 277 had completed its early draft review, with feedback being incorporated into revised specifications currently under expert group review. Key areas of ongoing work included interoperability with OSGi and refining the language-level constructs defined in JSR 294. The presenters expressed hope for a later release of the specifications that year. A significant announcement was the plan for Sun Microsystems to release open-source reference implementations of both JSR 277 and JSR 294 later in the year, with project setup on OpenJDK. The ultimate goal remains to eliminate the notorious 'classpath hell', 'JAR hell', and 'extension hell', providing Java developers with a more robust, manageable, and scalable module system for future generations of the platform.

Common Questions

JSR 277 aims to address deficiencies in the traditional JAR format, such as difficulties in expressing version information and dependencies, the lack of a standard format for bundling multiple JARs and native libraries, and performance issues related to classloading on the JVM.

Topics

Mentioned in this video

More from GoogleTalksArchive

View all 48 summaries

Ask anything from this episode.

Save it, chat with it, and connect it to Claude or ChatGPT. Get cited answers from the actual content — and build your own knowledge base of every podcast and video you care about.

Get Started Free