java.lang.isolate
Class Isolate

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

An isolated computation (or isolate) 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).
In contrast an aggregate is defined as the set of isolates that share a common
ancestor isolate.

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

For example, the following code will run the public static main
method (which returns void and takes a single String[] argument)
of the public class org.example.Main with the
single argument "-help" in a new isolate. The output of the new isolate will be
printed to the standard output streams of the invoking isolate:

In addition to a main class and its arguments, the constructor of
an isolate can specify a Preferences-based "context" for the new isolate, redirect the
standard I/O of the isolate, and establish communication with the
isolate. Each of these topics are addressed in turn.

The context parameter to the long Isolate
constructor allows a creator to specify application-defined and
system-defined parameters for the new isolate. For
application-defined parameter, the new isolate can invoke Isolate.currentIsolateContext to retrieve the values.
See the currentIsolateContext documentation for details on the
standard and implementation-defined context parameters.

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 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 currentIsolateContext). 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.)

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
preferencejava.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).

The "standard" IO of an isolated computation (i.e., System.in, System.out and System.err) can be redirected by the creator of the isolate
using the long constructor. The three
IsolateMessage parameters represent the standard input,
output and error streams, respectively.

The given IsolateMessage objects must contain valid IO
object references (see IsolateMessage), or an
exception will be thrown. The associated standard
System stream will be initialized in the new isolate
from the stream object. Additionally, copies (as if sent via a
Link) of the messages will be available
via currentIsolateIOBindings in the new isolate.

The following examples illustrate some of the scenarios
supported. Parameters a and t in the
example Isolate constructor calls are simply
placeholders for the String[]mainArgs and
TransientPreferencescontext parameters
respectively.

Inter-Isolate 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
objects convertible to String may be
copied through this interface.

TransientPreferences

The TransientPreferences, or context,
parameter to the long 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 currentIsolateContext
method. See the method documentation 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.

Initial messages can be passed via the start
method and retrieved in the new isolate via the static currentIsolateStartMessages method. The initial messages can be used
for passing one-time messages, or for establishing new communication
channels See IsolateMessage for details.

The initial class

The initial class provided to a new isolate can also be used as
means of supplying information to the new isolate by coding
information into the class. For example, a class that 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.

Isolate

This constructor has the same effect as invoking the
long constructor and passing null for the context
and the first three
IsolateMessages returned from currentIsolateIOBindings (padding with null if less than three
are returned).

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

See the long constructor documentation for more details.

Parameters:

mainClass - fully qualified name of the main method class

mainArgs - the arguments of the main method in the new isolate or null

Creates a new isolated java application with the specified
context and standard i/o bindings.
When started the new isolate will execute the public
main method of public 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, or be present in the aggregate-wide
bootstrap or extension class paths.

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.currentIsolateContext 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 stdin, stdout, or stderr
bindings are null then a null device binding is passed to the created
isolate. A null device returns EOF on reads and ignores writes. If not
null these binding parameters must be IsolateMessage
objects wrapping valid i/o types (see IsolateMessage).
A creating isolate may pass on
its own bindings by, for example, using the appropriate IsolateMessage
returned from currentIsolateIOBindings.

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:

Implementation Notes

An implementation of the Isolate class has
latitude as to when the underlying isolate container is
actually created and initialized.
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 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."

start

Indicate that the isolate this Isolate represents is to
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.

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

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

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

If any given IsolateMessage contains a serializable object, then
start may throw an IsolateStartupException
which will chain
a LinkSerializationException if any
serialization errors occur.

A SecurityException will be thrown if the invoker does
not have permission to send the
given type of IsolateMessage.

An IllegalArgumentException will be thrown if any given
IsolateMessage contains an Isolate that has
not been started.

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

currentIsolateIOBindings

Retrieves a copy of the IsolateMessage array
defining the initial "standard" i/o bindings of the current isolate.
In the typical case the creator isolate defines
bindings for standard input, output and error respectively and this
method will return a array whose elements correspond to
the three standard streams.
The atypical case is for an isolate started
by the implementation (i.e., the first isolate in an aggregate). In
this case, the array contains one element for each of the initial
i/o bindings defined by the environment that started the aggregate.

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 no bindings are defined.

exit

public void exit(int status)

Requests normal termination of the isolate this Isolate represents.
Invocation of this method is
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.

Note that this method is not synchronous with the state change of
the isolate in question. Monitoring of events can be used to confirm
termination or the isolate state can be polled with hasTerminated().

No exception is thrown if this isolate is already
terminated. Even if hasTerminated() 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.

If a security manager is present the user of this method must have the "control"
IsolatePermission and appropriate additional permissions.

halt

public void halt(int status)

Forces termination of the isolate this Isolate represents.
Invocation of this method is
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.

Note that this method is not synchronous with the state change of
the isolate in question. Monitoring of events can be used to confirm
termination or the isolate state can be polled with hasTerminated().

No exception is thrown if this isolate is already
terminated. Even if hasTerminated() 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.

If a security manager is present the user of this method must have the "control"
IsolatePermission and appropriate additional permissions.

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.

currentIsolateContext

Returns the context associated with the current isolate. The
returned context is a deep copy of the context parameter
supplied by the creator when the current isolate was created, or a default context if none was supplied by the
creator. The returned context may have been modified
by the system when it was copied.

This method never returns null.
The first isolate in a new aggregate is provided with a
non-null context which will contain standard default
values, and may contain implementation-specific default values.

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

The name space of the context preferences object is
structured similarly to the Java class name space. The
java. and javax. prefixes are reserved for standard, system-defined
names defined by a Java API; for non-standard names
a reverse-domain-name prefix convention is encouraged
(e.g. "org.apache.neatfeature").

Some preferences are meant to be used by a parent (to specify
a configuration option for a new isolate). Some are meant to be
used by the current isolate (to query its environment or settings
from its parent).

The following context preferences are defined in the
java.* name space by this specification:

True if isolation of JNI code is supported in this isolate, false otherwise.
JNI isolation implies that faults or
errors in user-loaded JNI code will be isolated from other isolate's
JNI code.

Not settable by a parent (will be ignored). Required to be defined in child.

java.lang.isolate.vm-isolatation

Boolean

True if isolation of JVM internal code is supported in this
isolate, false otherwise. VM isolation implies that a fault or
error in the VM may only terminate this isolate (and not the
entire aggregate). Of course, faults in the code that
implements isolation probably cannot be isolated.

Not settable by a parent (will be ignored). Required to be defined in child.

This specifications only covers those parts of the
transient preferences namespace
with a standard prefix. A
reverse-domain-name prefix convention is suggested for vendor
specific preferences (e.g. "edu.utah.cs.janosopts"). The only
exception to this convention is the "options" key shown below,
intended for passing a collection of implementation-defined
options:

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 System Properties for
communicating application state is strongly recommended (unless
per-name access checks are required as only Properties provides
fine-grained access control).

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 (e.g.,
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. While properties are defined
by a parent in the "java.properties/" node of the
context, properties are not accessible in the new isolate via the
context (they must be accessed via existing means).

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 in a context 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:

Key

Description 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

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.

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 standard
preferences as defined above, and
may contain implementation-defined preferences.

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.vendor" and "java.class.path". The property
"java.vendor" 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.currentIsolateContext() in a child isolate reflect the
values provided by the parent. Implementations are free to define
additional
entries in the returned context. For
example, an implementation could report the value of a special feature
containing an isolate in a context entry (e.g.,
"org.javafun.mpisolate.turbomode"). Any value provided
by a parent for these kinds of implementation-defined properties
will be ignored.