OSDN Git Service

* java/io/ObjectInputStream.java (resolveProxyClass): New method
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Oct 2002 03:46:43 +0000 (03:46 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Oct 2002 03:46:43 +0000 (03:46 +0000)
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

28 files changed:
libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/gcj/Makefile.in
libjava/gnu/java/rmi/RMIMarshalledObjectInputStream.java [new file with mode: 0644]
libjava/gnu/java/rmi/RMIMarshalledObjectOutputStream.java [new file with mode: 0644]
libjava/gnu/java/rmi/dgc/DGCImpl.java
libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java
libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java
libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java
libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java
libjava/gnu/java/rmi/server/ConnectionRunnerPool.java [new file with mode: 0644]
libjava/gnu/java/rmi/server/RMIHashes.java
libjava/gnu/java/rmi/server/RMIObjectInputStream.java
libjava/gnu/java/rmi/server/RMIObjectOutputStream.java
libjava/gnu/java/rmi/server/UnicastConnection.java
libjava/gnu/java/rmi/server/UnicastConnectionManager.java
libjava/gnu/java/rmi/server/UnicastRef.java
libjava/gnu/java/rmi/server/UnicastServer.java
libjava/gnu/java/rmi/server/UnicastServerRef.java
libjava/include/Makefile.in
libjava/java/io/ObjectInputStream.java
libjava/java/rmi/MarshalledObject.java
libjava/java/rmi/server/RMIClassLoader.java
libjava/java/rmi/server/RemoteObject.java
libjava/java/rmi/server/UnicastRemoteObject.java
libjava/java/security/SecureClassLoader.java
libjava/testsuite/Makefile.in

index 4b0cc0f..8c2ab3e 100644 (file)
@@ -1,3 +1,32 @@
+2002-09-30  Tom Tromey  <tromey@redhat.com>
+
+       * 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  <green@redhat.com>
 
        * java/lang/reflect/UndeclaredThrowableException.java: New file.
index 5d2a182..a1ea9e0 100644 (file)
@@ -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 \
index a0f6851..4bdfe19 100644 (file)
@@ -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//`; \
index 9ec51a6..201722f 100644 (file)
@@ -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 (file)
index 0000000..8835280
--- /dev/null
@@ -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 (file)
index 0000000..6639291
--- /dev/null
@@ -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
+
index adca54f..fba18c1 100644 (file)
@@ -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);
 }
 
index fd0f2ee..545ebc7 100644 (file)
@@ -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;
index e611fb2..bffde52 100644 (file)
@@ -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;
index 7ba41c3..de6b9e4 100644 (file)
@@ -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;
index bfa755c..33cb06a 100644 (file)
@@ -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 (file)
index 0000000..df6363b
--- /dev/null
@@ -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();
+  }
+  
+}
index 993e5bf..6e32724 100644 (file)
@@ -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 ();
   }
 }
+
index 70b6c53..5913e92 100644 (file)
@@ -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
index d729047..71a2bac 100644 (file)
@@ -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);
 }
 
 }
index a895165..e13bb68 100644 (file)
@@ -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;
index fe08ad0..64fecdc 100644 (file)
@@ -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();
                }
        }
 }
index 1c5bf57..d6cda49 100644 (file)
@@ -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");
        }
 }
index d9f5fb7..15c622f 100644 (file)
@@ -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();
 }
index b145089..196f969 100644 (file)
@@ -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
index ebcd425..1deb2b4 100644 (file)
@@ -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.
index e1e16f2..08ce401 100644 (file)
@@ -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 <code>enable</code> is <code>true</code> and this object is
      trusted, then <code>resolveObject (Object)</code> will be called
index eaa7fb5..4c9a9cc 100644 (file)
@@ -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;
+  }
+  
 }
index cde97b0..da8f52c 100644 (file)
@@ -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
    */
index e73dfc5..8ae93ff 100644 (file)
@@ -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) {
index 5571b9f..a9c4f35 100644 (file)
@@ -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.<init>->...->UnicastServer.startDGC()->UnicastRemoteObject.<init>->...
+  //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;
+  }
 
 }
index 9a4e672..7adba1a 100644 (file)
@@ -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);
   }
 
   /**
index 46247a6..e5ed976 100644 (file)
@@ -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.