Package java.lang.isolate

Provides for the creation and management of isolated applications.

See:
          Description

Interface Summary
LinkMessageDispatcher.Listener A listener interface for receiving messages on a Link.
 

Class Summary
Isolate The Isolate class provides the means of creating and managing isolated computations and arranging for their communication with each other.
IsolateEvent Isolate events represent state changes in an isolate lifecycle.
IsolatePermission This class represents access control to the isolate creation and management.
IsolateStreamBindings This class specifies the binding of a set of streams to a child isolate's standard streams.
Link A Link supports communication between isolates.
LinkMessage A LinkMessage wraps the various types that can be sent through a Link.
LinkMessageDispatcher Receives and dispatches messages to listeners.
LinkMessageVisitor An abstract utility class used to process a LinkMessage containing arbitrary data via LinkMessage.acceptVisitor.
 

Exception Summary
ClosedLinkException An exception thrown when a closed link condition prevents completion of a Link operation.
IsolateStartupException An exception thrown when the implementation is unable to start execution of a new isolate due to an error or exceptional condition in the bootstrap code for the new isolate (i.e., before the application starts).
LinkSerializationException An exception thrown as the result of one of a number of underlying serialization-related exceptions.
 

Package java.lang.isolate Description

Provides for the creation and management of isolated applications. Using the java.lang.isolate classes, users can create isolated environments for running untrusted code, application extensions, or other code that should be isolated.

JSR-121: Java Application Isolation API Specification

1. Introduction

JSR-121 specifies a new fundamental facility for supporting multiple applications in the Java programming language. The java.lang.isolate package provides programming-level support for creating, starting, stopping, managing, and communicating with otherwise separate Java programs.

The Java Application Isolation Specification ("Isolate API") is in two parts. This document contains the rationale and overview. The surrounding javadoc contains specific details for the classes, methods, and semantics of the API organized by class.

The only fundamental requirement of JSR-121 that cannot be stated in the API specification is that henceforth, all static methods and fields (as well as associated JVM and JNI facilities) that are worded to have per-program scope are to be interpreted as acting on a per-isolate basis unless explicitly stated otherwise. Section 3 completely specifies the remainder of the API, but users and implementors will probably find Section 2 useful as a brief guide.

2. Rationale

1. The Role of Isolates

The choice of the uncommon (but accurate) name Isolate (pronounced "isolet") for the main class avoids ambiguities and misleading connotations of more common terms, such as "process" and "task." It also emphasizes the basic property that isolates do not and cannot share access to objects. For example, the static variables in each isolate are  unique to that isolate.

Informally, isolates are a construct midway between threads and JVMs. Like threads, they can be used to initiate concurrent execution. Like JVMs, they cause execution of a "main" method of a given class to proceed within its own system-level context, independently of any other Java programs that may be running. Thus, isolates differ from threads by guaranteeing lack of interference due to sharing statics or per-application run-time objects (such as the AWT thread and shutdown hooks), and they differ from JVMs by providing an API to create, start, terminate, monitor, and communicate with these independent activities.  The Isolate API is intended to provide a minimal yet complete interface for the many applications and frameworks that might take advantage of such a facility.

jvms and isolates

The Isolate API is intended to be implementable in at least three very different styles:

  1. All-in-one. A JVM is constructed within a single operating system  (or hardware-level) process but guarantees isolation by, among other things, managing separate "address spaces" for each isolate.
  2. One-to-One. A JVM manages a set of OS-level processes, one per isolate.
  3. Clustered. An extension of (2) in which isolates may reside on different machines of a tightly coupled cluster operating within a single administrative domain.
The term aggregate in the context of isolates will be used to refer to the set of isolates sharing a common ancestor. Thus with the styles list above, an aggregate involves only one OS or hardware level process for an all-in-one implementation while for the other two styles, multiple isolates belonging to an aggregate implies multiple processes. This specification defines no mechanism for communication between separate aggregates.

