From: tromey Date: Tue, 1 Oct 2002 03:46:43 +0000 (+0000) Subject: * java/io/ObjectInputStream.java (resolveProxyClass): New method X-Git-Tag: upstream/4.9.2~84146 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1834f2d6e707af5e33654167ac0b3844210764c3;p=platform%2Fupstream%2Flinaro-gcc.git * java/io/ObjectInputStream.java (resolveProxyClass): New method from Classpath. * Makefile.in: Rebuilt. * Makefile.am (rmi_java_source_files): Added new files. * gnu/java/rmi/RMIMarshalledObjectInputStream.java, gnu/java/rmi/RMIMarshalledObjectOutputStream.java, gnu/java/rmi/server/ConnectionRunnerPool.java: New files from Classpath. * 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_Skel.java, gnu/java/rmi/registry/RegistryImpl_Stub.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/UnicastServer.java, gnu/java/rmi/server/UnicastServerRef.java, java/rmi/MarshalledObject.java, java/rmi/server/RMIClassLoader.java, java/rmi/server/RemoteObject.java, java/rmi/server/UnicastRemoteObject.java, java/security/SecureClassLoader.java: Merged from Classpath. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57675 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 4b0cc0f..8c2ab3e 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,32 @@ +2002-09-30 Tom Tromey + + * java/io/ObjectInputStream.java (resolveProxyClass): New method + from Classpath. + * Makefile.in: Rebuilt. + * Makefile.am (rmi_java_source_files): Added new files. + * gnu/java/rmi/RMIMarshalledObjectInputStream.java, + gnu/java/rmi/RMIMarshalledObjectOutputStream.java, + gnu/java/rmi/server/ConnectionRunnerPool.java: New files from + Classpath. + * 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_Skel.java, + gnu/java/rmi/registry/RegistryImpl_Stub.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/UnicastServer.java, + gnu/java/rmi/server/UnicastServerRef.java, + java/rmi/MarshalledObject.java, + java/rmi/server/RMIClassLoader.java, + java/rmi/server/RemoteObject.java, + java/rmi/server/UnicastRemoteObject.java, + java/security/SecureClassLoader.java: Merged from Classpath. + 2002-09-29 Anthony Green * java/lang/reflect/UndeclaredThrowableException.java: New file. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 5d2a182..a1ea9e0 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -1284,6 +1284,8 @@ java/rmi/server/SocketSecurityException.java \ java/rmi/server/UID.java \ java/rmi/server/UnicastRemoteObject.java \ java/rmi/server/Unreferenced.java \ +gnu/java/rmi/RMIMarshalledObjectInputStream.java \ +gnu/java/rmi/RMIMarshalledObjectOutputStream.java \ gnu/java/rmi/dgc/DGCImpl.java \ gnu/java/rmi/dgc/DGCImpl_Skel.java \ gnu/java/rmi/dgc/DGCImpl_Stub.java \ @@ -1295,6 +1297,7 @@ gnu/java/rmi/rmic/Compiler.java \ gnu/java/rmi/rmic/CompilerProcess.java \ gnu/java/rmi/rmic/RMIC.java \ gnu/java/rmi/rmic/TabbedWriter.java \ +gnu/java/rmi/server/ConnectionRunnerPool.java \ gnu/java/rmi/server/ProtocolConstants.java \ gnu/java/rmi/server/RMIDefaultSocketFactory.java \ gnu/java/rmi/server/RMIHashes.java \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index a0f6851..4bdfe19 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -1042,6 +1042,8 @@ java/rmi/server/SocketSecurityException.java \ java/rmi/server/UID.java \ java/rmi/server/UnicastRemoteObject.java \ java/rmi/server/Unreferenced.java \ +gnu/java/rmi/RMIMarshalledObjectInputStream.java \ +gnu/java/rmi/RMIMarshalledObjectOutputStream.java \ gnu/java/rmi/dgc/DGCImpl.java \ gnu/java/rmi/dgc/DGCImpl_Skel.java \ gnu/java/rmi/dgc/DGCImpl_Stub.java \ @@ -1053,6 +1055,7 @@ gnu/java/rmi/rmic/Compiler.java \ gnu/java/rmi/rmic/CompilerProcess.java \ gnu/java/rmi/rmic/RMIC.java \ gnu/java/rmi/rmic/TabbedWriter.java \ +gnu/java/rmi/server/ConnectionRunnerPool.java \ gnu/java/rmi/server/ProtocolConstants.java \ gnu/java/rmi/server/RMIDefaultSocketFactory.java \ gnu/java/rmi/server/RMIHashes.java \ @@ -2462,8 +2465,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/locale/LocaleInformation_zh_HK.P \ .deps/gnu/java/locale/LocaleInformation_zh_SG.P \ .deps/gnu/java/locale/LocaleInformation_zh_TW.P \ -.deps/gnu/java/math/MPN.P .deps/gnu/java/rmi/dgc/DGCImpl.P \ -.deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \ +.deps/gnu/java/math/MPN.P \ +.deps/gnu/java/rmi/RMIMarshalledObjectInputStream.P \ +.deps/gnu/java/rmi/RMIMarshalledObjectOutputStream.P \ +.deps/gnu/java/rmi/dgc/DGCImpl.P .deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \ .deps/gnu/java/rmi/dgc/DGCImpl_Stub.P \ .deps/gnu/java/rmi/registry/RegistryImpl.P \ .deps/gnu/java/rmi/registry/RegistryImpl_Skel.P \ @@ -2472,6 +2477,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/gnu/java/rmi/rmic/Compiler.P \ .deps/gnu/java/rmi/rmic/CompilerProcess.P \ .deps/gnu/java/rmi/rmic/RMIC.P .deps/gnu/java/rmi/rmic/TabbedWriter.P \ +.deps/gnu/java/rmi/server/ConnectionRunnerPool.P \ .deps/gnu/java/rmi/server/ProtocolConstants.P \ .deps/gnu/java/rmi/server/RMIDefaultSocketFactory.P \ .deps/gnu/java/rmi/server/RMIHashes.P \ @@ -3785,7 +3791,7 @@ maintainer-clean-recursive: dot_seen=no; \ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ rev="$$subdir $$rev"; \ - test "$$subdir" != "." || dot_seen=yes; \ + test "$$subdir" = "." && dot_seen=yes; \ done; \ test "$$dot_seen" = "no" && rev=". $$rev"; \ target=`echo $@ | sed s/-recursive//`; \ diff --git a/libjava/gcj/Makefile.in b/libjava/gcj/Makefile.in index 9ec51a6..201722f 100644 --- a/libjava/gcj/Makefile.in +++ b/libjava/gcj/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libjava/gnu/java/rmi/RMIMarshalledObjectInputStream.java b/libjava/gnu/java/rmi/RMIMarshalledObjectInputStream.java new file mode 100644 index 0000000..8835280 --- /dev/null +++ b/libjava/gnu/java/rmi/RMIMarshalledObjectInputStream.java @@ -0,0 +1,70 @@ +/* gnu.java.rmi.RMIMarshalledObjectInputStream + Copyright (C) 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; + +import gnu.java.rmi.server.RMIObjectInputStream; +import java.io.ObjectInputStream; +import java.io.IOException; +import java.io.ByteArrayInputStream; + +/** + * This class is only for java.rmi.MarshalledObject to deserialize object from + * objBytes and locBytes + */ + +public class RMIMarshalledObjectInputStream extends RMIObjectInputStream +{ + private ObjectInputStream locStream; + + public RMIMarshalledObjectInputStream(byte[] objBytes, byte[] locBytes) throws IOException + { + super(new ByteArrayInputStream(objBytes)); + if(locBytes != null) + locStream = new ObjectInputStream(new ByteArrayInputStream(locBytes)); + } + + //This method overrides RMIObjectInputStream's + protected Object getAnnotation() throws IOException, ClassNotFoundException + { + if(locStream == null) + return null; + return locStream.readObject(); + } + +} // End of RMIMarshalledObjectInputStream diff --git a/libjava/gnu/java/rmi/RMIMarshalledObjectOutputStream.java b/libjava/gnu/java/rmi/RMIMarshalledObjectOutputStream.java new file mode 100644 index 0000000..6639291 --- /dev/null +++ b/libjava/gnu/java/rmi/RMIMarshalledObjectOutputStream.java @@ -0,0 +1,103 @@ +/* gnu.java.rmi.RMIMarshalledObjectOutputStream + Copyright (C) 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; + +import java.io.OutputStream; +import java.io.ObjectOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.rmi.Remote; +import java.rmi.server.ObjID; +import java.rmi.server.RemoteStub; + +import gnu.java.rmi.server.RMIObjectOutputStream; +import gnu.java.rmi.server.UnicastServerRef; + +/** + * This class is only for java.rmi.MarshalledObject to serialize object and + * got objBytes and locBytes + */ +public class RMIMarshalledObjectOutputStream extends RMIObjectOutputStream +{ + private ObjectOutputStream locStream; + private ByteArrayOutputStream locBytesStream; + + public RMIMarshalledObjectOutputStream(OutputStream objStream) throws IOException + { + super(objStream); + } + + //This method overrides RMIObjectOutputStream's. + protected void setAnnotation(String annotation) throws IOException{ + synchronized(this){ + if(locStream == null){ + locBytesStream = new ByteArrayOutputStream(); + locStream = new ObjectOutputStream(locBytesStream); + } + } + locStream.writeObject(annotation); + } + + //This method overrides ObjectOutputStream's to replace Remote to RemoteStub + protected Object replaceObject(Object obj) throws IOException + { + if((obj instanceof Remote) && !(obj instanceof RemoteStub)) + { + UnicastServerRef ref = new UnicastServerRef(new ObjID(), 0, null); + try{ + return ref.exportObject((Remote)obj); + }catch(Exception e){} + } + return obj; + } + + public void flush() throws IOException { + super.flush(); + if(locStream != null) + locStream.flush(); + } + + public byte[] getLocBytes(){ + if(locStream != null) + return locBytesStream.toByteArray(); + return null; + } + +} // End of RMIMarshalledObjectOutputStream + diff --git a/libjava/gnu/java/rmi/dgc/DGCImpl.java b/libjava/gnu/java/rmi/dgc/DGCImpl.java index adca54f..fba18c1 100644 --- a/libjava/gnu/java/rmi/dgc/DGCImpl.java +++ b/libjava/gnu/java/rmi/dgc/DGCImpl.java @@ -49,12 +49,16 @@ import gnu.java.rmi.server.UnicastServerRef; public class DGCImpl extends UnicastRemoteObject implements DGC { +private static final long leaseValue = 600000L; + public DGCImpl() throws RemoteException { super(new UnicastServerRef(new ObjID(ObjID.DGC_ID), 0, RMISocketFactory.getSocketFactory())); } public Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) throws RemoteException { - System.out.println("DGCImpl.dirty - not implemented"); + VMID vmid = lease.getVMID(); + lease = new Lease(vmid, leaseValue); + System.out.println("DGCImpl.dirty - not completely implemented"); return (lease); } diff --git a/libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java b/libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java index fd0f2ee..545ebc7 100644 --- a/libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java +++ b/libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java @@ -1,3 +1,41 @@ +/* DGCImpl_Skel.java + Copyright (C) 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. */ + + // Skel class generated by rmic - DO NOT EDIT! package gnu.java.rmi.dgc; diff --git a/libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java b/libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java index e611fb2..bffde52 100644 --- a/libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java +++ b/libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java @@ -1,3 +1,41 @@ +/* DGCImpl_Stub.java + Copyright (C) 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. */ + + // Stub class generated by rmic - DO NOT EDIT! package gnu.java.rmi.dgc; diff --git a/libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java b/libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java index 7ba41c3..de6b9e4 100644 --- a/libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java +++ b/libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java @@ -1,3 +1,41 @@ +/* RegistryImpl_Skel.java + Copyright (C) 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. */ + + // Skel class generated by rmic - DO NOT EDIT! package gnu.java.rmi.registry; diff --git a/libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java b/libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java index bfa755c..33cb06a 100644 --- a/libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java +++ b/libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java @@ -1,3 +1,41 @@ +/* RegistryImpl_Stub.java + Copyright (C) 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. */ + + // Stub class generated by rmic - DO NOT EDIT! package gnu.java.rmi.registry; diff --git a/libjava/gnu/java/rmi/server/ConnectionRunnerPool.java b/libjava/gnu/java/rmi/server/ConnectionRunnerPool.java new file mode 100644 index 0000000..df6363b --- /dev/null +++ b/libjava/gnu/java/rmi/server/ConnectionRunnerPool.java @@ -0,0 +1,154 @@ +/* gnu.java.rmi.server.ConnectionRunnerPool + Copyright (C) 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; + +import java.util.ArrayList; +import java.util.Arrays; + +//Should I generalize this class? + +class ConnectionRunnerPool +{ + + public static + class ConnectionRunner extends Thread{ + private UnicastConnection conn; + private volatile boolean exiting = false; + + public ConnectionRunner(ThreadGroup group, String id){ + super(group, id); + } + + public synchronized void run(){ + while(!exiting){ + if(conn == null) + try{ + wait(); + }catch(InterruptedException e){ + continue; + } + else{ + conn.run(); + conn = null; + synchronized(ConnectionRunnerPool.class){ + freelist.add(this); + if(freelist.size() == 1) + ConnectionRunnerPool.class.notifyAll(); + } + } + } + } + + public synchronized void dispatch(UnicastConnection conn){ + this.conn = conn; + notify(); + } + + void exit(){ + exiting = true; + if(conn != null) + try{ + join(500); + }catch(InterruptedException e){} + interrupt(); + } + + } + + private static int size = 5; + private static int max_size = 10; + + private static ArrayList freelist; + + private static ThreadGroup group = new ThreadGroup("pool"); + + static { + ConnectionRunner[] pools = new ConnectionRunner[size]; + for(int i = 0; i < pools.length; i++){ + pools[i] = new ConnectionRunner(group, new Integer(i).toString()); + pools[i].setContextClassLoader(Thread.currentThread().getContextClassLoader()); + pools[i].start(); + } + freelist = new ArrayList(Arrays.asList(pools)); + } + + public static void setSize(int size_){ + size = size_; + } + + public static void setMaxSize(int size){ + max_size = size; + } + + private synchronized static ConnectionRunner getConnectionRunner() + { + if(freelist.size() == 0){ + if(size < max_size){ + ++size; + ConnectionRunner a = new ConnectionRunner(group, new Integer(size).toString()); + a.start(); + freelist.add(a); + }else + while(freelist.size() == 0) + try{ + ConnectionRunnerPool.class.wait(); + }catch(InterruptedException e){} + } + + // always let the first in pool most busy or other scheduling plan?? + ConnectionRunner a = (ConnectionRunner)freelist.get(0); + freelist.remove(a); + return a; + } + + public static void dispatchConnection(UnicastConnection conn) + { + ConnectionRunner r = getConnectionRunner(); + r.dispatch(conn); + } + + public static void exit() + { + Thread[] list = new Thread[group.activeCount()]; + group.enumerate(list); + for(int i = 0; i < list.length; i++) + ((ConnectionRunner)list[i]).exit(); + } + +} diff --git a/libjava/gnu/java/rmi/server/RMIHashes.java b/libjava/gnu/java/rmi/server/RMIHashes.java index 993e5bf..6e32724 100644 --- a/libjava/gnu/java/rmi/server/RMIHashes.java +++ b/libjava/gnu/java/rmi/server/RMIHashes.java @@ -39,13 +39,56 @@ package gnu.java.rmi.server; import java.lang.reflect.Method; import java.lang.Class; -import gnu.java.security.provider.SHA; +import gnu.java.io.NullOutputStream; +import gnu.java.lang.reflect.TypeSignature; +import java.security.MessageDigest; +import java.security.DigestOutputStream; +import java.io.DataOutputStream; +import java.io.ByteArrayOutputStream; public class RMIHashes { + //There're other places using DigestOutputStream to generate hash in classpath, but I think the way I used + //here is more efficient, anyway, you can switch to DigestOutputStream by doing like "//or:" comments say. + + //or:add this statement: private static final NullOutputStream nullOutputStream = new NullOutputStream (); public static long getMethodHash(Method meth) { - return meth.hashCode (); + //Object Serialization Spec 8.3 + try + { + MessageDigest md = MessageDigest.getInstance ("SHA"); + //or:remove this statement: DigestOutputStream digest_out = new DigestOutputStream (nullOutputStream, md); + ByteArrayOutputStream digest_out = new ByteArrayOutputStream(); + DataOutputStream data_out = new DataOutputStream (digest_out); + + StringBuffer sbuf = new StringBuffer(); + sbuf.append(meth.getName()); + sbuf.append('('); + Class params[] = meth.getParameterTypes(); + for(int i = 0; i < params.length; i++) + sbuf.append(TypeSignature.getEncodingOfClass(params[i])); + sbuf.append(')'); + Class rcls = meth.getReturnType(); + if(rcls != Void.TYPE) + sbuf.append(TypeSignature.getEncodingOfClass(rcls)); + else + sbuf.append('V'); + + data_out.writeUTF (sbuf.toString()); + data_out.flush(); + data_out.close (); + + md.update(digest_out.toByteArray()); //or:remove this statement + byte[] sha = md.digest (); + long result = 0; + int len = sha.length < 8 ? sha.length : 8; + for (int i=0; i < len; i++) + result += (long)(sha[i] & 0xFF) << (8 * i); + return result; + }catch(Exception _){ + return -1L; + } } public static long getInterfaceHash(Class clazz) @@ -53,3 +96,4 @@ public class RMIHashes return clazz.hashCode (); } } + diff --git a/libjava/gnu/java/rmi/server/RMIObjectInputStream.java b/libjava/gnu/java/rmi/server/RMIObjectInputStream.java index 70b6c53..5913e92 100644 --- a/libjava/gnu/java/rmi/server/RMIObjectInputStream.java +++ b/libjava/gnu/java/rmi/server/RMIObjectInputStream.java @@ -44,6 +44,8 @@ import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; import java.rmi.server.RMIClassLoader; +import java.lang.ClassNotFoundException; +import java.lang.reflect.Proxy; public class RMIObjectInputStream extends ObjectInputStream { @@ -56,20 +58,80 @@ public RMIObjectInputStream(InputStream strm, UnicastConnectionManager man) thro enableResolveObject(true); } +public RMIObjectInputStream(InputStream strm) throws IOException { + this(strm, UnicastConnectionManager.getInstance(0, null)); +} + 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)); + String annotation = (String)getAnnotation(); + try{ + return super.resolveClass(desc); + }catch(ClassNotFoundException _){}; + + try { + if(annotation == null) + return (RMIClassLoader.loadClass(desc.getName())); + else + return (RMIClassLoader.loadClass(annotation, desc.getName())); } - else { - try { - return (RMIClassLoader.loadClass(new URL(annotation), desc.getName())); - } - catch (MalformedURLException _) { - throw new ClassNotFoundException(desc.getName()); - } + catch (MalformedURLException _) { + throw new ClassNotFoundException(desc.getName()); } } +//Separate it for override by MarshalledObject +protected Object getAnnotation() + throws IOException, ClassNotFoundException +{ + return readObject(); +} + +protected Class resolveProxyClass(String intfs[]) + throws IOException, ClassNotFoundException +{ + String annotation = (String)getAnnotation(); + try{ + return super.resolveProxyClass(intfs); + }catch(ClassNotFoundException _){}; + + Class clss[] = new Class[intfs.length]; + if(annotation == null) + clss[0] = RMIClassLoader.loadClass(intfs[0]); + else + clss[0] = RMIClassLoader.loadClass(annotation, intfs[0]); + //assume all interfaces can be loaded by the same classloader + ClassLoader loader = clss[0].getClassLoader(); + if(loader == null) + for(int i = 1; i < intfs.length; i++) + clss[i] = Class.forName(intfs[i]); + else + for(int i = 1; i < intfs.length; i++) + clss[i] = loader.loadClass(intfs[i]); + return Proxy.getProxyClass(loader, clss); +} + +protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException { + if(valueClass.isPrimitive()){ + if(valueClass == Boolean.TYPE) + return new Boolean(readBoolean()); + if(valueClass == Byte.TYPE) + return new Byte(readByte()); + if(valueClass == Character.TYPE) + return new Character(readChar()); + if(valueClass == Short.TYPE) + return new Short(readShort()); + if(valueClass == Integer.TYPE) + return new Integer(readInt()); + if(valueClass == Long.TYPE) + return new Long(readLong()); + if(valueClass == Float.TYPE) + return new Float(readFloat()); + if(valueClass == Double.TYPE) + return new Double(readDouble()); + else + throw new Error("Unsupported primitive class: " + valueClass); + } else + return readObject(); } + +} \ No newline at end of file diff --git a/libjava/gnu/java/rmi/server/RMIObjectOutputStream.java b/libjava/gnu/java/rmi/server/RMIObjectOutputStream.java index d729047..71a2bac 100644 --- a/libjava/gnu/java/rmi/server/RMIObjectOutputStream.java +++ b/libjava/gnu/java/rmi/server/RMIObjectOutputStream.java @@ -41,17 +41,74 @@ import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.IOException; import java.rmi.server.RMIClassLoader; +import java.rmi.Remote; +import java.rmi.server.RemoteStub; +import java.rmi.server.ObjID; public class RMIObjectOutputStream extends ObjectOutputStream { public RMIObjectOutputStream(OutputStream strm) throws IOException { super(strm); + enableReplaceObject(true); +} + +//Separate it for override by MarshalledObject +protected void setAnnotation(String annotation) throws IOException{ + writeObject(annotation); } protected void annotateClass(Class cls) throws IOException { -//System.out.println("Annotating class: " + cls); - writeObject(RMIClassLoader.getClassAnnotation(cls)); + setAnnotation(RMIClassLoader.getClassAnnotation(cls)); +} + +protected void annotateProxyClass(Class cls) + throws IOException +{ + annotateClass(cls); +} + +protected Object replaceObject(Object obj) + throws IOException +{ + if((obj instanceof Remote) && !(obj instanceof RemoteStub)){ + UnicastServerRef ref = new UnicastServerRef(new ObjID(), 0, null); + try{ + return ref.exportObject((Remote)obj); + }catch(Exception e){} + } + return obj; +} + +protected void writeValue(Object value, Class valueClass) throws IOException{ + if(valueClass.isPrimitive()){ + if(valueClass == Boolean.TYPE) + writeBoolean(((Boolean)value).booleanValue()); + else + if(valueClass == Byte.TYPE) + writeByte(((Byte)value).byteValue()); + else + if(valueClass == Character.TYPE) + writeChar(((Character)value).charValue()); + else + if(valueClass == Short.TYPE) + writeShort(((Short)value).shortValue()); + else + if(valueClass == Integer.TYPE) + writeInt(((Integer)value).intValue()); + else + if(valueClass == Long.TYPE) + writeLong(((Long)value).longValue()); + else + if(valueClass == Float.TYPE) + writeFloat(((Float)value).floatValue()); + else + if(valueClass == Double.TYPE) + writeDouble(((Double)value).doubleValue()); + else + throw new Error("Unsupported primitive class: " + valueClass); + } else + writeObject(value); } } diff --git a/libjava/gnu/java/rmi/server/UnicastConnection.java b/libjava/gnu/java/rmi/server/UnicastConnection.java index a895165..e13bb68 100644 --- a/libjava/gnu/java/rmi/server/UnicastConnection.java +++ b/libjava/gnu/java/rmi/server/UnicastConnection.java @@ -44,6 +44,8 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.ObjectOutput; import java.io.ObjectInput; import java.io.IOException; @@ -65,9 +67,10 @@ UnicastConnection(UnicastConnectionManager man, Socket sock) { } void acceptConnection() throws IOException { -//System.out.println("Accepting connection on " + lport); - din = new DataInputStream(sock.getInputStream()); - dout = new DataOutputStream(sock.getOutputStream()); +//System.out.println("Accepting connection on " + sock); + //Use BufferedXXXStream would be more efficient + din = new DataInputStream(new BufferedInputStream(sock.getInputStream())); + dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); int sig = din.readInt(); if (sig != PROTOCOL_HEADER) { @@ -85,6 +88,7 @@ void acceptConnection() throws IOException { // Send my hostname and port dout.writeUTF(manager.serverName); dout.writeInt(manager.serverPort); + dout.flush(); // Read their hostname and port String rhost = din.readUTF(); @@ -94,15 +98,16 @@ void acceptConnection() throws IOException { } void makeConnection(int protocol) throws IOException { - dout = new DataOutputStream(sock.getOutputStream()); - din = new DataInputStream(sock.getInputStream()); + //Use BufferedXXXStream would be more efficient + din = new DataInputStream(new BufferedInputStream(sock.getInputStream())); + dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); // Send header dout.writeInt(PROTOCOL_HEADER); dout.writeShort(PROTOCOL_VERSION); dout.writeByte(protocol); - dout.flush(); - + dout.flush(); + if (protocol != SINGLE_OP_PROTOCOL) { // Get back ack. int ack = din.readUnsignedByte(); @@ -117,6 +122,7 @@ void makeConnection(int protocol) throws IOException { // Send them my endpoint dout.writeUTF(manager.serverName); dout.writeInt(manager.serverPort); + dout.flush(); } // Okay, ready to roll ... } @@ -144,13 +150,15 @@ ObjectOutputStream getObjectOutputStream() throws IOException { } void disconnect() { - oin = null; - oout = null; try { - sock.close(); + if(oout != null) + oout.close(); } catch (IOException _) { - } + } + + oin = null; + oout = null; din = null; dout = null; sock = null; diff --git a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java index fe08ad0..64fecdc 100644 --- a/libjava/gnu/java/rmi/server/UnicastConnectionManager.java +++ b/libjava/gnu/java/rmi/server/UnicastConnectionManager.java @@ -57,9 +57,12 @@ public class UnicastConnectionManager implements Runnable, ProtocolConstants { private static String localhost; +// use different maps for server/client type UnicastConnectionManager private static Hashtable servers = new Hashtable(); +private static Hashtable clients = new Hashtable(); -private Thread serverThread; +// make serverThread volatile for poll +private volatile Thread serverThread; private ServerSocket ssock; String serverName; int serverPort; @@ -68,7 +71,9 @@ private RMIClientSocketFactory clientFactory; static { try { - localhost = InetAddress.getLocalHost().getHostName(); + //Use host address instead of host name to avoid name resolving issues + //localhost = InetAddress.getLocalHost().getHostName(); + localhost = InetAddress.getLocalHost().getHostAddress(); } catch (UnknownHostException _) { localhost = "localhost"; @@ -112,11 +117,16 @@ public static synchronized UnicastConnectionManager getInstance(String host, int if (csf == null) { csf = RMISocketFactory.getSocketFactory(); } + // change host name to host address to avoid name resolving issues + try{ + host = InetAddress.getByName(host).getHostAddress(); + }catch(Exception _){} + TripleKey key = new TripleKey(host, port, csf); - UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key); + UnicastConnectionManager man = (UnicastConnectionManager)clients.get(key); if (man == null) { man = new UnicastConnectionManager(host, port, csf); - servers.put(key, man); + clients.put(key, man); } return (man); } @@ -199,17 +209,33 @@ public void startServer() { } /** + * Stop a server on this manager + */ +public void stopServer() { + synchronized(this) { + if(serverThread != null){ + serverThread = null; + try{ + ssock.close(); + }catch(Exception _){} + } + } +} + +/** * Server thread for connection manager. */ public void run() { - for (;;) { + for (;serverThread != null;) { // if serverThread==null, then exit thread try { //System.out.println("Waiting for connection on " + serverPort); UnicastConnection conn = getServerConnection(); - (new Thread(conn)).start(); + // use a thread pool to improve performance + // (new Thread(conn)).start(); + ConnectionRunnerPool.dispatchConnection(conn); } catch (Exception e) { - e.printStackTrace(); + // e.printStackTrace(); } } } diff --git a/libjava/gnu/java/rmi/server/UnicastRef.java b/libjava/gnu/java/rmi/server/UnicastRef.java index 1c5bf57..d6cda49 100644 --- a/libjava/gnu/java/rmi/server/UnicastRef.java +++ b/libjava/gnu/java/rmi/server/UnicastRef.java @@ -107,6 +107,7 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu 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) { @@ -117,6 +118,11 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu } } } + */ + // must handle primitive class and their wrapper classes + Class clss[] = method.getParameterTypes(); + for(int i = 0; i < clss.length; i++) + ((RMIObjectOutputStream)out).writeValue(params[i], clss[i]); out.flush(); } @@ -139,12 +145,25 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu returncode = in.readUnsignedByte(); ack = UID.read(in); - returnval = in.readObject(); + //returnval = in.readObject(); + Class cls = method.getReturnType(); + if(cls == Void.TYPE){ + returnval = null; + }else + returnval = ((RMIObjectInputStream)in).readValue(cls); } catch (IOException e3) { throw new RemoteException("call return failed: ", e3); } + /* if DGCAck is necessary + //According to RMI wire protocol, send a DGCAck + // to indicate receiving return value + dout.writeByte(MESSAGE_DGCACK); + ack.write(dout); + out.flush(); + */ + manager.discardConnection(conn); if (returncode != RETURN_ACK) { @@ -183,13 +202,16 @@ public void writeExternal(ObjectOutput out) throws IOException { } manager.write(out); objid.write(out); - out.writeByte(RETURN_ACK); + // This byte is somewhat confusing when interoperating with JDK + out.writeByte(0); //RETURN_ACK); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { manager = UnicastConnectionManager.read(in); objid = ObjID.read(in); - if (in.readByte() != RETURN_ACK) { + byte ack = in.readByte(); + // This byte is somewhat confusing when interoperating with JDK + if (ack != RETURN_ACK && ack != 0/*jdk ack value*/) { throw new IOException("no ack found"); } } diff --git a/libjava/gnu/java/rmi/server/UnicastServer.java b/libjava/gnu/java/rmi/server/UnicastServer.java index d9f5fb7..15c622f 100644 --- a/libjava/gnu/java/rmi/server/UnicastServer.java +++ b/libjava/gnu/java/rmi/server/UnicastServer.java @@ -65,6 +65,13 @@ public static void exportObject(UnicastServerRef obj) { obj.manager.startServer(); } +// FIX ME: I haven't handle force parameter +public static boolean unexportObject(UnicastServerRef obj, boolean force) { + objects.remove(obj.objid); + obj.manager.stopServer(); + return true; +} + private static synchronized void startDGC() { if (dgc == null) { try { @@ -100,10 +107,14 @@ private static void incomingMessageCall(UnicastConnection conn) throws IOExcepti UnicastServerRef uref = (UnicastServerRef)objects.get(objid); Object returnval; int returncode = RETURN_ACK; + // returnval is from Method.invoke(), so we must check the return class to see + // if it's primitive type + Class returncls = null; if (uref != null) { try { // Dispatch the call to it. returnval = uref.incomingMessageCall(conn, method, hash); + returncls = uref.getMethodReturnType(method, hash); } catch (Exception e) { returnval = e; @@ -121,7 +132,10 @@ private static void incomingMessageCall(UnicastConnection conn) throws IOExcepti out.writeByte(returncode); (new UID()).write(out); - out.writeObject(returnval); + if(returnval != null && returncls != null) + ((RMIObjectOutputStream)out).writeValue(returnval, returncls); + else + out.writeObject(returnval); out.flush(); } diff --git a/libjava/gnu/java/rmi/server/UnicastServerRef.java b/libjava/gnu/java/rmi/server/UnicastServerRef.java index b145089..196f969 100644 --- a/libjava/gnu/java/rmi/server/UnicastServerRef.java +++ b/libjava/gnu/java/rmi/server/UnicastServerRef.java @@ -66,14 +66,15 @@ import java.io.ObjectOutputStream; import java.util.Hashtable; public class UnicastServerRef - extends UnicastRef { + extends UnicastRef + implements ServerRef{ //SHOULD implement ServerRef final static private Class[] stubprototype = new Class[] { RemoteRef.class }; Remote myself; private Skeleton skel; private RemoteStub stub; -private Hashtable methods; +private Hashtable methods = new Hashtable(); public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) { super(id); @@ -95,7 +96,7 @@ public RemoteStub exportObject(Remote obj) throws RemoteException { skel = (Skeleton)getHelperClass(cls, "_Skel"); // Build hash of methods which may be called. - buildMethodHash(obj.getClass()); + buildMethodHash(obj.getClass(), true); // Export it. UnicastServer.exportObject(this); @@ -104,10 +105,25 @@ public RemoteStub exportObject(Remote obj) throws RemoteException { return (stub); } +public RemoteStub exportObject(Remote remote, Object obj) + throws RemoteException +{ + //FIX ME + return exportObject(remote); +} + + +public boolean unexportObject(Remote obj, boolean force) throws RemoteException { + // Remove all hashes of methods which may be called. + buildMethodHash(obj.getClass(), false); + return UnicastServer.unexportObject(this, force); +} + private Object getHelperClass(Class cls, String type) { try { - String classname = cls.getName(); - Class scls = Class.forName(classname + type); + String classname = cls.getName(); + ClassLoader cl = cls.getClassLoader(); //DONT use "Class scls = Class.forName(classname + type);" + Class scls = cl.loadClass(classname + type); if (type.equals("_Stub")) { try { // JDK 1.2 stubs @@ -147,8 +163,7 @@ public String getClientHost() throws ServerNotActiveException { throw new Error("Not implemented"); } -private void buildMethodHash(Class cls) { - methods = new Hashtable(); +private void buildMethodHash(Class cls, boolean build) { Method[] meths = cls.getMethods(); for (int i = 0; i < meths.length; i++) { /* Don't need to include any java.xxx related stuff */ @@ -156,11 +171,23 @@ private void buildMethodHash(Class cls) { continue; } long hash = RMIHashes.getMethodHash(meths[i]); - methods.put(new Long (hash), meths[i]); + if(build) + methods.put(new Long (hash), meths[i]); + else + methods.remove(new Long (hash)); //System.out.println("meth = " + meths[i] + ", hash = " + hash); } } +Class getMethodReturnType(int method, long hash) throws Exception +{ + if (method == -1) { + Method meth = (Method)methods.get(new Long (hash)); + return meth.getReturnType(); + }else + return null; +} + 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 @@ -189,7 +216,15 @@ public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throw t; } } - return (meth.invoke(myself, args)); + //We must reinterpret the exception thrown by meth.invoke() + //return (meth.invoke(myself, args)); + Object ret = null; + try{ + ret = meth.invoke(myself, args); + }catch(InvocationTargetException e){ + throw (Exception)(e.getTargetException()); + } + return ret; } // Otherwise this is JDK 1.1 style RMI - we find the skeleton // and invoke it using the method number. We wrap up our diff --git a/libjava/include/Makefile.in b/libjava/include/Makefile.in index ebcd425..1deb2b4 100644 --- a/libjava/include/Makefile.in +++ b/libjava/include/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index e1e16f2..08ce401 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -1,5 +1,5 @@ /* ObjectInputStream.java -- Class used to read serialized objects - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -42,6 +42,7 @@ import gnu.classpath.Configuration; import java.lang.reflect.Array; import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Hashtable; import java.util.Vector; @@ -527,6 +528,32 @@ public class ObjectInputStream extends InputStream } + protected Class resolveProxyClass (String[] intfs) + throws IOException, ClassNotFoundException + { + SecurityManager sm = System.getSecurityManager (); + + if (sm == null) + sm = new SecurityManager () {}; + + ClassLoader cl = currentClassLoader (sm); + + Class[] clss = new Class[intfs.length]; + if(cl == null){ + for (int i = 0; i < intfs.length; i++) + clss[i] = Class.forName(intfs[i]); + cl = ClassLoader.getSystemClassLoader(); + } + else + for (int i = 0; i < intfs.length; i++) + clss[i] = cl.loadClass(intfs[i]); + try { + return Proxy.getProxyClass(cl, clss); + } catch (IllegalArgumentException e) { + throw new ClassNotFoundException(null, e); + } + } + /** If enable is true and this object is trusted, then resolveObject (Object) will be called diff --git a/libjava/java/rmi/MarshalledObject.java b/libjava/java/rmi/MarshalledObject.java index eaa7fb5..4c9a9cc 100644 --- a/libjava/java/rmi/MarshalledObject.java +++ b/libjava/java/rmi/MarshalledObject.java @@ -38,24 +38,73 @@ exception statement from your version. */ package java.rmi; import java.io.Serializable; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import gnu.java.rmi.RMIMarshalledObjectInputStream; +import gnu.java.rmi.RMIMarshalledObjectOutputStream; +/** + * FIXME - doc missing + */ public final class MarshalledObject - extends Object implements Serializable { - -public MarshalledObject(Object obj) { - throw new Error("Not implemented"); -} - -public boolean equals(Object obj) { - throw new Error("Not implemented"); -} - -public Object get() { - throw new Error("Not implemented"); -} - -public int hashCode() { - throw new Error("Not implemented"); + extends Object implements Serializable +{ + + //The following fields are from Java API Documentation "Serialized form" + private static final long serialVersionUID = 8988374069173025854L; + byte[] objBytes; + byte[] locBytes; + int hash; + + public MarshalledObject(Object obj) throws java.io.IOException + { + ByteArrayOutputStream objStream = new ByteArrayOutputStream(); + RMIMarshalledObjectOutputStream stream = new RMIMarshalledObjectOutputStream(objStream); + stream.writeObject(obj); + stream.flush(); + objBytes = objStream.toByteArray(); + locBytes = stream.getLocBytes(); + + //The following algorithm of calculating hashCode is similar to String + hash = 0; + for (int i = 0; i < objBytes.length; i++) + hash = hash * 31 + objBytes[i]; + if(locBytes != null) + for (int i = 0; i < locBytes.length; i++) + hash = hash * 31 + locBytes[i]; + } + + public boolean equals(Object obj) + { + if(obj == null || !(obj instanceof MarshalledObject) ) + return false; + + MarshalledObject aobj = (MarshalledObject)obj; + if (objBytes == null || aobj.objBytes == null) + return objBytes == aobj.objBytes; + if (objBytes.length != aobj.objBytes.length) + return false; + for (int i = 0; i < objBytes.length; i++) + { + if (objBytes[i] != aobj.objBytes[i]) + return false; + } + // Ignore comparison of locBytes(annotation) + return true; + } + +public Object get() + throws java.io.IOException, java.lang.ClassNotFoundException +{ + if(objBytes == null) + return null; + RMIMarshalledObjectInputStream stream = + new RMIMarshalledObjectInputStream(objBytes, locBytes); + return stream.readObject(); } - + + public int hashCode() { + return hash; + } + } diff --git a/libjava/java/rmi/server/RMIClassLoader.java b/libjava/java/rmi/server/RMIClassLoader.java index cde97b0..da8f52c 100644 --- a/libjava/java/rmi/server/RMIClassLoader.java +++ b/libjava/java/rmi/server/RMIClassLoader.java @@ -39,21 +39,25 @@ package java.rmi.server; import java.net.URL; import java.net.URLConnection; +import java.net.URLClassLoader; import java.io.IOException; import java.io.DataInputStream; import java.net.MalformedURLException; import java.util.StringTokenizer; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.ArrayList; public class RMIClassLoader { - static private class MyClassLoader extends ClassLoader + static private class MyClassLoader extends URLClassLoader { - /** - * Non-private constructor to reduce bytecode emitted. - */ - MyClassLoader() + private MyClassLoader(URL[] urls, ClassLoader parent) { + super (urls, parent); } Class defineClass(String name, byte[] data) @@ -62,58 +66,133 @@ public class RMIClassLoader } } - static private MyClassLoader loader = new MyClassLoader(); - + private static Map cacheLoaders; //map annotations to loaders + private static Map cacheClasses; //map loader to classes that the loader loaded+ + private static String defaultAnnotation; + private static URL defaultCodebase; + private static MyClassLoader defaultLoader; + + static + { + cacheLoaders = Collections.synchronizedMap(new WeakHashMap(5)); + cacheClasses = Collections.synchronizedMap(new WeakHashMap(5)); + defaultAnnotation = System.getProperty("java.rmi.server.defaultAnnotation"); + try + { + if (defaultAnnotation != null) + defaultCodebase = new URL(defaultAnnotation); + } + catch(Exception _) + { + defaultCodebase = null; + } + if (defaultCodebase != null) + { + defaultLoader = new MyClassLoader(new URL[]{ defaultCodebase }, + Thread.currentThread().getContextClassLoader()); + cacheLoaders.put(defaultAnnotation, defaultLoader); + cacheClasses.put(defaultLoader, Collections.synchronizedMap(new WeakHashMap())); + } + } + /** * @deprecated */ public static Class loadClass(String name) throws MalformedURLException, ClassNotFoundException { - return loadClass(System.getProperty("java.rmi.server.codebase"), name); + return (loadClass("", name)); } - public static Class loadClass(URL codebase, String name) - throws MalformedURLException, ClassNotFoundException + public static Class loadClass(URL codebase, String name) + throws MalformedURLException, ClassNotFoundException { URL u = new URL(codebase, name + ".class"); - try + try { - URLConnection conn = u.openConnection(); - DataInputStream strm = new DataInputStream(conn.getInputStream()); - byte data[] = new byte[conn.getContentLength()]; - strm.readFully(data); - return loader.defineClass(name, data); + URLConnection conn = u.openConnection(); + DataInputStream strm = new DataInputStream(conn.getInputStream()); + byte data[] = new byte[conn.getContentLength()]; + strm.readFully(data); + return (defaultLoader.defineClass(name, data)); } - catch (IOException _) + catch (IOException _) { - throw new ClassNotFoundException(name); + throw new ClassNotFoundException(name); } } - - public static Class loadClass(String codebase, String name) - throws MalformedURLException, ClassNotFoundException + + public static Class loadClass(String codebases, String name) + throws MalformedURLException, ClassNotFoundException { - StringTokenizer tok = new StringTokenizer(codebase, ":"); - while (tok.hasMoreTokens()) + ClassLoader loader = (ClassLoader)cacheLoaders.get(codebases); + if (loader == null) { - try - { - return loadClass(new URL(tok.nextToken()), name); - } - catch (ClassNotFoundException _) - { - // Ignore - try the next one. - } + if (codebases != "") + { + //codebases are separated by " " + StringTokenizer tok = new StringTokenizer(codebases, " "); + ArrayList urls = new ArrayList(); + while (tok.hasMoreTokens()) + urls.add(new URL(tok.nextToken())); + + loader = new MyClassLoader((URL[])urls.toArray(new URL[urls.size()]), + Thread.currentThread().getContextClassLoader()); + cacheLoaders.put(codebases, loader); + cacheClasses.put(loader, Collections.synchronizedMap(new WeakHashMap())); + } + else + { + //if codebases is empty, construct a classloader + // based on current context classloader, + // and we won't cache classloader for empty codebases + loader = new MyClassLoader(new URL[]{ defaultCodebase }, + Thread.currentThread().getContextClassLoader()); + } } - throw new ClassNotFoundException(name); - } + Class c = null; + Map classes = (Map)cacheClasses.get(loader); + if (classes != null) + { + c = (Class)classes.get(name); + if (c == null) + { + c = loader.loadClass(name); + classes.put(name, c); + } + }else + c = loader.loadClass(name); + + return c; + } + public static String getClassAnnotation(Class cl) { - return null; // We don't yet do this. + ClassLoader loader = cl.getClassLoader(); + if (loader == null) + { + if (defaultCodebase != null) + return defaultCodebase.toExternalForm(); + else + return null; + } + if (loader instanceof URLClassLoader) + { + URL[] urls = ((URLClassLoader)loader).getURLs(); + if(urls.length == 0) + return null; + StringBuffer annotation = new StringBuffer(urls[0].toExternalForm()); + for(int i = 1; i < urls.length; i++) + { + annotation.append(' '); + annotation.append(urls[i].toExternalForm()); + } + return annotation.toString(); + } + return null; } - + /** * @deprecated */ diff --git a/libjava/java/rmi/server/RemoteObject.java b/libjava/java/rmi/server/RemoteObject.java index e73dfc5..8ae93ff 100644 --- a/libjava/java/rmi/server/RemoteObject.java +++ b/libjava/java/rmi/server/RemoteObject.java @@ -48,6 +48,7 @@ import java.io.IOException; import java.lang.ClassNotFoundException; import java.lang.InstantiationException; import java.lang.IllegalAccessException; +import java.lang.reflect.Constructor; public abstract class RemoteObject implements Remote, Serializable { @@ -68,9 +69,22 @@ public RemoteRef getRef() { return (ref); } -public static Remote toStub(Remote obj) throws NoSuchObjectException { - throw new Error("Not implemented"); -} + public static Remote toStub(Remote obj) throws NoSuchObjectException + { + Class cls = obj.getClass(); + String classname = cls.getName(); + ClassLoader cl = cls.getClassLoader(); + try + { + Class scls = cl.loadClass(classname + "_Stub"); + // JDK 1.2 stubs + Class[] stubprototype = new Class[] { RemoteRef.class }; + Constructor con = scls.getConstructor(stubprototype); + return (Remote)(con.newInstance(new Object[]{obj})); + } + catch (Exception e) {} + throw new NoSuchObjectException(obj.getClass().getName()); + } public int hashCode() { if (ref == null) { @@ -86,30 +100,46 @@ public boolean equals(Object obj) { return (this == obj); } -public String toString() { - return (ref.toString()); -} - -private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - String cname = in.readUTF(); - if (!cname.equals("")) { - cname = RemoteRef.packagePrefix + '.' + cname; - try { - Class cls = Class.forName(cname); - ref = (RemoteRef)cls.newInstance(); - } - catch (InstantiationException e1) { - throw new UnmarshalException("failed to create ref"); - } - catch (IllegalAccessException e2) { - throw new UnmarshalException("failed to create ref"); - } - ref.readExternal(in); - } - else { - ref = (RemoteRef)in.readObject(); - } -} + public String toString() + { + if (ref == null) + return getClass ().toString (); + return (ref.toString ()); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException + { + String cname = in.readUTF(); + if (!cname.equals("")) + { + if (cname.equals ("UnicastRef2")) + { + // hack for interoperating with JDK + cname = "UnicastRef"; + in.read (); //some unknown UnicastRef2 field + } + + cname = RemoteRef.packagePrefix + '.' + cname; + try + { + Class cls = Class.forName(cname); + ref = (RemoteRef)cls.newInstance(); + } + catch (InstantiationException e1) + { + throw new UnmarshalException("failed to create ref"); + } + catch (IllegalAccessException e2) + { + throw new UnmarshalException("failed to create ref"); + } + ref.readExternal(in); + } + else + { + ref = (RemoteRef)in.readObject(); + } + } private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException { if (ref == null) { diff --git a/libjava/java/rmi/server/UnicastRemoteObject.java b/libjava/java/rmi/server/UnicastRemoteObject.java index 5571b9f..a9c4f35 100644 --- a/libjava/java/rmi/server/UnicastRemoteObject.java +++ b/libjava/java/rmi/server/UnicastRemoteObject.java @@ -42,10 +42,17 @@ import java.rmi.Remote; import java.rmi.server.RemoteRef; import java.rmi.NoSuchObjectException; import gnu.java.rmi.server.UnicastServerRef; +import gnu.java.rmi.server.UnicastServer; public class UnicastRemoteObject extends RemoteServer { +private static final long serialVersionUID = 4974527148936298033L; +//The following serialized fields are from Java API Documentation "Serialized form" +private int port = 0; +private RMIClientSocketFactory csf = null; +private RMIServerSocketFactory ssf = null; + protected UnicastRemoteObject() throws RemoteException { this(0); } @@ -55,11 +62,21 @@ protected UnicastRemoteObject(int port) throws RemoteException { } protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - super(new UnicastServerRef(new ObjID(), port, ssf)); + this.port = port; + //Is RMIXXXSocketFactory serializable + //this.csf = csf; + //this.ssf = ssf; + this.ref = new UnicastServerRef(new ObjID(), port, ssf); + //Should we export it here? + // if we export, we got infinite recursive call: + // UnicastRemoteObject.->...->UnicastServer.startDGC()->UnicastRemoteObject.->... + //exportObject(this); } protected UnicastRemoteObject(RemoteRef ref) throws RemoteException { super((UnicastServerRef)ref); + //Should we export it here? + //exportObject(this); } public Object clone() throws CloneNotSupportedException { @@ -71,16 +88,46 @@ public static RemoteStub exportObject(Remote obj) throws RemoteException { return (sref.exportObject(obj)); } -public static Remote exportObject(Remote obj, int port) throws RemoteException { - return (exportObject(obj)); -} - -public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - return (exportObject(obj)); -} - -public static boolean unexportObject(Remote obj, boolean force) throws NoSuchObjectException { - throw new Error("Not implemented"); -} + public static Remote exportObject(Remote obj, int port) throws RemoteException + { + return exportObject(obj, port, null); + } + + protected static Remote exportObject(Remote obj, int port, RMIServerSocketFactory ssf) + throws RemoteException + { + UnicastServerRef sref = null; + if (obj instanceof RemoteObject) + sref = (UnicastServerRef)((RemoteObject)obj).getRef (); + if(sref == null) + { + sref = new UnicastServerRef(new ObjID (), port, ssf); + } + return (sref.exportObject (obj)); + } + + /** + * FIX ME + */ + public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, + RMIServerSocketFactory ssf) + throws RemoteException + { + return (exportObject(obj, port, ssf)); + } + + public static boolean unexportObject(Remote obj, boolean force) + throws RemoteException, NoSuchObjectException + { + if (obj instanceof RemoteObject) + { + UnicastServerRef sref = (UnicastServerRef)((RemoteObject)obj).getRef(); + return sref.unexportObject(obj, force); + } + else + //FIX ME + ; + return true; + } } diff --git a/libjava/java/security/SecureClassLoader.java b/libjava/java/security/SecureClassLoader.java index 9a4e672..7adba1a 100644 --- a/libjava/java/security/SecureClassLoader.java +++ b/libjava/java/security/SecureClassLoader.java @@ -71,7 +71,7 @@ public class SecureClassLoader extends ClassLoader @param b the data representing the classfile, in classfile format. @param off the offset into the data where the classfile starts. @param len the length of the classfile data in the array. - @param cs the CodeSource for the class + @param cs the CodeSource for the class or null when unknown. @return the class that was defined and optional CodeSource. @@ -81,16 +81,14 @@ public class SecureClassLoader extends ClassLoader CodeSource cs) { // FIXME: Need to cache ProtectionDomains according to 1.3 docs. - ProtectionDomain protectionDomain = - new ProtectionDomain(cs, getPermissions(cs)); - try + if (cs != null) { + ProtectionDomain protectionDomain + = new ProtectionDomain(cs, getPermissions(cs)); return super.defineClass(name, b, off, len, protectionDomain); - } - catch (ClassFormatError cfe) - { - return null; - } + } + else + return super.defineClass(name, b, off, len); } /** diff --git a/libjava/testsuite/Makefile.in b/libjava/testsuite/Makefile.in index 46247a6..e5ed976 100644 --- a/libjava/testsuite/Makefile.in +++ b/libjava/testsuite/Makefile.in @@ -1,6 +1,6 @@ -# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am +# Makefile.in generated automatically by automake 1.4 from Makefile.am -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved.