Commit f903e73b by Norbert Frese Committed by Michael Koch

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
parent 079f946d
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.
2004-03-20 Michael Koch <konqueror@gmx.de>
* java/net/InetAddress.java
......
......@@ -1704,6 +1704,7 @@ gnu/java/rmi/server/ConnectionRunnerPool.java \
gnu/java/rmi/server/ProtocolConstants.java \
gnu/java/rmi/server/RMIDefaultSocketFactory.java \
gnu/java/rmi/server/RMIHashes.java \
gnu/java/rmi/server/RMIIncomingThread.java \
gnu/java/rmi/server/RMIObjectInputStream.java \
gnu/java/rmi/server/RMIObjectOutputStream.java \
gnu/java/rmi/server/RMIVoidValue.java \
......
......@@ -1387,6 +1387,7 @@ gnu/java/rmi/server/ConnectionRunnerPool.java \
gnu/java/rmi/server/ProtocolConstants.java \
gnu/java/rmi/server/RMIDefaultSocketFactory.java \
gnu/java/rmi/server/RMIHashes.java \
gnu/java/rmi/server/RMIIncomingThread.java \
gnu/java/rmi/server/RMIObjectInputStream.java \
gnu/java/rmi/server/RMIObjectOutputStream.java \
gnu/java/rmi/server/RMIVoidValue.java \
......@@ -3347,6 +3348,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/java/rmi/server/ProtocolConstants.P \
.deps/gnu/java/rmi/server/RMIDefaultSocketFactory.P \
.deps/gnu/java/rmi/server/RMIHashes.P \
.deps/gnu/java/rmi/server/RMIIncomingThread.P \
.deps/gnu/java/rmi/server/RMIObjectInputStream.P \
.deps/gnu/java/rmi/server/RMIObjectOutputStream.P \
.deps/gnu/java/rmi/server/RMIVoidValue.P \
......
/*
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;
}
}
......@@ -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);
}
}
......@@ -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();
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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();
......
......@@ -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) {
......
......@@ -39,6 +39,7 @@ package java.rmi.server;
import java.io.OutputStream;
import java.io.PrintStream;
import gnu.java.rmi.server.RMIIncomingThread;
public abstract class RemoteServer
extends RemoteObject {
......@@ -54,7 +55,14 @@ protected RemoteServer(RemoteRef ref) {
}
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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment