[Isolate-interest] Strawman 7 notes
Pete Soper
Pete@Soper.US
Tue, 22 Jun 2004 22:59:38 -0400
I neglected to include these notes (mostlly written by Richard
Holdsworth) to go along with the "still mostly empty" javadoc. Here they
are:
-----------------------------
//
// JSR-121 "Strawman 7" proposed APIs for J2ME/CLDC J2ME/CDC and J2SE
//
// September 11, 2003
//
/**
CORE API:
---------
*/
package javax.isolate;
interface Message { }
public final class Isolate implements Message {
public Isolate(String mainClass, String[] mainArgs) {}
public Isolate(IsolateParameters params) {}
public static Isolate currentIsolate() {}
public static Link[] currentIsolateStartLinks() {}
public static IsolateParameters currentIsolateParameters() {}
public Link newStatusLink() {}
public void start(Link[] links) throws IsolateStartException {}
public void exit(int status) {}
public void halt(int status) {}
public StatusMessage.Type getStatus() {}
public boolean equals(Object o) {}
public int hashCode() {}
}
public class CompositeMessage implements Message {
CompositeMessage() {}
public Message[] getComposite(Message[] msgs) {}
public static CompositeMessage newCompositeMessage(Message[] msgs) {}
}
public class DataMessage implements Message {
DataMessage() {}
public long size() {}
public byte[] getData(byte[] b) {}
public void getData(int src_position, byte[] dst, int
dst_position, int length) {}
public static DataMessage newDataMessage(byte[] b) {} // convenience
public static DataMessage newDataMessage(byte[] b, int off, int
len) {}
}
public class StatusMessage implements Message {
StatusMessage() {}
public final class ExitReason {
private ExitReason() {}
public final ExitReason IMPLICIT_EXIT = new ExitReason();
public final ExitReason OTHER_EXIT = new ExitReason();
public final ExitReason OTHER_HALT = new ExitReason();
public final ExitReason SELF_EXIT = new ExitReason();
public final ExitReason SELF_HALT = new ExitReason();
public final ExitReason UNCAUGHT_EXCEPTION = new ExitReason();
}
public final class Type {
private Type() {}
public final Type STARTING = new Type();
public final Type EXITING = new Type();
public final Type TERMINATED = new Type();
}
public ExitReason getExitReason() {}
public Type getType() {}
public int getExitStatus() {}
public Isolate getIsolate() {}
public boolean equals(Object o) {}
public int hashCode() {}
}
public abstract class Link implements Message {
Link() {}
public static Link newLink(Isolate sender, Isolate receiver) {}
public abstract Message receive() throws IOException;
public abstract void send(Message msg) throws IOException;
public abstract void close() throws IOException;
public abstract boolean isOpen();
public abstract boolean isSender(Isolate i);
public abstract boolean isReceiver(Isolate i);
public boolean equals(Object o) {}
public int hashCode() {}
}
public class IsolateParameters implements Message {
public IsolateParameters(String classname, String[] mainArgs) {}
public void setContext(String name, String value) {}
public String getContext(String name) {}
}
public class IsolateStartException extends Exception {
public IsolateStartException() {}
public IsolateStartException(String detail) {}
}
/**
CDC ADDITIONAL API:
-------------------
*/
package javax.isolate.tbd;
import java.security.BasicPermission;
public class IsolatePermission extends BasicPermission {
public IsolatePermission(String name) {}
public IsolatePermission(String name, String actions) {}
}
public class ObjectMessage implements Message {
ObjectMessage() {}
public Object getObject() {}
public static ObjectMessage newObjectMessage(Object o) {}
}
/**
SE ADDITIONAL API:
------------------
*/
package javax.isolate.io
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.DatagramSocket;
import javax.isolate.Link;
import javax.isolate.Message;
import javax.isolate.DataMessage;
public interface IOMessage extends Message { }
public class FileMessage implements IOMessage {
FileMessage() {}
public FileInputStream getFileInputStream() {}
public FileOutputStream getFileOutputStream() {}
public RandomAccessFile getRandomAccessFile() {}
public static FileMessage
newFileInputStreamMessage(FileInputStream f) {}
public static FileMessage
newFileOutputStreamMessage(FileOutputStream f) {}
public static FileMessage
newRandomAccessFileMessage(RandomAccessFile f) {}
}
public class SocketMessage implements IOMessage {
SocketMessage() {}
public Socket getSocket() {}
public DatagramSocket getDatagramSocket() {}
public ServerSocket getServerSocket() {}
public static SocketMessage newSocketMessage(Socket s) {}
public static SocketMessage
newDatagramSocketMessage(DatagramSocket s) {}
public static SocketMessage newServerSocketMessage(ServerSocket s) {}
}
public class DataMessageOutputStream extends OutputStream {
public DataMessageOutputStream() {}
public DataMessageOutputStream(int size) {}
public DataMessageOutputStream(Link l) throws IOException {}
// OutputStream
public void close() throws IOException {}
public void flush() throws IOException {}
public void write(byte[] b) throws IOException {}
public void write(byte[] b, int off, int len) throws IOException {}
public void write(int b) throws IOException {}
// conversion
public DataMessage readDataMessage() throws IOException {}
}
public class DataMessageInputStream extends InputStream {
public DataMessageInputStream() {}
public DataMessageInputStream(DataMessage m) {}
public DataMessageInputStream(Link l) throws IOException {}
// InputStream
public int available() throws IOException {}
public void close() throws IOException {}
public void mark(int readlimit) {}
public boolean markSupported() {}
public int read() throws IOException {}
public int read(byte[] b) throws IOException {}
public int read (byte[] b, int off, int len) throws IOException {}
public void reset() throws IOException {}
public long skip(long n) throws IOException {}
// conversion
public void writeDataMessage(DataMessage m) throws IOException {}
}
public class IOIsolateParameters extends IsolateParameters {
public IOIsolateParameters(String mainClass, String[] mainArgs)
{super(null,null);}
public void setIn(IOMessage in) {}
public void setOut(IOMessage out) {}
public void setErr(IOMessage err) {}
public void setName(String name) {}
public IOMessage getIn() {}
public IOMessage getOut() {}
public IOMessage getErr() {}
public String getName() {}
}
public class LinkClosedException extends IOException {
public LinkClosedException() {}
public LinkClosedException(String detail) {}
}
/**
SE additional API: java.
------------------
*/
package javax.isolate.nio;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.DatagramChannel;
import java.nio.channels.FileChannel;
import java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.Pipe.SourceChannel;
public class ByteBufferMessage implements Message {
ByteBufferMessage() {}
public ByteBuffer getByteBuffer() {}
public ByteBufferMessage newByteBufferMessage(ByteBuffer b) {}
}
public class ChannelMessage implements IOMessage {
ChannelMessage() {}
public SocketChannel getSocketChannel() {}
public DatagramChannel getDatagramChannel() {}
public ServerSocketChannel getServerSocketChannel() {}
public FileChannel getFileChannel() {}
public Pipe.SinkChannel getPipeSinkChannel() {}
public Pipe.SourceChannel getPipeSourceChannel() {}
public static ChannelMessage newSocketChannelMessage(SocketChannel
c) {}
public static ChannelMessage
newDatagramChannelMessage(DatagramChannel c) {}
public static ChannelMessage
newServerSocketChannelMessage(ServerSocketChannel c) {}
public static ChannelMessage newFileChannelMessage(FileChannel c) {}
public static ChannelMessage
newPipeSinkChannelMessage(Pipe.SinkChannel c) {}
public static ChannelMessage
newPipeSourceChannelMessage(Pipe.SourceChannel c) {}
}
/**
SE additional API: javax.isolate.util
------------------
*/
package javax.isolate.util;
import javax.isolate.Link;
import javax.isolate.Message;
import javax.isolate.CompositeMessage;
import javax.isolate.DataMessage;
import javax.isolate.Isolate;
import javax.isolate.StatusMessage;
import javax.isolate.io.FileMessage;
import javax.isolate.io.ObjectMessage;
import javax.isolate.io.SocketMessage;
import javax.isolate.nio.ByteBufferMessage;
import javax.isolate.nio.ChannelMessage;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.DatagramChannel;
import java.nio.channels.FileChannel;
import java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.Pipe.SourceChannel;
public interface MessageHandler {
public void messageReceived(MessageDispatcher d, Link l, Message m);
public void receiveFailed(MessageDispatcher d, Link l, Throwable t);
}
public class MessageDispatcher implements Runnable {
public MessageDispatcher() {}
public void add(Link l, MessageHandler h) {}
public void remove(Link l) {}
public void run() {}
public void shutdown() {}
}
public abstract class MessageVisitor {
public MessageVisitor() {}
public void acceptMessage(Message m) throws IOException {}
// core message types
public void visitIsolate(Isolate i) {}
public void visitLink(Link l) {}
public void visitComposite(CompositeMessage m) {}
public void visitData(DataMessage m) {}
public void visitStatus(StatusMessage m) {}
// serial message types
public void visitObject(ObjectMessage m) {}
// nio bytebuffers
public void visitByteBuffer(ByteBufferMessage m) {}
// desc message types
public void visitSocketChannel(ChannelMessage m) {}
public void visitDatagramChannel(ChannelMessage m) {}
public void visitServerSocketChannel(ChannelMessage m) {}
public void visitFileChannel(ChannelMessage m) {}
public void visitPipeSinkChannel(ChannelMessage m) {}
public void visitPipeSourceChannel(ChannelMessage m) {}
public void visitSocket(SocketMessage m) {}
public void visitDatagramSocket(SocketMessage m) {}
public void visitServerSocket(SocketMessage m) {}
public void visitFileInputStream(FileMessage m) {}
public void visitFileOutputStream(FileMessage m) {}
public void visitRandomAccessFile(FileMessage m) {}
}
/**********
Notes
-----
- The marker interface for link-sendables is called Message. Other possible
names for the interface: LinkTransmittable, Sendable,
IsolateTransferrable,
LinkSendable, LinkMessage.
- Few classes are final. Package constructors are used to prevent user
extension. This is less limiting on future expansion, and allows for a
hierarchy of Message types (e.g. IOMessage).
- Renamed IsolateEvent to StatusMessage to fit with the Message
terminology and
to avoid the 'Event types should extend EventObject' complaint.
- The DataMessage includes size(), getData(byte[]...) a
create-from-subarray
method. These allow copying to and from user-provided buffers so new
arrays
do not have to be created by the API or the user.
- ClosedLinkException is moved to 'io' and only IOException is thrown by
the
Link methods. For CLDC just the basic IOException class is thrown,
for the
other platforms the subclass is actually thrown.
- IsolateResourceError is removed. OutOfMemoryError can be thrown
instead. If
reinstated, it should probably extend VirtualMachineError and live in
the
util package.
- SerializableMessage renamed to ObjectMessage and placed in the io
package.
This class is used for potentially optimised object transfer.
- MessageConverters changed to extend InputStream and OutputStream (and
renamed
as such) and have new constructors that take Link. This fully links
DataMessages in with the IO API by hiding Link.send() and
Link.receive().
Manual driving from DataMessages is still supported, but only with
no-parameter constructors. Need to consider how stream is segmented
into
DataMessages, just on flush() or should there be a maximum transfer size?
- {Data|Object}{In|Out}put interfaces removed from Converter/Stream
classes, so
there is no exposure of standard to-serialized-form operations in
this API.
- Have put ByteBuffer into a separate class.
- IOMessage is an extension interface of IOMessage that marks a DBD type
("Descriptor Bearing Doober", a link message "wrapping" a filesystem or
network class instance that typically contains an underlying OS
descriptor of some sort).
- Reasonable type-safety is imposed on the IOBindings by using the
IOMessage
interface - it now only implements the DBD types (is ByteBuffer
FD-backed?).
- The basic IOMessage type is moved into the io package, along with
FileMessage
and SocketMessage, which means CDC system need to support DBD-passing
for
file and socket FDs.
- LinkSerializationException is removed - java.io.NotSerializableException
(which is an IOException) can be thrown instead.
- IsolatePermission is in security subpackage as it doesn't fit in 'io'.
Move
back if 'serial' is reinstated.
- Renamed Visitor, Dispatcher and Dispatcher.Listener based on 'Message'
rather
than 'IsolateMessage'.
- MessageListener is renamed MessageHandler as it does not follow the
EventListener pattern, so a different name is suitable. Not an inner
interface as previously as there seems no advantage to that, and it
is an
unfamiliar pattern.
- The acceptVisitor() method is moved to the Visitor class itself, as any
Message type could be visited. This means the Visitor implementation
must
have some internal magic to identify Message type. It throws
IOException to
cover serialization exceptions.
- The visitXXX() methods do type conversions to the correct Message type.
- Removed TransientPreferences and String[][] context types in favour of an
extendable IsolateParameters object. Alternative considered was a simple
Hashtable.
- IsolateParameters has Message interface so it can be transferred between
Isolates on CLDC.
- IOBoundIsolate removed and an extended IOIsolateParameters object used.
- The IOBoundIsolateParameters class is now in isolate.io, so only NIO
APIs are
left in isolate.nio.
- Isolate made final - this should prevent a lot of API abuses.
- Changed DataMessage.getData and CopositeMessage getComposite to take an
optional array parameter to be filled if possible. See
Vector.toArray(Object[]);
- Looked at DataMessage again - using System.arraycopy()-lookalike for
reading.
Reduces method count slightly.
- Flagged a small number of methods in core API as 'convenience' which
can be
removed without loss of functionality.
- Sep 10 EG meeting resulted in 1) sticking with Message interface, 2)
collapsing Isolate state query methods into one "getStatus" method and 3)
grouping ObjectMessage with IsolatePermission in javax.isolate.tbd
(formerly
called javax.isolate.security).
- The Isolate.getStatus method CANNOT take advantage of enumeration
support in
J2SE 1.5 as this package is intended to serve J2ME users too.
*********/