[kaffe] CVS kaffe (dalibor): Fixes for RMI
Kaffe CVS
cvs-commits at kaffe.org
Wed Mar 10 09:37:03 PST 2004
PatchSet 4501
Date: 2004/03/10 17:24:44
Author: dalibor
Branch: HEAD
Tag: (none)
Log:
Fixes for RMI
2004-03-10 Norbert Frese <postfach at nfrese.net>
* libraries/javalib/gnu/java/rmi/server/UnicastConnection.java
Create a new RMIObjectOuputStream/RMIObjectInputStream for every
rmi-message:
getObjectInputStream() : Return object reference (IOException if null)
startObjectInputStream() : Create new RMIObjectInputStream on top of
'din'.
getObjectOutputStream() : Return object reference (IOException if null)
startObjectOutputStream() : Create new RMIObjectOutputStream on top of
'dout'.
* libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java
private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) :
Throw RemoteException if port is not available. Before, libjava was
choosing a different port without warning.
getInstance(int port, RMIServerSocketFactory ssf) : Has to throw
RemoteException.
run(): When accepting connections: Lookup client host and attach it to
new RMIIncomingThread for later retrieval. The hostaddress will be
displayed in Thread.toString().
* libraries/javalib/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.
* libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java
Start a new RMIObjectInputStream/RMIObjectOutputStream for every
rmi-message.
* libraries/javalib/gnu/java/rmi/server/UnicastServer.java
dispatch(UnicastConnection conn): Answer ping messages which are sent by
other java implementions. Before, other javas had to create a new
TCP-Connection for every method call, because recieving a 'ping' caused
libjava to cancel the connection.
incomingMessageCall(UnicastConnection conn): Start a new
RMIObjectInputStream/RMIObjectOutputStream for every rmi-message and fix
void return problems.
* libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java
UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) : Has
to throw RemoteException. exportObject(Remote obj): 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(Class startCls): New method which looks for the class
which has the _Stub.
getClientHost(): Add implementation.
* libraries/javalib/java/rmi/server/RemoteServer.java
getClientHost(): Add implementation: Retrieves the hostaddress from
RMIIncomingThread.
* gnu/java/rmi/server/RMIIncomingThread.java:
New file
Members:
ChangeLog:1.2081->1.2082
libraries/javalib/gnu/java/rmi/server/UnicastConnection.java:1.1->1.2
libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java:1.2->1.3
libraries/javalib/gnu/java/rmi/server/UnicastRef.java:1.1->1.2
libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java:1.3->1.4
libraries/javalib/gnu/java/rmi/server/UnicastServer.java:1.2->1.3
libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java:1.3->1.4
libraries/javalib/java/rmi/server/RemoteServer.java:1.2->1.3
libraries/javalib/profiles/allatonce/all.files:1.37->1.38
libraries/javalib/profiles/default/rmi.files:1.5->1.6
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2081 kaffe/ChangeLog:1.2082
--- kaffe/ChangeLog:1.2081 Wed Mar 10 16:42:12 2004
+++ kaffe/ChangeLog Wed Mar 10 17:24:44 2004
@@ -1,3 +1,86 @@
+2004-03-10 Norbert Frese <postfach at nfrese.net>
+
+ * libraries/javalib/gnu/java/rmi/server/UnicastConnection.java
+
+ Create a new RMIObjectOuputStream/RMIObjectInputStream for every
+ rmi-message:
+
+ getObjectInputStream() : Return object reference (IOException if null)
+
+ startObjectInputStream() : Create new RMIObjectInputStream on top of
+ 'din'.
+
+ getObjectOutputStream() : Return object reference (IOException if null)
+
+ startObjectOutputStream() : Create new RMIObjectOutputStream on top of
+ 'dout'.
+
+
+ * libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java
+
+ private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) :
+ Throw RemoteException if port is not available. Before, libjava was
+ choosing a different port without warning.
+
+ getInstance(int port, RMIServerSocketFactory ssf) : Has to throw
+ RemoteException.
+
+ run(): When accepting connections: Lookup client host and attach it to
+ new RMIIncomingThread for later retrieval. The hostaddress will be
+ displayed in Thread.toString().
+
+
+ * libraries/javalib/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.
+
+
+ * libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java
+
+ Start a new RMIObjectInputStream/RMIObjectOutputStream for every
+ rmi-message.
+
+
+ * libraries/javalib/gnu/java/rmi/server/UnicastServer.java
+
+ dispatch(UnicastConnection conn): Answer ping messages which are sent by
+ other java implementions. Before, other javas had to create a new
+ TCP-Connection for every method call, because recieving a 'ping' caused
+ libjava to cancel the connection.
+
+ incomingMessageCall(UnicastConnection conn): Start a new
+ RMIObjectInputStream/RMIObjectOutputStream for every rmi-message and fix
+ void return problems.
+
+
+ * libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java
+
+ UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) : Has
+ to throw RemoteException.
+
+ exportObject(Remote obj): 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(Class startCls): New method which looks for the class
+ which has the _Stub.
+
+ getClientHost(): Add implementation.
+
+
+ * libraries/javalib/java/rmi/server/RemoteServer.java
+
+ getClientHost(): Add implementation: Retrieves the hostaddress from
+ RMIIncomingThread.
+
+ * gnu/java/rmi/server/RMIIncomingThread.java:
+ New file
+
2004-03-10 Dalibor Topic <robilad at kaffe.org>
Resynced with GNU Classpath
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnection.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnection.java:1.1 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnection.java:1.2
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnection.java:1.1 Mon Aug 18 17:40:33 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnection.java Wed Mar 10 17:24:45 2004
@@ -104,6 +104,7 @@
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 @@
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)
@@ -199,5 +228,6 @@
}
}while(true);
}
+
}
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java:1.2 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java:1.3
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java:1.2 Wed Aug 20 13:08:38 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastConnectionManager.java Wed Mar 10 17:24:45 2004
@@ -59,6 +59,7 @@
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 @@
/**
* 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 @@
* 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 @@
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();
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRef.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRef.java:1.1 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRef.java:1.2
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRef.java:1.1 Mon Aug 18 17:40:33 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRef.java Wed Mar 10 17:24:45 2004
@@ -116,7 +116,7 @@
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 @@
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 @@
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);
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java:1.3 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java:1.4
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java:1.3 Sat Dec 27 21:15:57 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastRemoteCall.java Wed Mar 10 17:24:45 2004
@@ -138,6 +138,21 @@
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 @@
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 @@
if (din.readByte() != MESSAGE_CALL_ACK)
throw new RemoteException("Call not acked");
- oin = getInputStream();
+ oin = startInputStream();
returncode = oin.readByte();
UID.read(oin);
}
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServer.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServer.java:1.2 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServer.java:1.3
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServer.java:1.2 Thu Aug 21 12:48:47 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServer.java Wed Mar 10 17:24:45 2004
@@ -99,13 +99,19 @@
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 @@
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();
Index: kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java
diff -u kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java:1.3 kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java:1.4
--- kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java:1.3 Sat Dec 27 21:15:57 2003
+++ kaffe/libraries/javalib/gnu/java/rmi/server/UnicastServerRef.java Wed Mar 10 17:24:45 2004
@@ -46,6 +46,7 @@
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 @@
{
}
-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 @@
// 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 @@
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 @@
return (null);
}
+
+
public String getClientHost() throws ServerNotActiveException {
- throw new Error("Not implemented");
+ return RemoteServer.getClientHost();
}
private void buildMethodHash(Class cls, boolean build) {
Index: kaffe/libraries/javalib/java/rmi/server/RemoteServer.java
diff -u kaffe/libraries/javalib/java/rmi/server/RemoteServer.java:1.2 kaffe/libraries/javalib/java/rmi/server/RemoteServer.java:1.3
--- kaffe/libraries/javalib/java/rmi/server/RemoteServer.java:1.2 Mon Aug 18 17:40:36 2003
+++ kaffe/libraries/javalib/java/rmi/server/RemoteServer.java Wed Mar 10 17:24:45 2004
@@ -39,6 +39,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
+import gnu.java.rmi.server.RMIIncomingThread;
public abstract class RemoteServer
extends RemoteObject {
@@ -54,7 +55,14 @@
}
public static String getClientHost() throws ServerNotActiveException {
- throw new Error("Not implemented");
+ Thread currThread = Thread.currentThread();
+ if (currThread instanceof RMIIncomingThread) {
+ RMIIncomingThread incomingThread = (RMIIncomingThread) currThread;
+ return incomingThread.getClientHost();
+ } else {
+ throw new ServerNotActiveException(
+ "Unknown client host - current thread not instance of 'RMIIncomingThread'");
+ }
}
public static void setLog(OutputStream out) {
Index: kaffe/libraries/javalib/profiles/allatonce/all.files
diff -u kaffe/libraries/javalib/profiles/allatonce/all.files:1.37 kaffe/libraries/javalib/profiles/allatonce/all.files:1.38
--- kaffe/libraries/javalib/profiles/allatonce/all.files:1.37 Fri Jan 23 17:34:21 2004
+++ kaffe/libraries/javalib/profiles/allatonce/all.files Wed Mar 10 17:24:46 2004
@@ -208,6 +208,7 @@
gnu/java/rmi/server/ConnectionRunnerPool.java
gnu/java/rmi/server/ProtocolConstants.java
gnu/java/rmi/server/RMIDefaultSocketFactory.java
+gnu/java/rmi/server/RMIIncomingThread.java
gnu/java/rmi/server/RMIHashes.java
gnu/java/rmi/server/RMIObjectInputStream.java
gnu/java/rmi/server/RMIObjectOutputStream.java
Index: kaffe/libraries/javalib/profiles/default/rmi.files
diff -u kaffe/libraries/javalib/profiles/default/rmi.files:1.5 kaffe/libraries/javalib/profiles/default/rmi.files:1.6
--- kaffe/libraries/javalib/profiles/default/rmi.files:1.5 Thu Aug 21 12:48:47 2003
+++ kaffe/libraries/javalib/profiles/default/rmi.files Wed Mar 10 17:24:46 2004
@@ -17,6 +17,7 @@
gnu/java/rmi/server/ConnectionRunnerPool.java
gnu/java/rmi/server/ProtocolConstants.java
gnu/java/rmi/server/RMIDefaultSocketFactory.java
+gnu/java/rmi/server/RMIIncomingThread.java
gnu/java/rmi/server/RMIHashes.java
gnu/java/rmi/server/RMIObjectInputStream.java
gnu/java/rmi/server/RMIObjectOutputStream.java
More information about the kaffe
mailing list