diff options
author | Tom Tromey <tromey@redhat.com> | 2001-08-27 23:52:27 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2001-08-27 23:52:27 +0000 |
commit | 5c1d9325c0779d3ccd2c73af543e78b805b6f81d (patch) | |
tree | ba9c6be45ab5b753b12e6b2752111f0ebc1bc05d /gnu/java/rmi/server | |
parent | 46d2cdeaeca05d8f71f9d336569be7dafbf9bad7 (diff) | |
download | classpath-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.am | 14 | ||||
-rw-r--r-- | gnu/java/rmi/server/ProtocolConstants.java | 53 | ||||
-rw-r--r-- | gnu/java/rmi/server/RMIDefaultSocketFactory.java | 49 | ||||
-rw-r--r-- | gnu/java/rmi/server/RMIHashes.java | 45 | ||||
-rw-r--r-- | gnu/java/rmi/server/RMIObjectInputStream.java | 65 | ||||
-rw-r--r-- | gnu/java/rmi/server/RMIObjectOutputStream.java | 47 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastConnection.java | 162 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastConnectionManager.java | 262 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastRef.java | 219 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastRemoteCall.java | 301 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastRemoteStub.java | 40 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastServer.java | 119 | ||||
-rw-r--r-- | gnu/java/rmi/server/UnicastServerRef.java | 198 |
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()); + } +} + +} |