summaryrefslogtreecommitdiff
path: root/gnu/java/rmi/server
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2001-08-27 23:52:27 +0000
committerTom Tromey <tromey@redhat.com>2001-08-27 23:52:27 +0000
commit5c1d9325c0779d3ccd2c73af543e78b805b6f81d (patch)
treeba9c6be45ab5b753b12e6b2752111f0ebc1bc05d /gnu/java/rmi/server
parent46d2cdeaeca05d8f71f9d336569be7dafbf9bad7 (diff)
downloadclasspath-5c1d9325c0779d3ccd2c73af543e78b805b6f81d.tar.gz
* 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. * configure.in (AC_OUTPUT): List new Makefiles. * gnu/java/rmi/server/Makefile.am: New file. * gnu/java/rmi/rmic/Makefile.am: New file. * gnu/java/rmi/registry/Makefile.am: New file. * gnu/java/rmi/dgc/Makefile.am: New file. * gnu/java/rmi/Makefile.am: New file. * gnu/java/Makefile.am (SUBDIRS): Added rmi. * java/rmi/server/Makefile.am: New file. * java/rmi/registry/Makefile.am: New file. * java/rmi/dgc/Makefile.am: New file. * java/rmi/activation/Makefile.am: New file. * java/rmi/Makefile.am: New file. * java/Makefile.am (SUBDIRS): Added rmi.
Diffstat (limited to 'gnu/java/rmi/server')
-rw-r--r--gnu/java/rmi/server/Makefile.am14
-rw-r--r--gnu/java/rmi/server/ProtocolConstants.java53
-rw-r--r--gnu/java/rmi/server/RMIDefaultSocketFactory.java49
-rw-r--r--gnu/java/rmi/server/RMIHashes.java45
-rw-r--r--gnu/java/rmi/server/RMIObjectInputStream.java65
-rw-r--r--gnu/java/rmi/server/RMIObjectOutputStream.java47
-rw-r--r--gnu/java/rmi/server/UnicastConnection.java162
-rw-r--r--gnu/java/rmi/server/UnicastConnectionManager.java262
-rw-r--r--gnu/java/rmi/server/UnicastRef.java219
-rw-r--r--gnu/java/rmi/server/UnicastRemoteCall.java301
-rw-r--r--gnu/java/rmi/server/UnicastRemoteStub.java40
-rw-r--r--gnu/java/rmi/server/UnicastServer.java119
-rw-r--r--gnu/java/rmi/server/UnicastServerRef.java198
13 files changed, 1574 insertions, 0 deletions
diff --git a/gnu/java/rmi/server/Makefile.am b/gnu/java/rmi/server/Makefile.am
new file mode 100644
index 000000000..a60bdefc9
--- /dev/null
+++ b/gnu/java/rmi/server/Makefile.am
@@ -0,0 +1,14 @@
+## Input file for automake to generate the Makefile.in used by configure
+
+EXTRA_DIST = ProtocolConstants.java \
+RMIDefaultSocketFactory.java \
+RMIHashes.java \
+RMIObjectInputStream.java \
+RMIObjectOutputStream.java \
+UnicastConnection.java \
+UnicastConnectionManager.java \
+UnicastRef.java \
+UnicastRemoteCall.java \
+UnicastRemoteStub.java \
+UnicastServer.java \
+UnicastServerRef.java
diff --git a/gnu/java/rmi/server/ProtocolConstants.java b/gnu/java/rmi/server/ProtocolConstants.java
new file mode 100644
index 000000000..431a6999a
--- /dev/null
+++ b/gnu/java/rmi/server/ProtocolConstants.java
@@ -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;
+
+};
diff --git a/gnu/java/rmi/server/RMIDefaultSocketFactory.java b/gnu/java/rmi/server/RMIDefaultSocketFactory.java
new file mode 100644
index 000000000..610c3a73b
--- /dev/null
+++ b/gnu/java/rmi/server/RMIDefaultSocketFactory.java
@@ -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));
+}
+
+}
diff --git a/gnu/java/rmi/server/RMIHashes.java b/gnu/java/rmi/server/RMIHashes.java
new file mode 100644
index 000000000..dc00276de
--- /dev/null
+++ b/gnu/java/rmi/server/RMIHashes.java
@@ -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 ();
+ }
+}
diff --git a/gnu/java/rmi/server/RMIObjectInputStream.java b/gnu/java/rmi/server/RMIObjectInputStream.java
new file mode 100644
index 000000000..b6efbf0b8
--- /dev/null
+++ b/gnu/java/rmi/server/RMIObjectInputStream.java
@@ -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());
+ }
+ }
+}
+
+}
diff --git a/gnu/java/rmi/server/RMIObjectOutputStream.java b/gnu/java/rmi/server/RMIObjectOutputStream.java
new file mode 100644
index 000000000..960252b64
--- /dev/null
+++ b/gnu/java/rmi/server/RMIObjectOutputStream.java
@@ -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));
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastConnection.java b/gnu/java/rmi/server/UnicastConnection.java
new file mode 100644
index 000000000..04d18bedc
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastConnection.java
@@ -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();
+ }
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastConnectionManager.java b/gnu/java/rmi/server/UnicastConnectionManager.java
new file mode 100644
index 000000000..84152bd88
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastConnectionManager.java
@@ -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);
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastRef.java b/gnu/java/rmi/server/UnicastRef.java
new file mode 100644
index 000000000..837e6e4e9
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastRef.java
@@ -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 _) {
+ }
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastRemoteCall.java b/gnu/java/rmi/server/UnicastRemoteCall.java
new file mode 100644
index 000000000..42759e70a
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastRemoteCall.java
@@ -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 {
+}
+
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastRemoteStub.java b/gnu/java/rmi/server/UnicastRemoteStub.java
new file mode 100644
index 000000000..244e7a8aa
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastRemoteStub.java
@@ -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);
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastServer.java b/gnu/java/rmi/server/UnicastServer.java
new file mode 100644
index 000000000..d2cc7dc40
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastServer.java
@@ -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();
+}
+
+}
diff --git a/gnu/java/rmi/server/UnicastServerRef.java b/gnu/java/rmi/server/UnicastServerRef.java
new file mode 100644
index 000000000..290ea09e6
--- /dev/null
+++ b/gnu/java/rmi/server/UnicastServerRef.java
@@ -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());
+ }
+}
+
+}