java.lang.isolate
Class Isolate

java.lang.Object
  |
  +--java.lang.isolate.Isolate

public final class Isolate
extends Object

The Isolate class provides the means of creating and managing isolated computations and arranging for their communication with each other.

An isolated computation ("isolate" for short) at a minimum shares no objects or mutable static state with any other computation. The Isolate object corresponding to an isolate supports operations on the isolated computation. Multiple isolates may hold an Isolate object corresponding to the same isolated computation (i.e. an Isolate instance is a "handle" to an isolate).

By convention, capitalization is used to distinguish an Isolate class or class instance from a reference to the isolate abstraction.

Class path

Part of the definition of an application is the application classpath, where the basic classes for the application are found. The Java runtime typically searches for classes in three sets of locations: the bootstrap class path, the installed extensions directory, and the application class path. The bootstrap class path and installed extensions directory are constant for the original isolate and all its progeny (called an isolate aggregate); only the application class path can be specified with a new isolate.

The application classpath is specified for a new isolate by the java.properties/java.class.path preference in the context (see getContext. The current isolate's class path is readable from the java.class.path property. The bootstrap classpath is visible in the java.bootclass.path property.

Note that the definition of the elements of the java.class.path is specified by the implementation. (Usually, it consists of file system directories and the full path to .jar files, but it could be database schema names, URLs, etc.)

Class Caching

Some implementations may "cache" classes between execution of isolates, to share class name resolution costs and spread the costs of finding and loading bytecodes for example.

The only way such "class caching" could interfere with user expectations is when a new isolate is created that should contain the latest available version of a class and not a cached version. For example, when developing servlets, it would be helpful if the servlet engine (assuming it runs each servlet in its own isolate) used the latest development version of the servlet code being debugged and not the first version it encountered.

The Isolate API supports this sort of application through the preference java.class.allow-caching. This preference defaults to the value true; if set to false, the VM guarantees that the new isolate will find classes as if it had been started in a new aggregate (i.e., using whatever mechanism the classes are located with at the lowest levels of the VM).

The java.class.allow-caching property has no effect on the classes loaded by the bootstrap class loader or on the standard extension classes.

For some implementations, for example, one that looks for classes in a read-only repository (such as ROM memory), setting the java.class.allow-caching property to false will make no difference: there is no difference between any possibly "cached" classes and the repository versions.

Similarly, setting the java.class.allow-caching property to true does not guarantee that cached classes will be used. Implementations are free to implement full loading and resolution of classes in each isolate. Even implementations that do support caching will probably have restrictions on when class caching is used (for example, only for a specific, well-defined java.class.path).

Basic communication

Because each isolate has its own logical heap and there are no visibly shared Java objects, isolates must communicate through other mechanisms. In addition to all of the pre-existing mechanisms, there are several isolate-specific mechanisms.

All pre-existing mechanisms that work between separate instances of the Java Virtual Machine should continue to work between isolates, such as network-based communication via sockets or RMI, the file system, persistent preferences, etc.

The following isolate-specific methods are also available:

Arguments for main()
The static main method in the initial class to start in a new isolate takes a String[] argument. The contents of the array are entirely application defined, and the array may be zero-length or null. Obviously, only String objects convertable to String may be copied through this interface.
TransientPreferences
The TransientPreferences, or context, parameter to the Isolate constructor provides a structured method for passing information to a new isolate. A logical copy of the TransientPreferences object passed by the parent is available to the child via the static getContext method. See the method doc for details of the format of the standardized areas of the context parameter.
System properties
System properties are the properties readable through System.getProperty. In addition to the standard properties outlined in the documentation for getProperties() (and elsewhere in the java specification), properties can contain VM-defined properties and application-defined properties. By default, a new isolate receives a copy of the aggregate default property values.

The java.properties/ node of a new isolate's context allows a creator to specify properties for the new isolate.

Standard streams
The streams passed to the Isolate constructor via the IsolateStreamBindings parameter can be used to establish byte-oriented connections between an isolate and its creator.
Initial Links
The initial links are passed via the start method (and retrieved in the new isolate via the static getLinks method). Like the standard i/o streams, links are a more dynamic method of data passing. Unlike the streams, the links support copying more complex objects, such as instances of Link, Isolate and Socket between isolated applications. See LinkMessage for details.
The initial class
The initial class provided to a new isolate can be a less flexible means of supplying information to the new isolate by coding information into the class. For example, a class which initializes the security environment of a new isolate to a well-defined state might be useful. Such classes are usually only useful if they subsequently load and initialize another class.

Since:
JDK1.5
See Also:
Link.newEventLink(java.lang.isolate.Isolate, java.lang.isolate.Isolate), IsolateEvent, IsolatePermission, Link, ResourceException, IsolateStartupException

Constructor Summary
Isolate(String mainClass, String[] mainArgs)
          Creates a new isolated java application with a default configuration.
Isolate(String mainClass, String[] mainArgs, TransientPreferences context, java.lang.isolate.IsolateStreamBindings bindings)
          Creates a new isolate java application with the specified context and standard streams.
 
Method Summary
static java.lang.isolate.Isolate currentIsolate()
          Returns an Isolate object corresponding to the currently executing isolate.
 boolean equals(Object other)
          Returns true if and only if the given Isolate object refers to the same isolate as this Isolate object.
 void exit(int status)
          Requests normal termination of the isolate this Isolate represents.
static TransientPreferences getContext()
          Returns the context associated with the current isolate.
static java.lang.isolate.Isolate[] getIsolates()
          Returns an array of Isolate objects corresponding to all isolates that have been started but have not terminated at the point of invocation.
static java.lang.isolate.Link[] getLinks()
          Retrieves a copy of the Link array passed to start by the current isolate's creator.
 void halt(int status)
          Forces termination of the isolate this Isolate represents.
 int hashCode()
          Returns the hashcode for this Isolate.
 boolean isTerminated()
          Returns true if the isolate this Isolate represents is terminated.
 java.lang.isolate.Link newEventLink(java.lang.isolate.Isolate receiver)
          Gets a new Link associated with this Isolate from which the given receiver isolate can receive events.
 void start(java.lang.isolate.Link[] links)
          Signals that the isolate this Isolate represents may begin execution.
 String toString()
          Returns a string identifier for this Isolate.
 
Methods inherited from class java.lang.Object
getClass, notify, notifyAll, wait, wait, wait
 

Constructor Detail

Isolate

public Isolate(String mainClass,
               String[] mainArgs)
        throws IsolateStartupException
Creates a new isolated java application with a default configuration. When started the new isolate will execute the main method of class mainClass with arguments mainArgs. The mainClass parameter should reference a class present in one of the classpath elements of the default "java.class.path" property.

This constructor has the same effect as invoking the long constructor with null for all the other parameters. Specifically, the new isolate is given a default context, and its standard I/O is directed to the original streams defined for the current isolate. (See the long constructor documentation for more details).

Any changes made to the constructor's parameters after control returns will not be visible in the newly created isolate.

When the constructor returns, the new isolate is not running (as far as the user can tell). The new isolate does not really start until the start method is invoked. No events are delivered to any registered listeners until after start is invoked. The halt and exit methods will fail if invoked between construction time and start time.

Because class resolution and loading are performed by the new isolate, any loading exceptions (such as ClassNotFoundException) will occur in the new isolate (not the creator) when it is started.

Parameters:
mainClass - fully qualified name of the main method class
mainArgs - the arguments of the main method in the new isolate
Throws:
SecurityException - if a SecurityManager is present and it denies IsolatePermission("create").
ResourceException - if insufficient resources are available to create the isolate
IsolateStartupException - if an error occurs in the configuration or startup of the new isolate before any application code is invoked

Isolate

public Isolate(String mainClass,
               String[] mainArgs,
               TransientPreferences context,
               java.lang.isolate.IsolateStreamBindings bindings)
        throws IsolateStartupException
Creates a new isolate java application with the specified context and standard streams. When started the new isolate will execute the main method of class mainClass with arguments mainArgs. The mainClass parameter must reference a class present in one of the classpath elements of the java.class.path property of the new isolate.

When the constructor returns, the new isolate is not running (as far as the user can tell). The new isolate does not really start until the start method is invoked. No events are delivered to any registered listeners until after start is invoked. The halt and exit methods will fail if invoked between construction time and start time.

Because class resolution and loading are performed by the new isolate, any loading exceptions (such as ClassNotFoundException) will occur in the new isolate (not the creator) when it is started.

Changes made to any of the constructor's parameters after control returns from this constructor will have no effect on the newly created isolate.

If mainArgs is null, a zero-length String[] will be provided to the main method of mainClass.

If the context parameter is null, a default, system-defined context will be supplied to the new isolate. The context parameter can contain app-specific and/or system-specific arguments, including system properties for the new isolate. See Isolate.getContext for details on the system defined entries and their semantics. By default, a new isolate gets a copy of the aggregate default system properties. The system may modify the context as it is copied into the child.

If the stdio parameter is null, the standard I/O streams defined on java.lang.System in the new isolate will be copies of the original standard I/O streams of the current isolate. If any streams provided by the stdio parameter are closed, an IsolateStartupException will be thrown; those streams may be safely closed after the constructor returns and that will not impact the new isolate.

Jar Files

To execute a jar file in a new isolate (similar to the -jar option supported by some java commands), the "Main-Class" attribute must be extracted from the jar's manifest. Additionally, the jar file must be placed on the class path for the new isolate.

The following example loads and executes "app.jar" in a new isolate. First, the name of the main class is extracted from the jar's manifest:

 String jarFileName = "app.jar";
 String mainClassName = new java.util.jar.JarFile(jarFileName)
     .getManifest()
     .getMainAttributes()
     .getValue(java.util.jar.Attributes.Name.MAIN_CLASS);
 
Second the java.class.path property for the new isolate is set with the name of the jar file.
 TransientPreferences p = new TransientPreferences();
 p.put("java.properties/java.class.path", jarFileName);
 
Finally, the isolate is created and started with the main class and the preferences containing the appropriate classpath.
 Isolate jarIsolate = new Isolate(mainClassName, null, p, null);
 jarIsolate.start();
 

Implementation Notes

The implementation is free to just hold on to the constructor parameters or to start a new container for the isolated application and begin execution of system code in that new container. The only restriction is that no "user code" (no main method, no static initializers, etc.) is executed in the new isolate before the start is invoked.

Note that implementations that start the underlying isolate container at construction time may have to garbage collect it if start is never invoked and the Isolate becomes unreferenced.

Implementations that start asynchronous execution of the isolate's system code at construction time must deal with buffering errors in the child until start time.

"User code" can be defined as code loaded off the java.class.path. Bootstrap classes, standard classes, and extension classes can be considered "system code."

Parameters:
mainClass - fully qualified name of the main method class
mainArgs - the arguments of the main method in the new isolate
context - the application context and system properties
bindings - the standard stream bindings
Throws:
SecurityException - if a SecurityManager is present and it denies IsolatePermission("create").
ResourceException - if insufficient resources are available to create the isolate
IsolateStartupException - if an error occurs in the configuration or startup of the new isolate before any application code is invoked
IllegalArgumentException - if any parameters are found to be invalid.
See Also:
getContext(), IsolateStreamBindings
Method Detail

start

public void start(java.lang.isolate.Link[] links)
           throws IsolateStartupException
Signals that the isolate this Isolate represents may begin execution. Prior to this method's use, no application code (including static initializers) has been executed. Control will return from this method when the new isolate's first user level thread starts executing or if an error occurs during the initialization of the new isolate.

A null links parameter results in the new isolate getting a zero length array of Link objects. Changes to the links parameter following return from this method will have no effect on the started isolate.

Any null entries in the Link array will cause an IllegalArgumentException to be thrown.

An IsolateStartupException will be thrown if any of the given Link objects are closed.

After start has been invoked (and potentially before it returns), the "started" event should be delivered on any relevant event links.

If any exception is thrown by this method, no application code will have executed. Additionally, exactly one of the two following cases will hold:

Errors such as the main class being invalid or not visible in the java.class.path will generally be handled within the new isolate by the default uncaught exception handler.

Parameters:
links - the array of zero or more Link objects available to the isolate or null
Throws:
IllegalStateException - if this isolate was already started or is terminated or if start was invoked in a different isolate from the creator
ResourceException - if insufficient resources to create and/or start isolate
IsolateStartupException - if an error occurs in the initialization or configuration of the new isolate before any application code is invoked.
SecurityException - if the links parameter is non-null and a SecurityManager is present and it denies IsolatePermission("send.Link")
See Also:
Link, IsolateEvent.STARTING, getLinks()

getLinks

public static java.lang.isolate.Link[] getLinks()
Retrieves a copy of the Link array passed to start by the current isolate's creator. Modification of this array will have no effect on subsequent invocation of this method.

This method never returns null: it will return a zero-length array if null was passed to start by the parent isolate.

Returns:
an array of zero or more Link objects
Throws:
SecurityException - if the links parameter is non-null and a SecurityManager is present and it denies IsolatePermission("receive.Link")

exit

public void exit(int status)
Requests normal termination of the isolate this Isolate represents. Equivalent to causing the isolate to invoke Runtime.exit(int). If this method invocation is, in fact, the cause of the isolate's termination, the status supplied will be the isolate's termination status.

No exception is thrown if this isolate is already terminated. Even if isTerminated() returns false prior to invoking exit, an invocation of exit may occur after the isolate exits on its own or is terminated by another isolate. In these cases, the actual exit code reported by the isolate may be different from the one specified.

Parameters:
status - By convention, a nonzero status code indicates abnormal termination.
Throws:
SecurityException - if security policy does not permit this operation
IllegalStateException - if this isolate is not yet started
See Also:
IsolateEvent.TERMINATED, IsolateEvent.getExitStatus()

halt

public void halt(int status)
Forces termination of the isolate this Isolate represents. Equivalent to causing the isolate to invoke Runtime.halt(int). If this method invocation is in fact the cause of the isolate's termination, the status supplied will be the isolate's termination status.

No exception is thrown if this isolate is already terminated. Even if isTerminated() returns false prior to invoking halt, an invocation of halt may occur after the isolate exits on its own or is terminated by another isolate. In these cases, the actual exit code reported by the isolate may be different from the one specified.

Implementation Note

Implementations should strive to implement "quick" termination with as little coordination with the target isolate as possible. The only information required of a terminated isolate is the exit code it was terminated with.

Parameters:
status - Termination status. By convention, a nonzero status code indicates abnormal termination.
Throws:
SecurityException - if security policy does not permit this operation
IllegalStateException - if this isolate is not yet started

isTerminated

public boolean isTerminated()
Returns true if the isolate this Isolate represents is terminated. See IsolateEvent.TERMINATED for the meaning of "terminated."


newEventLink

public java.lang.isolate.Link newEventLink(java.lang.isolate.Isolate receiver)
                                    throws ClosedLinkException
Gets a new Link associated with this Isolate from which the given receiver isolate can receive events.

This method is equivalent to:

   Link.newEventLink(this, receiver);
 
See the Link.newEventLink method for further details.

Parameters:
receiver - The Isolate that will receive events from this Isolate.
Returns:
a new Link associated with this isolate
Throws:
IllegalArgumentException - if receiver is equal to this Isolate.
ResourceException - if there are insufficient resources to allocate the link or if either isolate is in the terminated state
ClosedLinkException - if either isolate is in the terminated state

currentIsolate

public static java.lang.isolate.Isolate currentIsolate()
Returns an Isolate object corresponding to the currently executing isolate.

This method never returns null.

Returns:
the Isolate object for the current isolate

getContext

public static TransientPreferences getContext()
Returns the context associated with the current isolate. The returned context is a deep copy of the context parameter supplied by the parent when the current isolate was created or a default context if none was supplied by the parent. The returned context may have been modified by the system when it was copied.

The first isolate in a new aggregate is provided with a non-null context. Although no standard values are defined for this context implementation-specific values are possible.

Changes to the context are not reflected in any other isolate. The returned preferences object is mutable.

This method never returns null.

The usage of a TransientPreferences instance for defining a new isolate's "context" can be broken down into several categories. The context can be used to set standard preferences, implementation-specific preferences, and application specified preferences. The context also holds per-isolate system properties (i.e., those available from System.getProperty). The default context and how an application-provided context will be merged are defined here.

Standard Context Preferences

The name space of the context preferences object is structured similarly to the Java class name space. The java. prefix is reserved for standard system-defined names defined by a Java API; non-standard names are encouraged to use a reverse-domain-name prefix.

The following context preferences are defined in the java.* name space by this specification:
NameTypeDefinition
java.class.allow-caching Boolean A hint for class caching. See Class Caching.
java.properties/ (node) Contains properties to set in a child isolate. This item defines a properties node in which specific properties may be defined, each with type String. See System Properties below.

Implementation Specific Preferences

All parts of the transient preferences namespace except those with a "java." prefix are outside this specification. A reverse-domain-name prefix convention is suggested for vendor specific preferences (e.g. "edu.utah.cs.janosopts"). An exception to this convention is the "options" key shown below, intended for passing a collection of implementation-defined options in the cases where they would be meaningful:
NameTypeDefinition
options String Java implementation-specific options e.g. "-Xmx64m -Xcheck:jni"

Application Preferences

Any portion of the transient preferences namespace not defined by standard or implementation-specific preferences is available for defining application state using the full set of types and naming hierarchy. Use of preferences in place of properties for communicating application state is strongly recommended (unless per-name access checks are required; only properties provides that).

Properties

Any entries in the java.properties/ node, (if the node exists), will have the node prefix stripped and be set as a String in the System properties of the new isolate. The property values can then be accessed within the new isolate via the normal manner (i.e., System.getProperty). For example, putting the key "java.properties/org.tullmann.prop" with value "prop value" in the context for a new isolate will cause the system property "org.tullmann.prop" to be set to "prop value" in the new isolate. Any properties defined by a parent in the java.properties/ node of the context will not be visible in context returned from Isolate.getContext in the created isolate, and the node itself will be absent.

Implementation Specific Properties

Implementation-specific properties (e.g., those prefixed with "com.sun.", etc.) are implementation-defined with respect to their per-isolate or aggregate-wide nature.

System Properties

Properties defined by other parts of the Java standard, for example, Java Security properties and JNDI properties, will be honored on a per-isolate basis. For example, adding "java.properties/java.security.manager" to a new isolate's context will enable the default security manager in that isolate as specified by the Java 2 Platform Security Architecture.

However, many of the standardized system properties documented on System.getProperties may be silently ignored if set in "java.properites/. For many of them, the code that reads and uses them may execute once at aggregate startup time (and thus per-isolate values will not be used for anything). Only the "java.class.path" property is guaranteed to be honored on a per-isolate basis. The behavior of setting any other such property is implementation-specific. For example, setting the property "file.separator" in a new isolate may or may not set that property in the new isolate, and even if the property is set in the new isolate, it may or may not have an impact. The only portable usage of these properties is to not set them on a per-isolate basis (excepting "java.class.path").

The following table lists the properties from System.getProperties whose per-isolate behavior are implementation-defined:
KeyDescription of Associated Value
java.version Java Runtime Environment version
java.vendor Java Runtime Environment vendor
java.vendor.url Java vendor URL
java.home Java installation directory
java.vm.specification.version Java Virtual Machine specification version
java.vm.specification.vendor Java Virtual Machine specification vendor
java.vm.specification.name Java Virtual Machine specification name
java.vm.version Java Virtual Machine implementation version
java.vm.vendor Java Virtual Machine implementation vendor
java.vm.name Java Virtual Machine implementation name
java.specification.version Java Runtime Environment specification version
java.specification.vendor Java Runtime Environment specification vendor
java.specification.name Java Runtime Environment specification name
java.class.version Java class format version number
java.library.path List of paths to search when loading libraries
java.io.tmpdir Default temp file path
java.compiler Name of JIT compiler to use
java.ext.dirs Path of extension directory or directories
os.name Operating system name
os.arch Operating system architecture
os.version Operating system version
file.separator File separator ("/" on UNIX)
path.separator Path separator (":" on UNIX)
line.separator Line separator ("\n" on UNIX)
user.name User's account name
user.home User's home directory
user.dir User's current working directory

Default Context

If a creator passes null for the context parameter to the long Isolate constructor, the system will create a preferences object in the new isolate. This preferences object will have no standard preferences defined in it nor a java.properties node.

The preferences object returned from Isolate.getContext in this scenario may contain implementation-defined properties.

Default system properties

The set of system properties defined in a new isolate is a combination of the aggregate default system properties, implementation-defined properties, and the properties provided by the parent in the context argument. Properties provided by the context take precedence over aggregate default system properties, except for the exceptional cases listed above. The precedence relation of parent-provided properties and implementation-defined properties is implementation-defined.

For example, consider the standard system properties "java.home" and "java.class.path". The property "java.home" is an exceptional case, so its value in a new isolate will most likely be the aggregate default value, regardless of what the parent provides (though the exact behavior is implementation-defined). The "java.class.path" property will default to the aggregate default value, but any parent-provided value will take precedence.

Relation between parent and child context

The values defined in the java.properties node of a context are not made available in the child's copy of the context. The child isolate must access the values for any properties through existing property access mechanisms (i.e., System.getProperty).

All other preferences in the context returned by Isolate.getContext() in a child isolate reflect the values provided by the parent. Implementations are free to define entries in the context. For example, an implementation could report the UNIX pid of a process containing an isolate in a context entry (e.g., "org.tullmann.mpisolate.currentpid"). Any value provided by a parent for these kinds of implementation-defined properties will be ignored.

Returns:
context for the current isolate
Throws:
SecurityException - if a SecurityManager is present and it denies IsolatePermission("context")

getIsolates

public static java.lang.isolate.Isolate[] getIsolates()
Returns an array of Isolate objects corresponding to all isolates that have been started but have not terminated at the point of invocation. New isolates may have been constructed or existing ones terminated by the time this method returns.

Returns:
the active Isolate objects present at the time of the call
Throws:
SecurityException - if a SecurityManager is present and it denies IsolatePermission("enumerate")

hashCode

public int hashCode()
Returns the hashcode for this Isolate.

Returns:
the hashcode

toString

public String toString()
Returns a string identifier for this Isolate.

Returns:
the identifier string

equals

public boolean equals(Object other)
Returns true if and only if the given Isolate object refers to the same isolate as this Isolate object.

Parameters:
other - Isolate to compare this with
Returns:
true if this Isolate is the same as the other Isolate