The Extension Mechanism

# Extension Mechanism Architecture

## Contents

- Introduction
- The Extension Mechanism

- Architecture
- Optional Package Deployment
- Bundled Optional Packages
- Installed Optional Packages

- Optional Package Sealing
- Optional Package Security
- API Details

## Introduction

> Note: Optional packages are the new name for what used to be known as standard extensions. The "extension mechanism" is that functionality of the Java 2 SDK and Java 2 Runtime Environment that supports the use of optional packages.

> This document describes the Java platform's mechanism for handling optional packages. An optional package is a group of packages housed in one or more JAR files that implement an API that extends the Java platform. Optional package classes extend the platform in the sense that the virtual machine can find and load them without their being on the class path, much as if they were classes in the platform's core API.

> An implementation of an optional package may consist of code written in the Java programming language and, less commonly, platform-specific native code. In addition, it may include properties, localization catalogs, images, serialized data, and other resources specific to the optional package.

> Support for optional packages in browsers such as Internet Explorer and Netscape Navigator is available through the Java Plug-in.

> A optional package is an implementation of an open, standard API (examples of optional packages from Sun are JavaServlet, Java3D, JavaManagement). Most optional packages are rooted in the `javax.*` namespace, although there may be exceptions.

## The Extension Mechanism

> ### Architecture

> The extension mechanism is designed to contain the following elements:
> - an optional package or application packaged as a JAR file can declare dependencies on other JAR files, thus allowing an application to consist of multiple modules, and,
> - the class loading mechanism is augmented to search installed optional packages (and other libraries) for classes, and, if that fails, to search along an application-specified path for classes.
> Applications must therefore, in general, be prepared to specify and supply the optional packages (and, more generally, libraries) that it needs. The system will prefer installed copies of optional packages (and libraries) if they exist; otherwise, it will delegate to the class loader of the application to find and load the referenced optional package (and library) classes.

> This architecture, since it allows applications, applets and servlets to extend their own class path, also permits packaging and deploying these as multiple JAR files.

> Each optional package or application consists of at least one JAR file containing an optional manifest, code and assorted resources. As described below, this primary JAR file can also include additional information in its manifest to describe dependencies on other JAR files. The `jar` command line tool included with the Java 2 SDK provides a convenient means of packaging optional packages, although any ZIP-compatible archiving tool should work as well. (See the reference pages for the `jar` tool: [Windows][Solaris])

> An optional package or application may refer to additional JAR files which will be referenced from the primary JAR, and these can optionally contain their own dependency information as well.

> Packages comprising optional packages should be named per the standard package naming conventions when implementing optional packages. These conventions are outlined in The Java Language Specification, but the requirement that the domain prefix be specified in all upper case letters has been removed. For example, the package name `com.sun.server` is an accepted alternative to `COM.sun.server`. Unique package naming is recommended in order to avoid conflicts, because applications and optional packages may share the same class loader.

> ### Optional Package Deployment

> An optional package may either be bundled with an application or installed in the JRE for use by all applications. Bundled optional packages are provided at the same code base as the application and will automatically be downloaded in the case of network applications (applets). For this reason, bundled optional packages are often called download optional packages. Installed optional packages are loaded when first used and will be shared by all applications running on the same runtime environment.

> When packaging optional packages, the JAR file manifest can be used to identify vendor and version information (see The Java Versioning Specification).

> Classes for installed optional packages are shared by all code in the same virtual machine. Thus, installed optional packages are similar to the platform's core classes (in `rt.jar`), but with an associated class loader and a pre-configured security policy as described below.

> Classes for bundled optional packages are private to the class loader of the application, applet or servlet. In the case of network applications such as applets, these optional packages will be automatically downloaded as needed. Since class loaders are currently associated with a codebase, this permits multiple applets originating from the same codebase to share implementations (JARs).

> ### Bundled Optional Packages

> The manifest for an application or optional package can specify one or more relative URLs referring to the JAR files and directories for the optional packages (and other libraries) that it needs. These relative URLs will be treated relative to the code base that the containing application or optional package JAR file was loaded from.

> An application (or, more generally, JAR file) specifies the relative URLs of the optional packages (and libraries) that it needs via the manifest attribute `Class-Path`. This attribute lists the URLs to search for implementations of optional packages (or other libraries) if they cannot be found as optional packages installed on the host Java virtual machine*. These relative URLs may include JAR files and directories for any libraries or resources needed by the application or optional package. Relative URLs not ending with '/' are assumed to refer to JAR files. For example,

> >     Class-Path: servlet.jar infobus.jar acme/beans.jar images/

> Multiple `Class-Path` headers may be specified, and are combined sequentially.

