Java

Support for Extensions and Applications
in the Java 1.2 Platform

Contents

Introduction

Several enhancements have been made to the Java 1.2 platform to support both extensions and applications packaged as JAR files. The following is a description of these new enhancements as well as their usage. The initial motivation for introducing these changes was to provide some basic infrastructure for the delivery and deployment of extensions, but the mechanisms described in this document are general enough to support other uses as well.

What is an extension?

An extension is a group of Java packages that implement an API extending the Java platform. A standard extension is an implementation of an open, standard Java API (e.g., JavaServlet, Java3D, JavaManagement). Most standard extension packages are rooted in the javax.* namespace, although there may be exceptions.

An extension or application is packaged in one or more JAR (Java Archive) files.

The extension namespace is open, but it is recommended that companies follow the standard package naming conventions when implementing extensions. These conventions are outlined in The Java Language Specification, but the requirement that the domain prefix be specified in all upper case 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, since an application and the downloaded extensions may share the same class loader.

An implementation of an extension may consist of Java code and, less commonly, platform-specific native code. In addition, it may consist of various resources, such as properties, localization catalogs, images, serialized data, etc specific to the extension.

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

How is an extension deployed?

A Java extension may either be bundled with an application or installed in the JRE for use by all applications. Bundled extensions are provided at the same code base as the application and will automatically be downloaded in the case of network applications (i.e. applets ). Installed extensions are loaded when first used and will be shared by all applications running in the JRE.

Support for extensions in browsers such as Internet Explorer and Netscape Navigator is available through the Java Activator.

Currently, an extension that contains native code cannot be downloaded by network code, whether such code is trusted or not, into the Java VM at execution time. An extension that contains native code and is bundled with a network application must be installed on the JRE or JDK. This restriction may be removed in a future release.

Installation of extensions must be user-driven. We leave open the issue of cacheing and automatic upgrades. Other VM implementors may wish to layer such functionality on the infrastructure proposed here.

Solution

