Activatable.java, [...]: RMI implementation from Kaffe.

* java/rmi/activation/Activatable.java,
	java/rmi/activation/ActivateFailedException.java,
	java/rmi/activation/ActivationDesc.java,
	java/rmi/activation/ActivationException.java,
	java/rmi/activation/ActivationGroup.java,
	java/rmi/activation/ActivationGroupDesc.java,
	java/rmi/activation/ActivationGroupID.java,
	java/rmi/activation/ActivationID.java,
	java/rmi/activation/ActivationInstantiator.java,
	java/rmi/activation/ActivationMonitor.java,
	java/rmi/activation/ActivationSystem.java,
	java/rmi/activation/Activator.java,
	java/rmi/activation/UnknownGroupException.java,
	java/rmi/activation/UnknownObjectException.java,
	java/rmi/AccessException.java,
	java/rmi/AlreadyBoundException.java,
	java/rmi/ConnectException.java, java/rmi/ConnectIOException.java,
	java/rmi/MarshalException.java, java/rmi/MarshalledObject.java,
	java/rmi/Naming.java, java/rmi/NoSuchObjectException.java,
	java/rmi/NotBoundException.java,
	java/rmi/RMISecurityException.java,
	java/rmi/RMISecurityManager.java, java/rmi/Remote.java,
	java/rmi/RemoteException.java, java/rmi/ServerError.java,
	java/rmi/ServerException.java,
	java/rmi/ServerRuntimeException.java,
	java/rmi/StubNotFoundException.java,
	java/rmi/UnexpectedException.java,
	java/rmi/UnknownHostException.java,
	java/rmi/UnmarshalException.java, java/rmi/dgc/DGC.java,
	java/rmi/dgc/Lease.java, java/rmi/dgc/VMID.java,
	java/rmi/registry/LocateRegistry.java,
	java/rmi/registry/Registry.java,
	java/rmi/registry/RegistryHandler.java,
	java/rmi/server/ExportException.java,
	java/rmi/server/LoaderHandler.java,
	java/rmi/server/LogStream.java, java/rmi/server/ObjID.java,
	java/rmi/server/Operation.java,
	java/rmi/server/RMIClassLoader.java,
	java/rmi/server/RMIClientSocketFactory.java,
	java/rmi/server/RMIFailureHandler.java,
	java/rmi/server/RMIServerSocketFactory.java,
	java/rmi/server/RMISocketFactory.java,
	java/rmi/server/RemoteCall.java,
	java/rmi/server/RemoteObject.java, java/rmi/server/RemoteRef.java,
	java/rmi/server/RemoteServer.java,
	java/rmi/server/RemoteStub.java,
	java/rmi/server/ServerCloneException.java,
	java/rmi/server/ServerNotActiveException.java,
	java/rmi/server/ServerRef.java, java/rmi/server/Skeleton.java,
	java/rmi/server/SkeletonMismatchException.java,
	java/rmi/server/SkeletonNotFoundException.java,
	java/rmi/server/SocketSecurityException.java,
	java/rmi/server/UID.java,
	java/rmi/server/UnicastRemoteObject.java,
	java/rmi/server/Unreferenced.java, gnu/java/rmi/dgc/DGCImpl.java,
	gnu/java/rmi/dgc/DGCImpl_Skel.java,
	gnu/java/rmi/dgc/DGCImpl_Stub.java,
	gnu/java/rmi/registry/RegistryImpl.java,
	gnu/java/rmi/registry/RegistryImpl_Skel.java,
	gnu/java/rmi/registry/RegistryImpl_Stub.java,
	gnu/java/rmi/rmic/RMIC.java, gnu/java/rmi/rmic/TabbedWriter.java,
	gnu/java/rmi/server/ProtocolConstants.java,
	gnu/java/rmi/server/RMIDefaultSocketFactory.java,
	gnu/java/rmi/server/RMIHashes.java,
	gnu/java/rmi/server/RMIObjectInputStream.java,
	gnu/java/rmi/server/RMIObjectOutputStream.java,
	gnu/java/rmi/server/UnicastConnection.java,
	gnu/java/rmi/server/UnicastConnectionManager.java,
	gnu/java/rmi/server/UnicastRef.java,
	gnu/java/rmi/server/UnicastRemoteCall.java,
	gnu/java/rmi/server/UnicastRemoteStub.java,
	gnu/java/rmi/server/UnicastServer.java,
	gnu/java/rmi/server/UnicastServerRef.java: RMI implementation from
	Kaffe.  Relabelled classes to fit into Classpath tree.
	* Makefile.in: Rebuilt.
	* Makefile.am (rmi_java_source_files): New macro.
	(ordinary_java_source_files): Reference it.
	(bin_PROGRAMS): Added rmic and rmiregistry.
	(rmic_SOURCES): New macro.
	(EXTRA_rmic_SOURCES): Likewise.
	(rmic_LDFLAGS): Likewise.
	(rmic_LINK): Likewise.
	(rmic_LDADD): Likewise.
	(rmic_DEPENDENCIES): Likewise.
	(rmiregistry_SOURCES): New macro.
	(EXTRA_rmiregistry_SOURCES): Likewise.
	(rmiregistry_LDFLAGS): Likewise.
	(rmiregistry_LINK): Likewise.
	(rmiregistry_LDADD): Likewise.
	(rmiregistry_DEPENDENCIES): Likewise.