JSR-121 is a J2SE, not a J2ME specification. However, it is designed to be subsetted in an obvious way for J2ME. (Essentially, all differences lie in LinkMessage, which is necessary because of differences in IO and related types across J2SE and the various J2ME profiles.)

While we expect isolates to be used across a wide range of systems, we have specifically focussed on support of the following usage scenarios in which, to maximize performance, reliability, controllability, and/or security, each independent component should be run independently of all others:

  1. Independent applications. For example, a system may choose to initialize a JVM upon boot or login time and arrange that the "java" command create a new isolate to run the given application.
  2. Containment Frameworks. Layered frameworks that execute "*lets" (Servlets, Applets, etc.) may provide options to run them as isolates.
  3. Server Forks. A network service may choose to spawn handlers servicing new clients as isolates.
  4. Fault tolerance. A system may choose to run multiple versions or redundant copies of essential services in separate isolates to enhance reliability.
  5. Clustered Execution. Analogs of "Beowulf clusters" and related frameworks arrange parallel execution of computationally intensive programs across the nodes of a cluster.
Each of these target use cases (as well as several variants and extensions) introduces different requirements and constraints. However, it is not the goal of JSR-121 to actually construct any of these frameworks, but only to make them possible, while maintaining a small, easy-to-learn API that fits well with other features of the language. Similarly, JSR-121 does not address issues related to but beyond the scope of simple isolation, including resource controls.

2. Isolate Lifecycle

The API for constructing isolates must accommodate all of the ways in which users can execute "Java programs." This entails supplying the class name, class path, arguments, and so on. Perhaps ideally, all of these would be encapsulated in a common structure, but to maintain compatibility with existing code and practice, the API dealing with creating and starting isolates supports a diverse collection of parameters, separately dealing with Properties, IO settings, etc. However, we also introduce a simple uniform mechanism to support non-historically-bound settings. The isolate context based on the java.util.prefs.Preferences API. JSR-121 does not specify how an isolate context is to be used but does predefine some name-value pairs and how they are to be interpreted by JVMs. We expect that some layered frameworks will continue to use yet other mechanisms (such as JNDI) within newly created isolates to establish other aspects of execution context.

The choice of defaults for the various creation parameters is intended to simplify the most common usages while still making it possible to provide the fine degree of control required in containment frameworks.

All of the isolates running under a given JVM share a few minimal, immutable Properties settings, including User identity and initial security policy. They also implicitly share any underlying system context; for example, all isolates must share the same view of the current file system. Even here though, there is a potential ambiguity about whether class files that have been updated since the construction of a JVM but before construction of a given isolate will be freshly loaded for that isolate. This is resolved by a predefined isolate context setting that controls whether updated class files must (as opposed to may) be loaded with the new application.

As with threads, the Isolate API separates the points of creating an isolate (establishing its existence without running any application code, not even static initializers) and starting it (causing it to run application code). This provides flexibility for both users and implementors, at the cost of some minor uncertainties. We do not specify whether the act of creating an isolate will consume resources or execute system-level code; all of this may be deferred to "start" time. Thus, the set of exceptions that may be thrown at each point overlaps.

Like a Java program, but unlike a thread, an isolate may be terminated either "normally" or "abruptly." Usage and semantics precisely parallel that for System.exit and System.halt. An explicit termination event is available to signal the point at which no user code will execute in the associated isolate ever again.

No special API is provided to start or stop a JVM, as opposed to an isolate. Note that a JVM that has no isolates cannot execute any bytecodes, so is not very useful. We expect that the most common implementation of shell-level "java" commands will use system-specific techniques to establish a "primordial" isolate that may in turn spawn other isolates. A JVM itself may terminate when all of its isolates do.

3. Communication

