diff options
author | Norbert Frese <postfach@nfrese.net> | 2004-03-20 20:30:56 +0000 |
---|---|---|
committer | Michael Koch <mkoch@gcc.gnu.org> | 2004-03-20 20:30:56 +0000 |
commit | f903e73b80ccb078fb4bb8cfb5c4a44ea901a002 (patch) | |
tree | 46489ab9dc40917ff9013121644478cc830a4a4e /libjava/gnu | |
parent | 079f946dad97b3def95bc6010e1a89f2058a69d5 (diff) | |
download | gcc-f903e73b80ccb078fb4bb8cfb5c4a44ea901a002.zip gcc-f903e73b80ccb078fb4bb8cfb5c4a44ea901a002.tar.gz gcc-f903e73b80ccb078fb4bb8cfb5c4a44ea901a002.tar.bz2 |
RMIIncomingThread.java: New file.
2004-03-20 Norbert Frese <postfach@nfrese.net>
* gnu/java/rmi/server/RMIIncomingThread.java: New file.
* gcc/libjava/gnu/java/rmi/server/UnicastConnection.java:
Create a new RMIObjectOuputStream/RMIObjectInputStream for every
rmi-message.
(getObjectInputStream): Return object reference, throw IOException if null.
(startObjectInputStream): Create new RMIObjectInputStream on top of 'din'.
(getObjectOutputStream): Return object reference, throw IOException if null.
(startObjectOutputStream): Create new RMIObjectOutputStream on top of 'dout'.
* gcc/libjava/gnu/java/rmi/server/UnicastConnectionManager.java:
(UnicastConnectionManager): Throw RemoteException if port is not available.
(getInstance): Throw RemoteException.
(run): Lookup client host and attach it to new RMIIncomingThread for later retrieval.
* gcc/libjava/gnu/java/rmi/server/UnicastRef.java:
Start a new RMIObjectInputStream/RMIObjectOutputStream for every rmi-message.
Collect Exceptions which are returned by a rmi-call and fix void returns.
* gcc/libjava/gnu/java/rmi/server/UnicastRemoteCall.java:
Start a new RMIObjectInputStream/RMIObjectOutputStream for every rmi-message.
* gcc/libjava/gnu/java/rmi/server/UnicastServer.java:
(dispatch): Answer ping messages which are sent by other java implementions.
(incomingMessageCall): Start a new RMIObjectInputStream/RMIObjectOutputStream
for every rmi-message and fix void return problems.
* gcc/libjava/gnu/java/rmi/server/UnicastServerRef.java
(UnicastServerRef): Throw RemoteException.
(exportObject): Find the class up the class hierarchy which has a _Stub generated by rmic.
In some situations it is necessary to export a subclass of the class which has the _Stub.
For instance when the class with has the _Stub is abstract.
(findStubSkelClass): New method which looks for the class which has the _Stub.
(getClientHost): Implementated.
* gcc/libjava/java/rmi/server/RemoteServer.java
(getClientHost): Implementated.
* gcc/libjava/Makefile.am (rmi_java_source_files):
Added gnu/java/rmi/server/RMIIncomingThread.java.
* Makefile.in: Regenerated.
From-SVN: r79755
Diffstat (limited to 'libjava/gnu')
-rw-r--r-- | libjava/gnu/java/rmi/server/RMIIncomingThread.java | 58 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastConnection.java | 36 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastConnectionManager.java | 29 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastRef.java | 22 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastRemoteCall.java | 19 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastServer.java | 17 | ||||
-rw-r--r-- | libjava/gnu/java/rmi/server/UnicastServerRef.java | 51 |
7 files changed, 199 insertions, 33 deletions
diff --git a/libjava/gnu/java/rmi/server/RMIIncomingThread.java b/libjava/gnu/java/rmi/server/RMIIncomingThread.java new file mode 100644 index 0000000..2855c03 --- /dev/null +++ b/libjava/gnu/java/rmi/server/RMIIncomingThread.java @@ -0,0 +1,58 @@ +/* + Copyright (c) 1996, 1997, 1998, 1999, 2002 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. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.rmi.server; + +public class RMIIncomingThread extends Thread { + + private String clientHost = null; + + public RMIIncomingThread(Runnable runnable, String s_clientHost) { + super(runnable); + clientHost = s_clientHost; + } + + public String toString() { + return "RMIIncoming from " + clientHost + " " + super.toString(); + } + + public String getClientHost() { + return clientHost; + } + + +} diff --git a/libjava/gnu/java/rmi/server/UnicastConnection.java b/libjava/gnu/java/rmi/server/UnicastConnection.java index 14d28f2..19e074a 100644 --- a/libjava/gnu/java/rmi/server/UnicastConnection.java +++ b/libjava/gnu/java/rmi/server/UnicastConnection.java @@ -104,6 +104,7 @@ void acceptConnection() throws IOException { void makeConnection(int protocol) throws IOException { //Use BufferedXXXStream would be more efficient din = new DataInputStream(new BufferedInputStream(sock.getInputStream())); + dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); // Send header @@ -139,20 +140,48 @@ DataOutputStream getDataOutputStream() throws IOException { return (dout); } +/* +* +* get ObjectInputStream for reading more objects +* +*/ ObjectInputStream getObjectInputStream() throws IOException { if (oin == null) { - oin = new RMIObjectInputStream(din); + throw new IOException("no ObjectInputtream for reading more objects"); } return (oin); } +/** +* +* starts ObjectInputStream. +* +*/ +ObjectInputStream startObjectInputStream() throws IOException { + return (oin = new RMIObjectInputStream(din)); +} + +/** +* +* get ObjectOutputStream for sending more objects +* +*/ ObjectOutputStream getObjectOutputStream() throws IOException { if (oout == null) { - oout = new RMIObjectOutputStream(dout); - } + throw new IOException("no ObjectOutputStream for sending more objects"); + } return (oout); } +/** +* +* starts ObjectOutputStream. +* +*/ +ObjectOutputStream startObjectOutputStream() throws IOException { + return (oout = new RMIObjectOutputStream(dout)); +} + void disconnect() { try { if(oout != null) @@ -200,4 +229,5 @@ public void run() { }while(true); } + } diff --git a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java index 3b9aa40..b7a505d 100644 --- a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java +++ b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java @@ -59,6 +59,7 @@ import java.util.Hashtable; import java.util.Iterator; import gnu.java.rmi.server.UnicastConnection; +import gnu.java.rmi.server.RMIIncomingThread; public class UnicastConnectionManager implements Runnable, ProtocolConstants { @@ -173,20 +174,16 @@ private UnicastConnectionManager(String host, int port, RMIClientSocketFactory c /** * Server UnicastConnectionManager constructor */ -private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) { +private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) throws RemoteException { + try { ssock = ssf.createServerSocket(port); serverPort = ssock.getLocalPort(); } - catch (IOException _) { - try { - ssock = ssf.createServerSocket(0); - serverPort = ssock.getLocalPort(); - } - catch (IOException __) { - ssock = null; - serverPort = 0; - } + catch (IOException ioex) { + ssock = null; + serverPort = 0; + throw new java.rmi.server.ExportException("can not create Server Socket on port " + port,ioex); } serverName = localhost; serverFactory = ssf; @@ -230,7 +227,7 @@ public static synchronized UnicastConnectionManager getInstance(String host, int * Return a server connection manager which will accept connection on the * given port. */ -public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) { +public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) throws RemoteException { //System.out.println("getInstance: " + port + "," + ssf); if (ssf == null) { ssf = defaultSocketFactory; @@ -376,9 +373,17 @@ public void run() { try { //System.out.println("Waiting for connection on " + serverPort); UnicastConnection conn = getServerConnection(); + + // get address of remote host for the RMIIncomingThread object + String remoteHost = null; + if (conn.sock != null) { + remoteHost = conn.sock.getInetAddress().getHostAddress(); + } + // use a thread pool to improve performance //ConnectionRunnerPool.dispatchConnection(conn); - (new Thread(conn)).start(); + (new RMIIncomingThread(conn, remoteHost)).start(); +// (new Thread(conn)).start(); } catch (Exception e) { e.printStackTrace(); diff --git a/libjava/gnu/java/rmi/server/UnicastRef.java b/libjava/gnu/java/rmi/server/UnicastRef.java index aaec7a3..60a745e 100644 --- a/libjava/gnu/java/rmi/server/UnicastRef.java +++ b/libjava/gnu/java/rmi/server/UnicastRef.java @@ -116,7 +116,7 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu dout = conn.getDataOutputStream(); dout.writeByte(MESSAGE_CALL); - out = conn.getObjectOutputStream(); + out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream objid.write(out); out.writeInt(opnum); @@ -146,19 +146,22 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu throw new RemoteException("Call not acked:" + returncode); } - in = conn.getObjectInputStream(); + in = conn.startObjectInputStream(); // (re)start ObjectInputStream returncode = in.readUnsignedByte(); ack = UID.read(in); Class cls = method.getReturnType(); - if(cls == Void.TYPE){ - returnval = null; - in.readObject(); - }else - returnval = ((RMIObjectInputStream)in).readValue(cls); + if (returncode == RETURN_NACK) { + returnval = in.readObject(); // get Exception + + } else if(cls == Void.TYPE) { + returnval = null; + // in.readObject() // not required! returntype 'void' means no field is returned. + } else { + returnval = ((RMIObjectInputStream)in).readValue(cls); // get returnvalue } - catch (IOException e3) { + } catch (IOException e3) { //for debug: e3.printStackTrace(); throw new RemoteException("call return failed: ", e3); } @@ -174,7 +177,8 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu manager.discardConnection(conn); if (returncode != RETURN_ACK && returnval != null) { - throw (Exception)returnval; + if (returncode == RETURN_NACK) throw (Exception)returnval; + else throw new RemoteException("unexpected returncode: " + returncode); } return (returnval); diff --git a/libjava/gnu/java/rmi/server/UnicastRemoteCall.java b/libjava/gnu/java/rmi/server/UnicastRemoteCall.java index 2d7d6d4..76dd8e2 100644 --- a/libjava/gnu/java/rmi/server/UnicastRemoteCall.java +++ b/libjava/gnu/java/rmi/server/UnicastRemoteCall.java @@ -138,6 +138,21 @@ public class UnicastRemoteCall oout.flush(); } + /** + * + * (re)starts ObjectInputStream + * + */ + public ObjectInput startInputStream() throws IOException + { + if (conn != null) { + return (oin = conn.startObjectInputStream()); + } else { + return getInputStream(); // dummy Input Stream + } + + } + public ObjectInput getInputStream() throws IOException { if (conn != null) @@ -177,7 +192,7 @@ public class UnicastRemoteCall DataOutputStream dout = conn.getDataOutputStream(); dout.write(MESSAGE_CALL); - oout = conn.getObjectOutputStream(); + oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream objid.write(oout); oout.writeInt(opnum); oout.writeLong(hash); @@ -194,7 +209,7 @@ public class UnicastRemoteCall if (din.readByte() != MESSAGE_CALL_ACK) throw new RemoteException("Call not acked"); - oin = getInputStream(); + oin = startInputStream(); returncode = oin.readByte(); UID.read(oin); } diff --git a/libjava/gnu/java/rmi/server/UnicastServer.java b/libjava/gnu/java/rmi/server/UnicastServer.java index fb6ec1f..ace43f0 100644 --- a/libjava/gnu/java/rmi/server/UnicastServer.java +++ b/libjava/gnu/java/rmi/server/UnicastServer.java @@ -99,13 +99,19 @@ public static void dispatch(UnicastConnection conn) throws Exception { case MESSAGE_CALL: incomingMessageCall(conn); break; + case MESSAGE_PING: + // jdk sends a ping before each method call -> answer it! + DataOutputStream out = conn.getDataOutputStream(); + out.writeByte(MESSAGE_PING_ACK); + out.flush(); + break; default: throw new Exception("bad method type"); } } private static void incomingMessageCall(UnicastConnection conn) throws IOException { - ObjectInputStream in = conn.getObjectInputStream(); + ObjectInputStream in = conn.startObjectInputStream(); // (re)start ObjectInputStream ObjID objid = ObjID.read(in); int method = in.readInt(); @@ -138,13 +144,18 @@ private static void incomingMessageCall(UnicastConnection conn) throws IOExcepti conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK); - ObjectOutputStream out = conn.getObjectOutputStream(); + ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream out.writeByte(returncode); (new UID()).write(out); + + //System.out.println("returnval=" + returnval + " returncls=" + returncls); + if(returnval != null && returncls != null) ((RMIObjectOutputStream)out).writeValue(returnval, returncls); - else if (!(returnval instanceof RMIVoidValue)) + + // 1.1/1.2 void return type detection: + else if (!(returnval instanceof RMIVoidValue || returncls == Void.TYPE)) out.writeObject(returnval); out.flush(); diff --git a/libjava/gnu/java/rmi/server/UnicastServerRef.java b/libjava/gnu/java/rmi/server/UnicastServerRef.java index b004927..3e9529c 100644 --- a/libjava/gnu/java/rmi/server/UnicastServerRef.java +++ b/libjava/gnu/java/rmi/server/UnicastServerRef.java @@ -46,6 +46,7 @@ import java.rmi.RemoteException; import java.rmi.server.RemoteStub; import java.rmi.server.ObjID; import java.rmi.server.ServerRef; +import java.rmi.server.RemoteServer; import java.rmi.server.RemoteRef; import java.rmi.server.ServerNotActiveException; import java.rmi.server.RMIClientSocketFactory; @@ -85,7 +86,7 @@ UnicastServerRef() { } -public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) { +public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) throws RemoteException { super(id); manager = UnicastConnectionManager.getInstance(port, ssf); } @@ -99,13 +100,21 @@ public RemoteStub exportObject(Remote obj) throws RemoteException { // Find and install the stub Class cls = obj.getClass(); - stub = (RemoteStub)getHelperClass(cls, "_Stub"); + Class expCls; + try { + // where ist the _Stub? (check superclasses also) + expCls = findStubSkelClass(cls); + } catch (Exception ex) { + throw new RemoteException("can not find stubs for class: " + cls, ex); + } + + stub = (RemoteStub)getHelperClass(expCls, "_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"); + skel = (Skeleton)getHelperClass(expCls, "_Skel"); // Build hash of methods which may be called. buildMethodHash(obj.getClass(), true); @@ -135,6 +144,38 @@ public boolean unexportObject(Remote obj, boolean force) { return UnicastServer.unexportObject(this, force); } +/** +* +* The Subs/Skels might not there for the actual class, but maybe +* for one of the superclasses. +* +*/ +private Class findStubSkelClass(Class startCls) throws Exception { + Class cls = startCls; + + while (true) { + try { + String stubClassname = cls.getName() + "_Stub"; + ClassLoader cl = cls.getClassLoader(); + Class scls = cl == null ? Class.forName(stubClassname) + : cl.loadClass(stubClassname); + return cls; // found it + } catch (ClassNotFoundException e) { + Class superCls = cls.getSuperclass(); + if (superCls == null + || superCls == java.rmi.server.UnicastRemoteObject.class) + { + throw new Exception("Neither " + startCls + + " nor one of their superclasses (like" + cls + ")" + + " has a _Stub"); + } + cls = superCls; + } + } +} + + + private Object getHelperClass(Class cls, String type) { try { String classname = cls.getName(); @@ -176,8 +217,10 @@ private Object getHelperClass(Class cls, String type) { return (null); } + + public String getClientHost() throws ServerNotActiveException { - throw new Error("Not implemented"); + return RemoteServer.getClientHost(); } private void buildMethodHash(Class cls, boolean build) { |