> Currently, the URLs must be relative to the code base of the JAR file for security reasons. Thus, remote optional packages will originate from the same code base as the application. A future enhancement will leverage the facilities of the Java 2 Platform's Security APIs to allow references to JAR files at other URLs.

> Each relative URL is resolved against the code base that the containing application or optional package was loaded from. If the resulting URL is invalid or refers to a resource that cannot be found then it is ignored.

> The resulting URLs are used to extend the class path for the application, applet, or servlet by inserting the URLs in the class path immediately following the URL of the containing JAR file. Any duplicate URLs are omitted. For example, given the following class path:

>             a.jar b.jar

> If optional package `b.jar` contained the following `Class-Path` manifest attribute:

>             Class-Path: x.jar a.jar

> Then the resulting application class path would be the following:

>             a.jar b.jar x.jar

> Of course, if `x.jar` had dependencies of its own then these would be added according to the same rules and so on for each subsequent URL. In the actual implementation, JAR file dependencies are processed lazily so that the JAR files are not actually opened until needed.

> ### Installed Optional Packages

> In Sun's implementation of the Java 2 Platform, the JAR files of a installed optional package are placed in a standard local code source

> >     <java-home>\lib\ext                     [Windows]
> >     <java-home>/lib/ext                     [Solaris]

> Its native code libraries, if any, are placed in

> >     <java-home>\bin                         [Windows]
> >     <java-home>/lib/<arch>                  [Solaris]

> Here `<java-home>` refers to the directory where the runtime software is installed (which is the top-level directory of the JRE or the `jre` directory in the Java 2 SDK), and `<arch>` refers to the Solaris processor architecture (`sparc` or `x86`).

> A installed optional package may additionally contain one or more shared libraries (such as .dll files) and executables. Native libraries may also be placed in `jre/lib/ext/<arch>` for both Windows and Solaris, where `<arch>` will be `x86` on Windows systems. The `jre/lib/ext/<arch>` directory is searched after `jre\bin` (Windows) or `jre/lib/<arch>` (Solaris).

> Currently, an optional package that contains native code cannot be downloaded by network code, whether such code is trusted or not, into the virtual machine at execution time. An optional package that contains native code and is bundled with a network application must be installed in the Java 2 SDK or Java 2 Runtime Environment.

> By default, installed optional packages in this standard directory are trusted. That is, they are granted the same privileges as if they were core platform classes (those in `rt.jar`). This default privilege is specified in the system policy file, but can be overridden for a particular optional package by adding the appropriate policy file entry.

> Note also that if a installed optional package JAR is signed by a trusted entity, then it will be granted the privileges associated with the trusted signer.

> Other locations for installed optional packages can be specified through the system property `java.ext.dirs`. This property specifies one or more directories to search for installed optional packages, each separated by `File.pathSeparatorChar`. The default setting for this property is the standard directory for installed optional packages indicated above.

## Optional Package Sealing

> JAR files and packages can be optionally sealed, so that an optional package or package can enforce consistency within a version.

> A package sealed within a JAR specifies that all classes defined in that package must originate from the same JAR. Otherwise, a `SecurityException` is thrown.

> A sealed JAR specifies that all packages defined by that JAR are sealed unless overridden specifically for a package.

> A sealed package is specified via the manifest attribute, `Sealed`, whose value is `true` or `false` (case irrelevant). For example,

> >     Name: javax/servlet/internal/
> >     Sealed: true

> specifies that the `javax.servlet.internal` package is sealed, and that all classes in that package must be loaded from the same JAR file.

> If this attribute is missing, the package sealing attribute is that of the containing JAR file.

> A sealed JAR is specified via the same manifest header, `Sealed`, with the value again of either `true` or `false`. For example,

> >     Sealed: true

> specifies that all packages in this archive are sealed unless explicitly overridden for a particular package with the `Sealed` attribute in a manifest entry.

> If this attribute is missing, the module is assumed to not be sealed, for backwards compatibility. The system then defaults to examining package headers for sealing information.

> Package sealing is also important for security, because it restricts access to package-protected members to only those classes defined in the package that originated from the same JAR file.

> Package sealing is checked for installed as well as downloaded optional packages, and will result in a `SecurityException` if violated. Also, the null package is not sealable, so classes that are to be sealed must be placed in their own packages.

## Optional Package Security

> The code source for a installed optional package (namely `<java-home>/lib/ext`) has a pre-configured security policy associated with it. In Sun's implementation, the exact level of trust granted to JARs in this directory is specified by the standard security policy configuration file

> >     <java-home>/lib/security/java.policy

> The default policy is for a installed optional package to behave the same way it would if were part of the core platform. This follows from the common need for a installed optional package to load native code.

