This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: FYI: Classpath merge


This merges some RMI changes from Classpath back in to libgcj.  It
also merges a couple java.security classes.

Tom

Index: ChangeLog
from  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.

Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.247
diff -u -r1.247 Makefile.am
--- Makefile.am 30 Sep 2002 05:19:06 -0000 1.247
+++ Makefile.am 1 Oct 2002 03:42:55 -0000
@@ -1284,6 +1284,8 @@
 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/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: gnu/java/rmi/RMIMarshalledObjectInputStream.java
===================================================================
RCS file: gnu/java/rmi/RMIMarshalledObjectInputStream.java
diff -N gnu/java/rmi/RMIMarshalledObjectInputStream.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/rmi/RMIMarshalledObjectInputStream.java 1 Oct 2002 03:42:59 -0000
@@ -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
Index: gnu/java/rmi/RMIMarshalledObjectOutputStream.java
===================================================================
RCS file: gnu/java/rmi/RMIMarshalledObjectOutputStream.java
diff -N gnu/java/rmi/RMIMarshalledObjectOutputStream.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/rmi/RMIMarshalledObjectOutputStream.java 1 Oct 2002 03:42:59 -0000
@@ -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: gnu/java/rmi/dgc/DGCImpl.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/dgc/DGCImpl.java,v
retrieving revision 1.2
diff -u -r1.2 DGCImpl.java
--- gnu/java/rmi/dgc/DGCImpl.java 22 Jan 2002 22:39:58 -0000 1.2
+++ gnu/java/rmi/dgc/DGCImpl.java 1 Oct 2002 03:42:59 -0000
@@ -49,12 +49,16 @@
 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: gnu/java/rmi/dgc/DGCImpl_Skel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/dgc/DGCImpl_Skel.java,v
retrieving revision 1.1
diff -u -r1.1 DGCImpl_Skel.java
--- gnu/java/rmi/dgc/DGCImpl_Skel.java 28 Aug 2001 00:03:20 -0000 1.1
+++ gnu/java/rmi/dgc/DGCImpl_Skel.java 1 Oct 2002 03:42:59 -0000
@@ -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: gnu/java/rmi/dgc/DGCImpl_Stub.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/dgc/DGCImpl_Stub.java,v
retrieving revision 1.1
diff -u -r1.1 DGCImpl_Stub.java
--- gnu/java/rmi/dgc/DGCImpl_Stub.java 28 Aug 2001 00:03:20 -0000 1.1
+++ gnu/java/rmi/dgc/DGCImpl_Stub.java 1 Oct 2002 03:42:59 -0000
@@ -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: gnu/java/rmi/registry/RegistryImpl_Skel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/registry/RegistryImpl_Skel.java,v
retrieving revision 1.1
diff -u -r1.1 RegistryImpl_Skel.java
--- gnu/java/rmi/registry/RegistryImpl_Skel.java 28 Aug 2001 00:03:22 -0000 1.1
+++ gnu/java/rmi/registry/RegistryImpl_Skel.java 1 Oct 2002 03:42:59 -0000
@@ -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: gnu/java/rmi/registry/RegistryImpl_Stub.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/registry/RegistryImpl_Stub.java,v
retrieving revision 1.1
diff -u -r1.1 RegistryImpl_Stub.java
--- gnu/java/rmi/registry/RegistryImpl_Stub.java 28 Aug 2001 00:03:22 -0000 1.1
+++ gnu/java/rmi/registry/RegistryImpl_Stub.java 1 Oct 2002 03:43:00 -0000
@@ -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;
Index: gnu/java/rmi/server/ConnectionRunnerPool.java
===================================================================
RCS file: gnu/java/rmi/server/ConnectionRunnerPool.java
diff -N gnu/java/rmi/server/ConnectionRunnerPool.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gnu/java/rmi/server/ConnectionRunnerPool.java 1 Oct 2002 03:43:00 -0000
@@ -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: gnu/java/rmi/server/RMIHashes.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/RMIHashes.java,v
retrieving revision 1.2
diff -u -r1.2 RMIHashes.java
--- gnu/java/rmi/server/RMIHashes.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/RMIHashes.java 1 Oct 2002 03:43:00 -0000
@@ -39,13 +39,56 @@
 
 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 @@
     return clazz.hashCode ();
   }
 }
+
Index: gnu/java/rmi/server/RMIObjectInputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/RMIObjectInputStream.java,v
retrieving revision 1.2
diff -u -r1.2 RMIObjectInputStream.java
--- gnu/java/rmi/server/RMIObjectInputStream.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/RMIObjectInputStream.java 1 Oct 2002 03:43:00 -0000
@@ -44,6 +44,8 @@
 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 @@
 	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: gnu/java/rmi/server/RMIObjectOutputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/RMIObjectOutputStream.java,v
retrieving revision 1.2
diff -u -r1.2 RMIObjectOutputStream.java
--- gnu/java/rmi/server/RMIObjectOutputStream.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/RMIObjectOutputStream.java 1 Oct 2002 03:43:00 -0000
@@ -41,17 +41,74 @@
 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: gnu/java/rmi/server/UnicastConnection.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/UnicastConnection.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastConnection.java