The Link class and its subclasses and helper classes provide a basic, fairly low-level communication medium across isolates. Minimally, the Link subclasses can be used to establish other communication mechanisms. To maintain isolation, Links provide only "data" passing facilities; normal Java Objects cannot be shared by passing them. However, to minimally support interaction, links may be used to pass the "special" types Isolate and Link, as well as a set of IO-types necessary to delegate service handling across isolates (for example, to support "Server Forks"). The existence of these "special" types introduces some slight irregularity, as well as some J2SE/J2ME differences, but this is a consequence of other choices made for supporting IO across different packages and frameworks. It would have been beyond the scope of JSR-121 to force all relevant APIs and specs to be reworked solely for the sake of making a slightly more elegant link API. Instead, all of the expected variation is encapsulated in the LinkMessage class that controls which types can be sent and received across links.

Like isolates, links provide a simple, reliable, efficient basis for layered frameworks. For example, JSR-121 does not state whether or how full RMI or CORBA is to be used to communicate across objects residing in different isolates (i.e., as a special case of RMI). However, the Link interfaces are intended to support the adaptation of such frameworks in a very straightforward fashion. Finally, any current inter-JVM communication mechanism (networking, RMI, file systems or shared memory) will continue to work for between isolates.

4. Monitoring and Management

The Isolate API does not enforce or even encourage any particular management style or topology of control across isolates. The only special relationship that a "parent" isolate has with a newly created "child" isolate is that the parent establishes the child's initial context. In all other respects, the parent and child are oblivious to each other unless programmers specifically arrange monitoring or communication between them.

Assuming that it has a handle to it, any isolate can register to receive "lifecycle" events from any other isolate. JSR-121 predefines only three events: starting (issued when the isolate's initial application-level thread begins execution), stopping (issued when the isolate first begins its shutdown process), and terminated (issued upon completion of isolate shutdown). A link created for event handling is used to receive these events, and LinkMessageDispatcher can be optionally used to simplify listening for events from multiple isolates.

Similarly, assuming that it has both a handle and appropriate permissions, one isolate may cause another to exit or halt. The effects of termination are precisely the same as if they were invoked from within the target isolate.

JSR-121 does not explicitly provide any other kinds of monitoring events, controls, or grouping constructs, but the supplied classes and methods can be used to create a wide range of framework-specific management regimes, including those tied to external monitoring APIs such as JMX.

5. Security

JSR-121 introduces few security concerns. The basic functionality of the Isolate class is access-checked via a new IsolatePermission class. Permissions are checked during the acts of creating Isolate instances, invoking exit or halt, getting the current isolate context, sending or receiving an object on a link, passing a link to a new isolate via start, and enumerating all Isolate instances. In the default security policy all permissions except for retrieving the current isolate context are denied. Of the isolate-related permissions, users and framework developers should pay special attention to the "create" and "enumerate" permissions. The "enumerate" permission guards the only method that can obtain the handles of arbitrary isolates. The "create" permission lets the creator define the security environment of the new isolate, allowing it to circumvent any existing policy.

Beyond these concerns, security relies on the combination of guarantees that isolates cannot share references to objects, along with a capability-style scheme for helping to ensure that handles to other isolates can easily be confined to objects serving as managers.

Because all isolates view a common file system, all isolates by default rely on common default policy files.

6. JNI

JSR-121 does not strictly guarantee full isolation in the presence of native code. The degree of isolation with respect to JNI code is treated as a quality of implementation property. Some JVM implementations may indeed guarantee that native code running in one isolate cannot affect others (with probable costs to efficiency), but the range of platforms supporting JVMs and the range of potential limitations lead us to the practical decision not to strictly require any particular properties.

Related Documentation

Any available overviews, tutorials, examples, and guides will be on the forthcoming JSR-121 Info Page (During Community Review JCP members must use id "jsr121" password "frabalitious" to access this page).

The JCP's JSR-121 jcp.org page will only contain formal spec files in addition to the original JSR proposal. @since 1.5