> The Java Security Model provides some safety when installed optional package code is called from untrusted code. However optional package code must be carefully reviewed for potential security breaches wherever it uses privileged blocks.

> A remotely loaded optional package that needs to use access-checked system services (such as file I/O) to function correctly must either be signed by a trusted entity or loaded from a trusted source.

> Consult the Java security documentation for further details regarding how to write optional package and application code to use the Java 2 Platform's security features.

## API Details

> The following classes in the Java 2 platform support the extension mechanism:
> - `public class java.lang.ClassLoader` (changed)

> The class loader delegation model allows a "parent" class loader to be specified which will always be searched first when loading a class or resource before attempting to load it locally. New class loader implementations override the methods `findClass` and `findResource` in order to specify how classes and resources are loaded locally.

> - `getSystemClassLoader`
> Returns the system class loader for delegation. This is the default delegation parent for new ClassLoader instances, and is typically the class loader used to start the application.
> - `loadClass`
> If the class has already been loaded then just return it. Otherwise, try loading the class from the parent class loader (or virtual machine's built-in class loader, called the bootstrap class loader, if no parent was specified). If still not found, then call the method `findClass` to load the class locally.

> - `findClass`
> Looks in this class loader for the specified class. This method should be overridden in new class loader implementations. Its default implementation throws `ClassNotFoundException`.

> - `getResource`
> Try fetching the resource from the parent class loader (or bootstrap class loader if no parent was specified). If still not found, then call the method `getLocalResource` to load the resource locally.

> - `findResource`
> Looks in this class loader for the specified resource. This method should be overridden by new class loader implementations. Its default implementation returns `null`.

> - `getResources`
> Returns an enumeration of all the resource URLs matching the specified resource name. This enumeration includes all of the matched resources of the parent class loader followed by the enumeration returned by `findResources`.

> - `findResources`
> Returns an enumeration of all the local resource URLs matching the given name. This method should be overridden by new class loader implementations. Its default implementation returns `null`.

> The delegation model provides a consistent and well defined search policy for loading classes and resources that simplifies class loader implementation. These changes are backward compatible and will not affect existing class loader implementations. However, applications that wish to create their own class loaders and use optional packages must use the delegation model.

> The following example demonstrates a simple network class loader:

>         public class NetClassLoader extends ClassLoader {
>             URL url;

>             public NetClassLoader(URL url, ClassLoader parent) {
>                 super(parent);
>                 this.url = url;
>             }

>             protected Class findClass(String name)
>                 throws ClassNotFoundException
>             {
>                 .. load class from URL ...
>             }

>             protected URL findResource(String name) {
>                 try {
>                     URL u = new URL(url, name);
>                     if (u.openConnection() != null) {
>                         return u;
>                     } else {
>                         return null;
>                     }
>                 } catch (java.net.MalformedURLException mue) {
>                        // handle exception
>                 } catch (java.io.IOException ioe) {
>                        // handle exception
>                 }
>             }
>         }

> This example will search the parent class loader (or bootstrap class loader, if no parent was specified) for classes and resources before checking the given URL. Classes and resources will be loaded according to the delegation model as described above.
> - `public class java.lang.Package`

> The method `isSealed` can be used to check if a package has been sealed, in which case it will return `true`. A second form of this method takes a URL and will return `true` if the package is sealed with respect to the specified URL. This can be used to in class loader implementations to keep track of currently sealed packages when loading new classes.

> - `public class java.net.URLClassLoader`

> This class provides the basic class loader support for optional packages and applications. It overrides both the `findClass` and `findResource` methods to search one or more base URLs for classes and resources. The search is lazy, such that a URL is not opened until needed.

> `URLClassLoader` manages a search path of URLs that is used to load classes and resources. Initially, this is set to the URLs specified when the class loader was created, but can be extended by `Class-Path` manifest attribute as described above.

> `URLClassLoader` supports all of the manifest attributes for versioning specified in The Java Versioning Specification.

> In addition, the following main manifest attributes are supported:

> - `Main-Class:` <classname> (no default)
> Specifies the main class of an application. This is used for invoking an application JAR file.

> - `Class-Path:` <urls..> (no default)
> Local search path of relative JAR and directory URLs for loading classes and resources. URLs not ending in '/' are assumed to refer to JAR files.

> - `Sealed:` <`true`|`false`> (default `false`)
> All of the packages defined in this JAR file, with the exception of the "null" package, are sealed. The "null" package can never be sealed. This header can also be used to seal individual packages.

*As used on this web site, the terms "Java Virtual Machine" or "JVM" mean a virtual machine for the Java platform.

Copyright © 1997-1999 Sun Microsystems, Inc. All Rights Reserved. Please send comments to: Java Software |