--- gnu/java/rmi/server/UnicastConnection.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/UnicastConnection.java 1 Oct 2002 03:43:00 -0000
@@ -44,6 +44,8 @@
 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 @@
 }
 
 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 @@
 		// 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 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 @@
 		// Send them my endpoint
 		dout.writeUTF(manager.serverName);
 		dout.writeInt(manager.serverPort);
+		dout.flush();
 	}
 	// Okay, ready to roll ...
 }
@@ -144,13 +150,15 @@
 }
 
 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: gnu/java/rmi/server/UnicastConnectionManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/UnicastConnectionManager.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastConnectionManager.java
--- gnu/java/rmi/server/UnicastConnectionManager.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/UnicastConnectionManager.java 1 Oct 2002 03:43:00 -0000
@@ -57,9 +57,12 @@
 	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 @@
 
 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 @@
 	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 @@
 }
 
 /**
+ * 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: gnu/java/rmi/server/UnicastRef.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/UnicastRef.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastRef.java
--- gnu/java/rmi/server/UnicastRef.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/UnicastRef.java 1 Oct 2002 03:43:00 -0000
@@ -107,6 +107,7 @@
 		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 @@
 				}
 			}
 		}
+		*/
+		// 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 @@
 
 		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 @@
 	}
 	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: gnu/java/rmi/server/UnicastServer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/UnicastServer.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastServer.java
--- gnu/java/rmi/server/UnicastServer.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/UnicastServer.java 1 Oct 2002 03:43:00 -0000
@@ -65,6 +65,13 @@
 	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 @@
 	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 @@
 
 	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: gnu/java/rmi/server/UnicastServerRef.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/rmi/server/UnicastServerRef.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastServerRef.java
--- gnu/java/rmi/server/UnicastServerRef.java 22 Jan 2002 22:40:01 -0000 1.2
+++ gnu/java/rmi/server/UnicastServerRef.java 1 Oct 2002 03:43:00 -0000
@@ -66,14 +66,15 @@
 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 @@
 		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 @@
 	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 @@
 	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 @@
 			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 @@
 				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: java/io/ObjectInputStream.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/io/ObjectInputStream.java,v
retrieving revision 1.12
diff -u -r1.12 ObjectInputStream.java
--- java/io/ObjectInputStream.java 24 Jul 2002 16:05:34 -0000 1.12
+++ java/io/ObjectInputStream.java 1 Oct 2002 03:43:02 -0000
@@ -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 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 @@
   }
 
 
+  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: java/rmi/MarshalledObject.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/rmi/MarshalledObject.java,v
retrieving revision 1.2
diff -u -r1.2 MarshalledObject.java
--- java/rmi/MarshalledObject.java 22 Jan 2002 22:40:24 -0000 1.2
+++ java/rmi/MarshalledObject.java 1 Oct 2002 03:43:03 -0000
@@ -38,24 +38,73 @@
 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");
+  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 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");
-}
-
+  
+  public int hashCode() {
+    return hash;
+  }
+  
 }
Index: java/rmi/server/RMIClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/rmi/server/RMIClassLoader.java,v
retrieving revision 1.3
diff -u -r1.3 RMIClassLoader.java
--- java/rmi/server/RMIClassLoader.java 14 Feb 2002 23:16:07 -0000 1.3
+++ java/rmi/server/RMIClassLoader.java 1 Oct 2002 03:43:03 -0000
@@ -39,21 +39,25 @@
 
 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 @@
     }
   }
 
-  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: java/rmi/server/RemoteObject.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/rmi/server/RemoteObject.java,v
retrieving revision 1.2
diff -u -r1.2 RemoteObject.java
--- java/rmi/server/RemoteObject.java 22 Jan 2002 22:40:29 -0000 1.2
+++ java/rmi/server/RemoteObject.java 1 Oct 2002 03:43:03 -0000
@@ -48,6 +48,7 @@
 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 @@
 	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 @@
 	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: java/rmi/server/UnicastRemoteObject.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/rmi/server/UnicastRemoteObject.java,v
retrieving revision 1.2
diff -u -r1.2 UnicastRemoteObject.java
--- java/rmi/server/UnicastRemoteObject.java 22 Jan 2002 22:40:29 -0000 1.2
+++ java/rmi/server/UnicastRemoteObject.java 1 Oct 2002 03:43:03 -0000
@@ -42,10 +42,17 @@
 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, 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 @@
 	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: java/security/SecureClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/security/SecureClassLoader.java,v
retrieving revision 1.7
diff -u -r1.7 SecureClassLoader.java
--- java/security/SecureClassLoader.java 24 May 2002 11:57:23 -0000 1.7
+++ java/security/SecureClassLoader.java 1 Oct 2002 03:43:03 -0000
@@ -71,7 +71,7 @@
      @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 @@
 				    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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]