The basic solution consists of two parts:
  1. an extension or application packaged as a JAR file can declare dependencies on other JAR files, thus allowing an application to consist of multiple modules, and,

  2. the Java class loading mechanism is augmented to search installed extensions (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 extensions (and, more generally, libraries) that it needs. The system will prefer installed copies of extensions (and libraries) if they exist; otherwise, it will delegate to the class loader of the application to find and load the referenced extension (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.

Solution Elements

Packaging: What does an extension or application consist of?

Each extension or application consists of at least one JAR file containing an optional manifest, Java 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 JDK provides a convenient means of packaging Java extensions, although any ZIP-compatible archiving tool should work as well.

An extension 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.

A installed extension may additionally contain one or more DLLs (shared libraries) and EXEs (commands).

Installed is Shared; Bundled Is Private

Classes for installed extensions are shared by all code in the same Java 1.2 Virtual Machine. Thus, installed extensions are similar to system classes, but with an associated class loader and a pre-configured security policy as described below.

Classes for bundled extensions are private to the class loader of the application, applet or servlet. In the case of network applications such as applets, these extensions 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).

Dependencies: How does an application specify the other extensions it needs?

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

An application (or, more generally, JAR file) specifies the relative URLs of the extensions (and libraries) that it needs via the manifest attribute Class-Path. This attribute lists the URLs to search for implementations of extensions (or other libraries) if they cannot be found as extensions 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 extension. 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 extensions will originate from the same code base as the application. A future enhancement will leverage the facilities of the Java 1.2 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 extension 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 extension 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 x.jar b.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.

Installation: Where is an extension installed?

In Sun's implementation of the Java 1.2 Virtual Machine, the JAR files of a installed extension are placed in a standard local code source
<java-home>\lib\ext			[Win32]
<java-home>/lib/ext			[Solaris]
Its native code libraries, if any, are placed in
<java-home>\bin				[Win32]
<java-home>/lib/<arch>		     [Solaris]
Here <java-home> refers to the directory where the JDK or JRE was installed, and <arch> refers to the Solaris processor architecture (sparc or x86).

By default, installed extensions in this standard directory are trusted. That is, they are granted the same privileges as if they were included explicitly in the system class path. This default privilege is specified in the system policy file, but can be overridden for a particular extension by adding the appropriate policy file entry.

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

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

Sealing: How does a (standard) extension enforce consistency?

JAR files and packages can be optionally sealed, so that an extension 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 new package manifest attribute, Package-Sealed, whose value is true or false (case irrelevant). For example,

Name: javax/servlet/internal/
Package-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 new manifest header, Archive-Sealed, whose value is also true or false. For example,

Archive-Sealed: true
specifies that all packages in this archive are sealed unless explicitly overridden for a particular package with the Package-Sealed attribute.

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. For example, in the runtime JAR rt.jar all of the standard core Java packages with the exception of packages sun.io and java.text.resources are sealed.

Package sealing is checked for installed as well as downloaded extensions, 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.

Exported Packages: How does an extension hide implementation?

An extension JAR file can optionally limit the packages that are visible to other applications and extensions that use it. This feature can be used to hide packages that are part of an extension's implementation but not part of its specification. By default, all packages in an extensions are exported. The special "null" package is always exported and can never be hidden.

The exported packages for a JAR file can be specified using the new main manifest attribute Exported-Packages whose value is a list of one or more space-delimited package names. Any name ending with '*' will match any packages matching the specified prefix. For example:

	Exported-Packages: com.sun.3d javax.3d.*
specifies that package com.sun.3d should be exported, as well as any packages beginning with the prefix javax.3d. This feature can be used to export a package and all of its subpackages.

The per-entry manifest attribute Exported-Package, whose value is true or false, can also be used to specify whether or not a package is exported. It will override any packages specified through the Exported-Packages main attribute. For example,

	Name: javax/3d/impl/
	Exported-Package: false
specifies that package java.3d.impl should not be exported.

Security: What is an extension allowed to do?

The code source for a installed extension (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 Java policy configuration file
<java-home>/lib/security/java.policy
The default policy is for a installed extension to behave the same way it would if placed directly in the system class path. This follows from the common need for a installed extension to load native code.

The Java 1.2 Security Model provides some safety when installed extension code is called from untrusted code. However, like system code, extension code must be carefully reviewed for potential security breaches wherever it uses privileged blocks.

A remotely loaded extension 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 1.2 Security Specification for further details regarding how to write extension and application code to use the new security features.

API Details

The following classes have been changed or added in JDK/JRE 1.2 to support the new extensions mechanism:

Java Command Changes

Overview

The java command has been changed for JDK/JRE 1.2 in order to support standalone applications that use extensions. Previously, application classes had been loaded from the system class loader. In the new java command, an instance of URLClassLoader is created to load the application. The delegation parent is set to to the shared class loader maintained by the system for loading installed extensions. The resulting application class loader will then handle loading both installed and bundled extensions for the application.

Application Class Path

The property java.class.path is read to obtain the search path of URLs to use when creating the instance of URLClassLoader to load the application. This specifies the application's class path for loading application classes and resources. When loading a class or resource, the class loader will first search the system class path, then installed extensions, and finally the application class path.

A consequence of this change is that the property java.class.path no longer includes entries from the system class path. The system class path can now be obtained separately from the system property java.sys.class.path.

The CLASSPATH environment variable specifies the default value of the property java.class.path. If this environment variable is not set, then the default value for java.class.path is set to the current directory.

The option -classpath is now shorthand for setting the java.class.path property. Formerly, this option was used to override the search path for system classes. In the new java command there is no longer any need to set the system class path.

New Command Options

-cp

The option -cp which had previously been part of only the jre command has now been added to java as well. Since it is no longer necessary to prepend the system class path this option is now merely an alias for -classpath.

For example, the following command usages are all equivalent:

	java -classpath foo.jar:bar Foo
	java -Djava.class.path=foo.jar:bar Foo
	java -cp foo.jar:bar Foo

-usepolicy

By default, applications are invoked without a security manager so that no policy checking is enabled. This is compatible with the previous command behavior where everything was loaded from the system class path.

If the new option -usepolicy[:file] is specified then a default security manager will be installed in order to enable policy checking. An optional policy file can also be specified to use in addition to the default system policy file.

The -usepolicy flag is shorthand for setting the property java.use.policy and, optionally, java.policy if a policy file was also specified. For example, the following command usages are equivalent:

	java -usepolicy:mypolicy foo
	java -Djava.use.policy=true -Djava.policy=mypolicy foo
Consult the Java 1.2 Security Model specification for detailed information on how policy files are used to control security.

-jar

For conveniently running applications packaged in JAR files the new -jar option has been added. This allows applications in JAR files to be executed directly using the java command.

When using the -jar option the java.class.path property is set to the JAR file being executed and overrides any other definition specified via the -classpath or -cp options. The JAR file's manifest is then consulted to find the name of the application's main class specified via the Main-Class manifest attribute. For example, if the manifest for server.jar contained the following attribute:

	Main-Class: com.sun.server.Main
then server.jar could be executed using either of the following:
	java -jar server.jar
	java -Djava.class.path=server.jar com.sun.server.Main

Executable JAR Files

On Win32 systems the installation program will register a default association for JAR files so that double-clicking a JAR file on the desktop will automatically run it with java -jar. Dependent extensions bundled with the application will also be loaded automatically. Such a feature will make the end-user JRE easier to use on Win32 systems.

The Solaris 2.6 kernel has already been extended to recognize the special "magic" number that identifies a JAR file, and to invoke java -jar on such a JAR file as if it were a native Solaris executable. A Java application packaged in a JAR file can thus be executed directly from the command line or by clicking an icon on the CDE desktop.

JRE Command

The jre command is obsolete for JRE 1.2 and has been merged with the java tool. The only environment variable still used is CLASSPATH and this can now be overridden by specifying the -classpath or -cp option. The -cp option which used to prepend the system class path in the JRE is now identical to -classpath in the new java command.

Compatibility

Applications which install their own class loaders or security managers may not be able to run under the new java command until they are updated for JDK/JRE 1.2. These applications must be updated to use the new security features and delegation class loader introduced in JDK/JRE 1.2.

For compatibility we still provide the old-style launcher behavior in the command oldjava which can be used to run applications from the system class path as in JDK/JRE 1.1. However, extensions are not supported with the oldjava command.


Copyright © 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.

Please send comments to: JavaSoft
Sun

JavaSoft
Last modified: Fri Mar 13 13:46:43 PST