Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Class Loading & Modularity

Thomas Diesler edited this page Sep 24, 2013 · 2 revisions

This section explores general issues with code integration in a modular java environment.

In the beginning there is always code that uses some package imports.

package imports

At runtime foo needs to get wired to other modules that provide the needed packages.

module wiring

This seemingly obvious procedure comes with a number of difficulties in practise.

The set of needed package imports

When integrating an arbitrary module, the first question the integrator is faced with is that of

What is the set of packages that this module needs?

There are a number of possible approaches to this problem

  1. The module provides the needed metadata itself
  2. We can use a tool to derive the needed metadata
  3. We make an educated guess what this set of packages might be

The first option is the OSGi approach. At build time, foo is examined and standard metadata is packaged as an integral part of foo. For a non OSGi environment there would need to be a tool that provides this information. Such a tool could be derived from available OSGi tooling (e.g. maven-bundle-plugin).

The set of wiring candidates

Given the set of needed packages, the second question would be

What is the set of modules that provide the needed packages?

There are also a number of possible approaches to this problem

  1. There is a repository we can query for the set of wiring candidates
  2. We make an educated guess what this set of modules might be

The first option is that of the OSGi Repository. For a given requirement (in this case a package requirement) it returns the set of resources that can provide the corresponding capability.

Making the correct wiring decision

In a system where any given package is only ever provided by a single module - in other words a given package cannot exist in multiple versions, this topic does not apply. In fact we would not need a modular environment in the first place and a flat class path would work just fine.

To overcome this constraint we need a modular environment that allows for multiple versions of the same package provided by multiple modules. The next question would therefore be

Which is the correct module to wire to for a consistent class space?

There are also a number of possible approaches to this problem

  1. We use a resolver at runtime that guarantees a consistent wiring between module requirements/capabilities. Wires can be added/removed dynamically at runtime.
  2. We use a resolver at build time that guarantees a consistent initial wiring. Additional hard coded wires can be added but may not be consistent.
  3. We make an educated guess what the correct wiring target might be

The first option is that of the OSGi runtime. Modules have lifecycle and only resolve if a consistent wiring can be found.