From-SVN: r45218
This commit is contained in:
Tom Tromey
2001-08-28 00:03:35 +00:00
committed by Tom Tromey
parent c5bb59c118
commit 83e7315b5f
88 changed files with 8583 additions and 49 deletions
@@ -0,0 +1,53 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
public interface ProtocolConstants {
final public static int PROTOCOL_HEADER = 0x4a524d49; // JRMI
final public static int PROTOCOL_VERSION = 2;
final public static int STREAM_PROTOCOL = 0x4b;
final public static int SINGLE_OP_PROTOCOL = 0x4c;
final public static int MULTIPLEX_PROTOCOL = 0x4d;
final public static int PROTOCOL_ACK = 0x4e;
final public static int PROTOCOL_NACK = 0x4f;
final public static int MESSAGE_CALL = 0x50;
final public static int MESSAGE_CALL_ACK = 0x51;
final public static int MESSAGE_PING = 0x52;
final public static int MESSAGE_PING_ACK = 0x53;
final public static int MESSAGE_DGCACK = 0x54;
final public static int RETURN_ACK = 0x01;
final public static int RETURN_NACK = 0x02;
final public static int DEFAULT_PROTOCOL = STREAM_PROTOCOL;
};
@@ -0,0 +1,49 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.rmi.server.RMISocketFactory;
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
public class RMIDefaultSocketFactory
extends RMISocketFactory {
public RMIDefaultSocketFactory() {
}
public Socket createSocket(String host, int port) throws IOException {
return (new Socket(host, port));
}
public ServerSocket createServerSocket(int port) throws IOException {
return (new ServerSocket(port));
}
}
@@ -0,0 +1,45 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.lang.reflect.Method;
import java.lang.Class;
import gnu.java.security.provider.SHA;
public class RMIHashes
{
public static long getMethodHash(Method meth)
{
return meth.hashCode ();
}
public static long getInterfaceHash(Class clazz)
{
return clazz.hashCode ();
}
}
@@ -0,0 +1,65 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.io.ObjectStreamClass;
import java.io.ObjectInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.rmi.server.RMIClassLoader;
public class RMIObjectInputStream
extends ObjectInputStream {
UnicastConnectionManager manager;
public RMIObjectInputStream(InputStream strm, UnicastConnectionManager man) throws IOException {
super(strm);
manager = man;
enableResolveObject(true);
}
protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
//System.out.println("Resolving class: " + desc.getName());
String annotation = (String)readObject();
if (annotation == null) {
return (super.resolveClass(desc));
}
else {
try {
return (RMIClassLoader.loadClass(new URL(annotation), desc.getName()));
}
catch (MalformedURLException _) {
throw new ClassNotFoundException(desc.getName());
}
}
}
}
@@ -0,0 +1,47 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.rmi.server.RMIClassLoader;
public class RMIObjectOutputStream
extends ObjectOutputStream {
public RMIObjectOutputStream(OutputStream strm) throws IOException {
super(strm);
}
protected void annotateClass(Class cls) throws IOException {
//System.out.println("Annotating class: " + cls);
writeObject(RMIClassLoader.getClassAnnotation(cls));
}
}
@@ -0,0 +1,162 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.lang.Runnable;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
import java.rmi.RemoteException;
public class UnicastConnection
implements Runnable, ProtocolConstants {
UnicastConnectionManager manager;
Socket sock;
DataInputStream din;
DataOutputStream dout;
ObjectInputStream oin;
ObjectOutputStream oout;
UnicastConnection(UnicastConnectionManager man, Socket sock) {
this.manager = man;
this.sock = sock;
}
void acceptConnection() throws IOException {
//System.out.println("Accepting connection on " + lport);
din = new DataInputStream(sock.getInputStream());
dout = new DataOutputStream(sock.getOutputStream());
int sig = din.readInt();
if (sig != PROTOCOL_HEADER) {
throw new IOException("bad protocol header");
}
short ver = din.readShort();
if (ver != PROTOCOL_VERSION) {
throw new IOException("bad protocol version");
}
int protocol = din.readUnsignedByte();
if (protocol != SINGLE_OP_PROTOCOL) {
// Send an ACK
dout.writeByte(PROTOCOL_ACK);
// Send my hostname and port
dout.writeUTF(manager.serverName);
dout.writeInt(manager.serverPort);
// Read their hostname and port
String rhost = din.readUTF();
int rport = din.readInt();
}
// Okay, ready to roll ...
}
void makeConnection(int protocol) throws IOException {
dout = new DataOutputStream(sock.getOutputStream());
din = new DataInputStream(sock.getInputStream());
// Send header
dout.writeInt(PROTOCOL_HEADER);
dout.writeShort(PROTOCOL_VERSION);
dout.writeByte(protocol);
dout.flush();
if (protocol != SINGLE_OP_PROTOCOL) {
// Get back ack.
int ack = din.readUnsignedByte();
if (ack != PROTOCOL_ACK) {
throw new RemoteException("Unsupported protocol");
}
// Read in host and port
String dicard_rhost = din.readUTF();
int discard_rport = din.readInt();
// Send them my endpoint
dout.writeUTF(manager.serverName);
dout.writeInt(manager.serverPort);
}
// Okay, ready to roll ...
}
DataInputStream getDataInputStream() throws IOException {
return (din);
}
DataOutputStream getDataOutputStream() throws IOException {
return (dout);
}
ObjectInputStream getObjectInputStream() throws IOException {
if (oin == null) {
oin = new RMIObjectInputStream(din, manager);
}
return (oin);
}
ObjectOutputStream getObjectOutputStream() throws IOException {
if (oout == null) {
oout = new RMIObjectOutputStream(dout);
}
return (oout);
}
void disconnect() {
oin = null;
oout = null;
try {
sock.close();
}
catch (IOException _) {
}
din = null;
dout = null;
sock = null;
}
/**
* We run connects on the server. Dispatch it then discard it.
*/
public void run() {
try {
UnicastServer.dispatch(this);
manager.discardConnection(this);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,262 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.RemoteException;
import gnu.java.rmi.server.UnicastConnection;
import java.util.Hashtable;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.lang.Thread;
import java.lang.Runnable;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class UnicastConnectionManager
implements Runnable, ProtocolConstants {
private static String localhost;
private static Hashtable servers = new Hashtable();
private Thread serverThread;
private ServerSocket ssock;
String serverName;
int serverPort;
private RMIServerSocketFactory serverFactory;
private RMIClientSocketFactory clientFactory;
static {
try {
localhost = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException _) {
localhost = "localhost";
}
}
private UnicastConnectionManager(String host, int port, RMIClientSocketFactory csf) {
ssock = null;
serverName = host;
serverPort = port;
serverFactory = null;
clientFactory = csf;
}
private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) {
try {
ssock = ssf.createServerSocket(port);
serverPort = ssock.getLocalPort();
}
catch (IOException _) {
try {
ssock = ssf.createServerSocket(0);
serverPort = ssock.getLocalPort();
}
catch (IOException __) {
ssock = null;
serverPort = 0;
}
}
serverName = localhost;
serverFactory = ssf;
clientFactory = null;
}
/**
* Return a client connection manager which will connect to the given
* host/port.
*/
public static synchronized UnicastConnectionManager getInstance(String host, int port, RMIClientSocketFactory csf) {
//System.out.println("getInstance: " + host + "," + port + "," + csf);
if (csf == null) {
csf = RMISocketFactory.getSocketFactory();
}
TripleKey key = new TripleKey(host, port, csf);
UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key);
if (man == null) {
man = new UnicastConnectionManager(host, port, csf);
servers.put(key, man);
}
return (man);
}
/**
* Return a server connection manager which will accept connection on the
* given port.
*/
public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) {
//System.out.println("getInstance: " + port + "," + ssf);
if (ssf == null) {
ssf = RMISocketFactory.getSocketFactory();
}
TripleKey key = new TripleKey(localhost, port, ssf);
UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key);
if (man == null) {
man = new UnicastConnectionManager(port, ssf);
// The provided port might not be the set port.
key.port = man.serverPort;
servers.put(key, man);
}
return (man);
}
/**
* Get a connection from this manager.
*/
public UnicastConnection getConnection() throws IOException {
if (ssock == null) {
return (getClientConnection());
}
else {
return (getServerConnection());
}
}
/**
* Accept a connection to this server.
*/
private UnicastConnection getServerConnection() throws IOException {
Socket sock = ssock.accept();
UnicastConnection conn = new UnicastConnection(this, sock);
conn.acceptConnection();
//System.out.println("Server connection " + conn);
return (conn);
}
/**
* Make a conection from this client to the server.
*/
private UnicastConnection getClientConnection() throws IOException {
Socket sock = clientFactory.createSocket(serverName, serverPort);
UnicastConnection conn = new UnicastConnection(this, sock);
conn.makeConnection(DEFAULT_PROTOCOL);
//System.out.println("Client connection " + conn);
return (conn);
}
/**
* Discard a connection when we're done with it - maybe it can be
* recycled.
*/
public void discardConnection(UnicastConnection conn) {
//System.out.println("Discarding connection " + conn);
conn.disconnect();
}
/**
* Start a server on this manager if it's a server socket and we've not
* already got one running.
*/
public void startServer() {
synchronized(this) {
if (ssock == null || serverThread != null) {
return;
}
serverThread = new Thread(this);
}
serverThread.start();
}
/**
* Server thread for connection manager.
*/
public void run() {
for (;;) {
try {
//System.out.println("Waiting for connection on " + serverPort);
UnicastConnection conn = getServerConnection();
(new Thread(conn)).start();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Serialization routine.
*/
void write(ObjectOutput out) throws IOException {
out.writeUTF(serverName);
out.writeInt(serverPort);
}
/**
* Serialization routine.
*/
static UnicastConnectionManager read(ObjectInput in) throws IOException {
String host = in.readUTF();
int port = in.readInt();
RMIClientSocketFactory csf = ((RMIObjectInputStream)in).manager.clientFactory;
return (getInstance(host, port, csf));
}
}
/**
* This is use as the hashkey for the client/server connections.
*/
class TripleKey {
String host;
int port;
Object other;
TripleKey(String host, int port, Object other) {
this.host = host;
this.port = port;
this.other = other;
}
/**
* Hash code just include the host and other - we ignore the port since
* this has unusual matching behaviour.
*/
public int hashCode() {
return (host.hashCode() ^ other.hashCode());
}
public boolean equals(Object obj) {
if (obj instanceof TripleKey) {
TripleKey other = (TripleKey)obj;
if (this.host.equals(other.host) &&
this.other == other.other &&
(this.port == other.port || this.port == 0 || other.port == 0)) {
return (true);
}
}
return (false);
}
}
+219
View File
@@ -0,0 +1,219 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.RemoteRef;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteCall;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.Operation;
import java.rmi.server.ObjID;
import java.rmi.server.UID;
import java.lang.reflect.Method;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
import java.net.Socket;
import java.net.InetAddress;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
public class UnicastRef
implements RemoteRef, ProtocolConstants {
public ObjID objid;
UnicastConnectionManager manager;
/**
* Used by serialization.
*/
private UnicastRef() {
}
public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) {
this(objid);
manager = UnicastConnectionManager.getInstance(host, port, csf);
}
public UnicastRef(ObjID objid) {
this.objid = objid;
}
public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
return (invokeCommon(obj, method, params, -1, opnum));
}
private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception {
UnicastConnection conn;
try {
conn = manager.getConnection();
}
catch (IOException e1) {
throw new RemoteException("connection failed to host: " + manager.serverName, e1);
}
ObjectOutputStream out;
DataOutputStream dout;
try {
dout = conn.getDataOutputStream();
dout.writeByte(MESSAGE_CALL);
out = conn.getObjectOutputStream();
objid.write(out);
out.writeInt(opnum);
out.writeLong(hash);
if (params != null) {
for (int i = 0; i < params.length; i++) {
if (params[i] instanceof UnicastRemoteObject) {
out.writeObject(UnicastRemoteObject.exportObject((UnicastRemoteObject)params[i]));
}
else {
out.writeObject(params[i]);
}
}
}
out.flush();
}
catch (IOException e2) {
throw new RemoteException("call failed: ", e2);
}
int returncode;
Object returnval;
DataInputStream din;
ObjectInputStream in;
UID ack;
try {
din = conn.getDataInputStream();
if (din.readUnsignedByte() != MESSAGE_CALL_ACK) {
throw new RemoteException("Call not acked");
}
in = conn.getObjectInputStream();
returncode = in.readUnsignedByte();
ack = UID.read(in);
returnval = in.readObject();
}
catch (IOException e3) {
throw new RemoteException("call return failed: ", e3);
}
manager.discardConnection(conn);
if (returncode != RETURN_ACK) {
throw (Exception)returnval;
}
return (returnval);
}
/**
* @deprecated
*/
public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) throws RemoteException {
return (new UnicastRemoteCall(obj, opnum, hash));
}
/**
* @deprecated
*/
public void invoke(RemoteCall call) throws Exception {
UnicastRemoteCall c = (UnicastRemoteCall)call;
Object ret = invokeCommon((Remote)c.getObject(), (Method)null, c.getArguments(), c.getOpnum(), c.getHash());
c.setReturnValue(ret);
}
/**
* @deprecated
*/
public void done(RemoteCall call) throws RemoteException {
/* Does nothing */
}
public void writeExternal(ObjectOutput out) throws IOException {
if (manager == null) {
throw new IOException("no connection");
}
manager.write(out);
objid.write(out);
out.writeByte(RETURN_ACK);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
manager = UnicastConnectionManager.read(in);
objid = ObjID.read(in);
if (in.readByte() != RETURN_ACK) {
throw new IOException("no ack found");
}
}
public boolean remoteEquals(RemoteRef ref) {
throw new Error("Not implemented");
}
public int remoteHashCode() {
throw new Error("Not implemented");
}
public String getRefClass(ObjectOutput out) {
return ("UnicastRef");
}
public String remoteToString() {
throw new Error("Not implemented");
}
public void dump(UnicastConnection conn) {
try {
DataInputStream din = conn.getDataInputStream();
for (;;) {
int b = din.readUnsignedByte();
System.out.print(Integer.toHexString(b));
if (b >= 32 && b < 128) {
System.out.print(": " + (char)b);
}
System.out.println();
}
}
catch (IOException _) {
}
}
}
@@ -0,0 +1,301 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.lang.Exception;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.StreamCorruptedException;
import java.rmi.server.RemoteCall;
import java.util.Vector;
public class UnicastRemoteCall
implements RemoteCall {
private UnicastConnection conn;
private Object result;
private Object object;
private int opnum;
private long hash;
private Vector vec;
private int ptr;
/**
* Incoming call.
*/
UnicastRemoteCall(UnicastConnection conn) {
this.conn = conn;
}
/**
* Outgoing call.
*/
UnicastRemoteCall(Object obj, int opnum, long hash) {
this.object = obj;
this.opnum = opnum;
this.hash = hash;
}
public ObjectOutput getOutputStream() throws IOException {
vec = new Vector();
return (new DummyObjectOutputStream());
}
public void releaseOutputStream() throws IOException {
// Does nothing.
}
public ObjectInput getInputStream() throws IOException {
if (conn != null) {
return (conn.getObjectInputStream());
}
else {
ptr = 0;
return (new DummyObjectInputStream());
}
}
public void releaseInputStream() throws IOException {
// Does nothing.
}
public ObjectOutput getResultStream(boolean success) throws IOException, StreamCorruptedException {
vec = new Vector();
return (new DummyObjectOutputStream());
}
public void executeCall() throws Exception {
throw new Error("Not implemented");
}
public void done() throws IOException {
/* Does nothing */
}
Object returnValue() {
return (vec.elementAt(0));
}
Object[] getArguments() {
return (vec.toArray());
}
Object getObject() {
return (object);
}
int getOpnum() {
return (opnum);
}
long getHash() {
return (hash);
}
void setReturnValue(Object obj) {
vec.removeAllElements();
vec.addElement(obj);
}
/**
* Dummy object output class.
*/
private class DummyObjectOutputStream implements ObjectOutput {
public void writeBoolean(boolean v) throws IOException {
vec.addElement(new Boolean(v));
}
public void writeByte(int v) throws IOException {
vec.addElement(new Byte((byte)v));
}
public void writeChar(int v) throws IOException {
vec.addElement(new Character((char)v));
}
public void writeDouble(double v) throws IOException {
vec.addElement(new Double(v));
}
public void writeFloat(float v) throws IOException {
vec.addElement(new Float(v));
}
public void writeInt(int v) throws IOException {
vec.addElement(new Integer(v));
}
public void writeLong(long v) throws IOException {
vec.addElement(new Long(v));
}
public void writeShort(int v) throws IOException {
vec.addElement(new Short((short)v));
}
public void writeObject(Object obj) throws IOException {
vec.addElement(obj);
}
public void write(byte b[]) throws IOException {
throw new IOException("not required");
}
public void write(byte b[], int off, int len) throws IOException {
throw new IOException("not required");
}
public void write(int b) throws IOException {
throw new IOException("not required");
}
public void writeBytes(String s) throws IOException {
throw new IOException("not required");
}
public void writeChars(String s) throws IOException {
throw new IOException("not required");
}
public void writeUTF(String str) throws IOException {
throw new IOException("not required");
}
public void flush() throws IOException {
}
public void close() throws IOException {
}
}
/**
* Dummy object input class.
*/
private class DummyObjectInputStream implements ObjectInput {
public boolean readBoolean() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Boolean)obj).booleanValue());
}
public byte readByte() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Byte)obj).byteValue());
}
public char readChar() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Character)obj).charValue());
}
public double readDouble() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Double)obj).doubleValue());
}
public float readFloat() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Float)obj).floatValue());
}
public int readInt() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Integer)obj).intValue());
}
public long readLong() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Long)obj).longValue());
}
public short readShort() throws IOException {
Object obj = vec.elementAt(ptr++);
return (((Short)obj).shortValue());
}
public Object readObject() throws IOException {
return (vec.elementAt(ptr++));
}
public int read(byte b[]) throws IOException {
throw new IOException("not required");
}
public int read(byte b[], int off, int len) throws IOException {
throw new IOException("not required");
}
public int read() throws IOException {
throw new IOException("not required");
}
public long skip(long n) throws IOException {
throw new IOException("not required");
}
public int available() throws IOException {
throw new IOException("not required");
}
public void readFully(byte b[]) throws IOException {
throw new IOException("not required");
}
public void readFully(byte b[], int off, int len) throws IOException {
throw new IOException("not required");
}
public String readLine() throws IOException {
throw new IOException("not required");
}
public String readUTF() throws IOException {
throw new IOException("not required");
}
public int readUnsignedByte() throws IOException {
throw new IOException("not required");
}
public int readUnsignedShort() throws IOException {
throw new IOException("not required");
}
public int skipBytes(int n) throws IOException {
throw new IOException("not required");
}
public void close() throws IOException {
}
}
}
@@ -0,0 +1,40 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.rmi.server.RemoteStub;
import java.rmi.server.RemoteRef;
public class UnicastRemoteStub
extends RemoteStub {
public static void setStubRef(RemoteStub stub, RemoteRef ref) {
setRef(stub, ref);
}
}
@@ -0,0 +1,119 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Hashtable;
import java.net.UnknownHostException;
import java.rmi.server.ObjID;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.UID;
import java.rmi.server.RemoteRef;
import java.rmi.RemoteException;
import java.rmi.NoSuchObjectException;
import gnu.java.rmi.dgc.DGCImpl;
public class UnicastServer
implements ProtocolConstants {
static private Hashtable objects = new Hashtable();
static private DGCImpl dgc;
public static void exportObject(UnicastServerRef obj) {
startDGC();
objects.put(obj.objid, obj);
obj.manager.startServer();
}
private static synchronized void startDGC() {
if (dgc == null) {
try {
dgc = new DGCImpl();
((UnicastServerRef)dgc.getRef()).exportObject(dgc);
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
public static void dispatch(UnicastConnection conn) throws Exception {
switch (conn.getDataInputStream().readUnsignedByte()) {
case MESSAGE_CALL:
incomingMessageCall(conn);
break;
default:
throw new Exception("bad method type");
}
}
private static void incomingMessageCall(UnicastConnection conn) throws IOException {
ObjectInputStream in = conn.getObjectInputStream();
ObjID objid = ObjID.read(in);
int method = in.readInt();
long hash = in.readLong();
//System.out.println("ObjID: " + objid + ", method: " + method + ", hash: " + hash);
// Use the objid to locate the relevant UnicastServerRef
UnicastServerRef uref = (UnicastServerRef)objects.get(objid);
Object returnval;
int returncode = RETURN_ACK;
if (uref != null) {
try {
// Dispatch the call to it.
returnval = uref.incomingMessageCall(conn, method, hash);
}
catch (Exception e) {
returnval = e;
returncode = RETURN_NACK;
}
}
else {
returnval = new NoSuchObjectException("");
returncode = RETURN_NACK;
}
conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
ObjectOutputStream out = conn.getObjectOutputStream();
out.writeByte(returncode);
(new UID()).write(out);
out.writeObject(returnval);
out.flush();
}
}
@@ -0,0 +1,198 @@
/*
Copyright (c) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License.
*/
package gnu.java.rmi.server;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.RemoteStub;
import java.rmi.server.ObjID;
import java.rmi.server.ServerRef;
import java.rmi.server.RemoteRef;
import java.rmi.server.ServerNotActiveException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UID;
import java.rmi.server.Skeleton;
import java.rmi.server.RemoteCall;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.Thread;
import java.lang.Exception;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;
public class UnicastServerRef
extends UnicastRef {
final static private Class[] stubprototype = new Class[] { RemoteRef.class };
Remote myself;
private Skeleton skel;
private RemoteStub stub;
private Hashtable methods;
public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) {
super(id);
manager = UnicastConnectionManager.getInstance(port, ssf);
}
public RemoteStub exportObject(Remote obj) throws RemoteException {
if (myself == null) {
myself = obj;
// Find and install the stub
Class cls = obj.getClass();
stub = (RemoteStub)getHelperClass(cls, "_Stub");
if (stub == null) {
throw new RemoteException("failed to export: " + cls);
}
// Find and install the skeleton (if there is one)
skel = (Skeleton)getHelperClass(cls, "_Skel");
// Build hash of methods which may be called.
buildMethodHash(obj.getClass());
// Export it.
UnicastServer.exportObject(this);
}
return (stub);
}
private Object getHelperClass(Class cls, String type) {
try {
String classname = cls.getName();
Class scls = Class.forName(classname + type);
if (type.equals("_Stub")) {
try {
// JDK 1.2 stubs
Constructor con = scls.getConstructor(stubprototype);
return (con.newInstance(new Object[]{this}));
}
catch (NoSuchMethodException e) {
}
catch (InstantiationException e) {
}
catch (IllegalAccessException e) {
}
catch (IllegalArgumentException e) {
}
catch (InvocationTargetException e) {
}
// JDK 1.1 stubs
RemoteStub stub = (RemoteStub)scls.newInstance();
UnicastRemoteStub.setStubRef(stub, this);
return (stub);
}
else {
// JDK 1.1 skel
return (scls.newInstance());
}
}
catch (ClassNotFoundException e) {
}
catch (InstantiationException e) {
}
catch (IllegalAccessException e) {
}
return (null);
}
public String getClientHost() throws ServerNotActiveException {
throw new Error("Not implemented");
}
private void buildMethodHash(Class cls) {
methods = new Hashtable();
Method[] meths = cls.getMethods();
for (int i = 0; i < meths.length; i++) {
/* Don't need to include any java.xxx related stuff */
if (meths[i].getDeclaringClass().getName().startsWith("java.")) {
continue;
}
long hash = RMIHashes.getMethodHash(meths[i]);
methods.put(new Long (hash), meths[i]);
//System.out.println("meth = " + meths[i] + ", hash = " + hash);
}
}
public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throws Exception {
//System.out.println("method = " + method + ", hash = " + hash);
// If method is -1 then this is JDK 1.2 RMI - so use the hash
// to locate the method
if (method == -1) {
Method meth = (Method)methods.get(new Long (hash));
//System.out.println("class = " + myself.getClass() + ", meth = " + meth);
if (meth == null) {
throw new NoSuchMethodException();
}
ObjectInputStream in = conn.getObjectInputStream();
int nrargs = meth.getParameterTypes().length;
Object[] args = new Object[nrargs];
for (int i = 0; i < nrargs; i++) {
/**
* For debugging purposes - we don't handle CodeBases
* quite right so we don't always find the stubs. This
* lets us know that.
*/
try {
args[i] = in.readObject();
}
catch (Exception t) {
t.printStackTrace();
throw t;
}
}
return (meth.invoke(myself, args));
}
// Otherwise this is JDK 1.1 style RMI - we find the skeleton
// and invoke it using the method number. We wrap up our
// connection system in a UnicastRemoteCall so it appears in a
// way the Skeleton can handle.
else {
if (skel == null) {
throw new NoSuchMethodException();
}
UnicastRemoteCall call = new UnicastRemoteCall(conn);
skel.dispatch(myself, call, method, hash);
return (call.returnValue());
}
}
}