summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/rmi
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/java/rmi
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/java/rmi')
-rw-r--r--libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java71
-rw-r--r--libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java78
-rw-r--r--libjava/classpath/gnu/java/rmi/activation/ActivationSystemTransient.java406
-rw-r--r--libjava/classpath/gnu/java/rmi/activation/BidiTable.java163
-rw-r--r--libjava/classpath/gnu/java/rmi/activation/DefaultActivationGroup.java159
-rw-r--r--libjava/classpath/gnu/java/rmi/activation/DefaultActivationSystem.java118
-rw-r--r--libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java182
-rw-r--r--libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java144
-rw-r--r--libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java158
-rw-r--r--libjava/classpath/gnu/java/rmi/dgc/LeaseRenewingTask.java234
-rw-r--r--libjava/classpath/gnu/java/rmi/dgc/package.html46
-rw-r--r--libjava/classpath/gnu/java/rmi/package.html46
-rw-r--r--libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java154
-rw-r--r--libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java227
-rw-r--r--libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java293
-rw-r--r--libjava/classpath/gnu/java/rmi/registry/package.html46
-rw-r--r--libjava/classpath/gnu/java/rmi/server/ActivatableRef.java179
-rw-r--r--libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java227
-rw-r--r--libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java135
-rw-r--r--libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java156
-rw-r--r--libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java62
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java357
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java59
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIHashes.java99
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java58
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java118
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java114
-rw-r--r--libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java51
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastConnection.java231
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java468
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastRef.java524
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java525
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java50
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastServer.java321
-rw-r--r--libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java481
-rw-r--r--libjava/classpath/gnu/java/rmi/server/package.html46
36 files changed, 6786 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java
new file mode 100644
index 000000000..f96310750
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java
@@ -0,0 +1,71 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * 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/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java
new file mode 100644
index 000000000..3bdf9239f
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java
@@ -0,0 +1,78 @@
+/* gnu.java.rmi.RMIMarshalledObjectOutputStream
+ Copyright (C) 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.RMIObjectOutputStream;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+/**
+ * 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);
+ locBytesStream = new ByteArrayOutputStream(256);
+ locStream = new ObjectOutputStream(locBytesStream);
+ }
+
+ //This method overrides RMIObjectOutputStream's.
+ protected void setAnnotation(String annotation) throws IOException{
+ locStream.writeObject(annotation);
+ }
+
+ public void flush() throws IOException {
+ super.flush();
+ locStream.flush();
+ }
+
+ public byte[] getLocBytes(){
+ return locBytesStream.toByteArray();
+ }
+
+} // End of RMIMarshalledObjectOutputStream
diff --git a/libjava/classpath/gnu/java/rmi/activation/ActivationSystemTransient.java b/libjava/classpath/gnu/java/rmi/activation/ActivationSystemTransient.java
new file mode 100644
index 000000000..975e13fd1
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/activation/ActivationSystemTransient.java
@@ -0,0 +1,406 @@
+/* ActivationSystemTransient.java -- The transient RMI object activation system.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.activation;
+
+import java.rmi.MarshalledObject;
+import java.rmi.RemoteException;
+import java.rmi.activation.ActivationDesc;
+import java.rmi.activation.ActivationException;
+import java.rmi.activation.ActivationGroup;
+import java.rmi.activation.ActivationGroupDesc;
+import java.rmi.activation.ActivationGroupID;
+import java.rmi.activation.ActivationID;
+import java.rmi.activation.ActivationInstantiator;
+import java.rmi.activation.ActivationMonitor;
+import java.rmi.activation.ActivationSystem;
+import java.rmi.activation.Activator;
+import java.rmi.activation.UnknownGroupException;
+import java.rmi.activation.UnknownObjectException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Provides the default transient activation system.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
+ */
+public class ActivationSystemTransient
+ extends DefaultActivationSystem
+ implements ActivationSystem, ActivationMonitor, Activator
+{
+ /**
+ * Maps group identifiers into group descriptions.
+ */
+ protected final BidiTable groupDescs;
+
+ /**
+ * Maps object identifiers into object activation descriptions
+ */
+ protected final BidiTable descriptions;
+
+ /**
+ * Maps group identifiers into already activated groups.
+ */
+ protected transient final Map groupInstantiators = new Hashtable();
+
+ /**
+ * The cache of the activated objects, maps activation ids to remote
+ * object stubs.
+ */
+ protected transient final Map activatedObjects = new HashMap();
+
+ /**
+ * The object incarnation counter.
+ */
+ static long groupIncarnations = 0;
+
+ /**
+ * The singleton of this activation system
+ */
+ static ActivationSystem singleton;
+
+ /**
+ * Set to true to print the event messages to console.
+ */
+ public static boolean debug = false;
+
+
+ /**
+ * Creates the group which uses the given maps to store the data.
+ */
+ protected ActivationSystemTransient(BidiTable objectDescriptions,
+ BidiTable groupDescriptiopns)
+ {
+ descriptions = objectDescriptions;
+ groupDescs = groupDescriptiopns;
+ }
+
+ /**
+ * Creates the group with transient maps.
+ */
+ protected ActivationSystemTransient()
+ {
+ this (new BidiTable(), new BidiTable());
+ }
+
+ public static ActivationSystem getInstance()
+ {
+ if (singleton == null)
+ singleton = new ActivationSystemTransient();
+ return singleton;
+ }
+
+ /**
+ * Activate the given object (try cache first if force = false)
+ */
+ public MarshalledObject activate(ActivationID id, boolean force)
+ throws ActivationException, UnknownObjectException, RemoteException
+ {
+ if (! force)
+ {
+ synchronized (activatedObjects)
+ {
+ MarshalledObject object = (MarshalledObject) activatedObjects.get(id);
+ if (object != null)
+ return object;
+ }
+ }
+
+ ActivationDesc desc = (ActivationDesc) descriptions.get(id);
+ if (desc == null)
+ throw new UnknownObjectException("Activating unknown object "+
+ id == null ? "null" : id.toString());
+
+ ActivationInstantiator group =
+ (ActivationInstantiator) groupInstantiators.get(desc.getGroupID());
+
+ if (group == null)
+ {
+ // The group is not active - must be activated.
+ ActivationGroupID gid = desc.getGroupID();
+ ActivationGroupDesc adesc = (ActivationGroupDesc) groupDescs.get(gid);
+
+ if (adesc == null)
+ throw new UnknownGroupException("Activating unknown group "
+ + gid + " for "+ id+" this "+this);
+
+ synchronized (ActivationSystemTransient.class)
+ {
+ groupIncarnations++;
+ }
+
+ group = ActivationGroup.createGroup(gid, adesc, groupIncarnations);
+ activeGroup(gid, group, groupIncarnations);
+ }
+
+ MarshalledObject object = group.newInstance(id, desc);
+
+ synchronized (activatedObjects)
+ {
+ activatedObjects.put(id, object);
+ }
+ return object;
+ }
+
+ /**
+ * Returns the activation monitor (THIS) and remebers the instantiator, used
+ * by that group.
+ */
+ public ActivationMonitor activeGroup(ActivationGroupID id,
+ ActivationInstantiator group,
+ long incarnation)
+ throws UnknownGroupException, ActivationException, RemoteException
+ {
+ groupInstantiators.put(id, group);
+ return this;
+ }
+
+ /**
+ * Get the activation descriptor for the given activation id.
+ *
+ * @return the activation descriptor, never null.
+ * @throws UnknownObjectException if such object is unknown.
+ */
+ public ActivationDesc getActivationDesc(ActivationID id)
+ throws ActivationException, UnknownObjectException, RemoteException
+ {
+ ActivationDesc desc = (ActivationDesc) descriptions.get(id);
+ if (desc == null)
+ throw new UnknownObjectException("No desc for "+
+ id == null ? "null" : id.toString());
+ return desc;
+ }
+
+ /**
+ * Get the descriptor of the given activation group.
+ *
+ * @return the activation group descriptor, never null.
+ * @throws UnknownGroupException if such group is unknown
+ */
+ public ActivationGroupDesc getActivationGroupDesc(ActivationGroupID groupId)
+ throws ActivationException, UnknownGroupException, RemoteException
+ {
+ ActivationGroupDesc desc = (ActivationGroupDesc) groupDescs.get(groupId);
+ if (desc == null)
+ throw new UnknownGroupException(groupId == null ? "null"
+ : groupId.toString());
+ return desc;
+ }
+
+ /**
+ * Create the activation group id and put this id-descriptor combination into
+ * the group map. The new ID will only be created if this description has not
+ * already been registered, otherwise the id of the registered description
+ * will be returned.
+ */
+ public ActivationGroupID registerGroup(ActivationGroupDesc groupDesc)
+ throws ActivationException, RemoteException
+ {
+ ActivationGroupID id = (ActivationGroupID) groupDescs.getKey(groupDesc);
+ if (id == null)
+ {
+ id = new ActivationGroupID(this);
+ groupDescs.put(id, groupDesc);
+ }
+ if (debug)
+ System.out.println("Register group " + id +":"+groupDesc+" this "+this);
+
+ return id;
+ }
+
+ /**
+ * Create the object activation id and put this id-descriptor combination into
+ * the group map. The new ID will only be created if this description has not
+ * already been registered, otherwise the id of the registered description
+ * will be returned.
+ */
+ public ActivationID registerObject(ActivationDesc desc)
+ throws ActivationException, UnknownGroupException, RemoteException
+ {
+ ActivationID id = (ActivationID) descriptions.getKey(desc);
+ if (id == null)
+ {
+ id = new ActivationID(this);
+ descriptions.put(id, desc);
+ }
+
+ if (debug)
+ System.out.println("Register object " + id +":"+desc+" this "+this);
+
+ return id;
+ }
+
+ /**
+ * Replace the activation descriptor, return the previous descriptor.
+ */
+ public ActivationDesc setActivationDesc(ActivationID id, ActivationDesc desc)
+ throws ActivationException, UnknownObjectException,
+ UnknownGroupException, RemoteException
+ {
+ ActivationDesc prev = getActivationDesc(id);
+ descriptions.put(id, desc);
+ return prev;
+ }
+
+ /**
+ * Replace the activation group descriptor, return the previous descriptor.
+ */
+ public ActivationGroupDesc setActivationGroupDesc(
+ ActivationGroupID groupId,
+ ActivationGroupDesc groupDesc)
+ throws ActivationException, UnknownGroupException, RemoteException
+ {
+ ActivationGroupDesc prev = getActivationGroupDesc(groupId);
+ groupDescs.put(groupId, groupDesc);
+ return prev;
+ }
+
+ /**
+ * Calls .shutdown on all bidirectional tables (has no effect if these
+ * table are not persistent).
+ */
+ public void shutdown() throws RemoteException
+ {
+ descriptions.shutdown();
+ groupDescs.shutdown();
+ }
+
+ /**
+ * Remove the group from the group map
+ */
+ public void unregisterGroup(ActivationGroupID groupId) throws ActivationException,
+ UnknownGroupException, RemoteException
+ {
+ if (! groupDescs.containsKey(groupId))
+ throw new UnknownGroupException("Unknown group "+groupId);
+
+ groupDescs.removeKey(groupId);
+ groupInstantiators.remove(groupId);
+ }
+
+ /**
+ * Remove the object id from the active object and description maps.
+ */
+ public void unregisterObject(ActivationID id) throws ActivationException,
+ UnknownObjectException, RemoteException
+ {
+ if (! descriptions.containsKey(id))
+ throw new UnknownObjectException("Unregistering unknown object");
+ descriptions.removeKey(id);
+
+ synchronized (activatedObjects)
+ {
+ activatedObjects.remove(id);
+ }
+ }
+
+ /**
+ * Put the object into active object map.
+ */
+ public void activeObject(ActivationID id, MarshalledObject obj)
+ throws UnknownObjectException, RemoteException
+ {
+ if (! descriptions.containsKey(id))
+ throw new UnknownObjectException("Activating unknown object "+
+ id+" this "+this);
+ try
+ {
+ synchronized (activatedObjects)
+ {
+ activatedObjects.put(id, obj.get());
+ }
+ }
+ catch (RemoteException e)
+ {
+ throw e;
+ }
+ catch (Exception e)
+ {
+ UnknownObjectException un = new UnknownObjectException(
+ "Cannot get Remote for MarshalledObject of "+id);
+ un.detail = e;
+ throw un;
+ }
+ }
+
+ /**
+ * Check if the group is known. Remove all active objects, belonging to
+ * that group, from the active object cache.
+ */
+ public void inactiveGroup(ActivationGroupID groupId, long incarnation)
+ throws UnknownGroupException, RemoteException
+ {
+ if (! groupInstantiators.containsKey(groupId))
+ throw new UnknownGroupException("Inactivating unkwnon group");
+
+ groupInstantiators.remove(groupId);
+
+ // Remove all members of this group from the cache.
+ synchronized (activatedObjects)
+ {
+ Iterator iter = activatedObjects.keySet().iterator();
+ ActivationID id;
+ ActivationDesc desc;
+ while (iter.hasNext())
+ {
+ id = (ActivationID) iter.next();
+ desc = (ActivationDesc) descriptions.get(id);
+ if (desc.getGroupID().equals(groupId))
+ activatedObjects.remove(id);
+ }
+ }
+ }
+
+ /**
+ * Removes this id from the active object cache.
+ */
+ public void inactiveObject(ActivationID id) throws UnknownObjectException,
+ RemoteException
+ {
+ if (! descriptions.containsKey(id))
+ throw new UnknownObjectException("Inactivating unknown object");
+
+ synchronized (activatedObjects)
+ {
+ activatedObjects.remove(id);
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/activation/BidiTable.java b/libjava/classpath/gnu/java/rmi/activation/BidiTable.java
new file mode 100644
index 000000000..ed9d9595a
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/activation/BidiTable.java
@@ -0,0 +1,163 @@
+/* BidiHasthable.java -- Bidirectional hash table.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.activation;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * The bidirectional hash table, maps both a to b and b to a.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
+ */
+public class BidiTable
+{
+ /**
+ * Use serialVerionUID for interoperability.
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Maps keys to values
+ */
+ protected Map k2v;
+
+ /**
+ * Maps values to keys (in reverse)
+ */
+ protected Map v2k;
+
+ /**
+ * Create a new table that is ready to use.
+ */
+ public BidiTable()
+ {
+ k2v = new HashMap();
+ v2k = new HashMap();
+ }
+
+ /**
+ * Create a new instance where the hashtable fields are not initialised
+ * (called from derivatives that intialise hashtables in they own way.
+ *
+ * @param flags currently used to mark the different constructor only.
+ */
+ protected BidiTable(int flags)
+ {
+ }
+
+ /**
+ * Get key by value
+ */
+ public synchronized Object getKey(Object value)
+ {
+ return v2k.get(value);
+ }
+
+ /**
+ * Put key-value pair.
+ */
+ public synchronized void put(Object key, Object value)
+ {
+ k2v.put(key, value);
+ v2k.put(value, key);
+ }
+
+ /**
+ * Get value from key
+ */
+ public synchronized Object get(Object key)
+ {
+ return k2v.get(key);
+ }
+
+ /**
+ * Remove the key-value pair by key
+ */
+ public synchronized void removeKey(Object key)
+ {
+ Object value = k2v.get(key);
+ if (value!=null)
+ {
+ k2v.remove(key);
+ v2k.remove(value);
+ }
+ }
+
+ /**
+ * Check if the table contains this key.
+ */
+ public synchronized boolean containsKey(Object key)
+ {
+ return k2v.containsKey(key);
+ }
+
+ /**
+ * This method is called before exit and may be used to write the database
+ * to the disk. The default method does nothing.
+ */
+ public synchronized void shutdown()
+ {
+ }
+
+ /**
+ * Get the size.
+ */
+ public synchronized int size()
+ {
+ return k2v.size();
+ }
+
+ /**
+ * Get the key collection.
+ */
+ public synchronized Object[] keys()
+ {
+ Collection keys = k2v.keySet();
+ Object[] k = new Object[keys.size()];
+
+ Iterator iter = keys.iterator();
+ for (int i = 0; i < k.length; i++)
+ k[i] = iter.next();
+
+ return k;
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/activation/DefaultActivationGroup.java b/libjava/classpath/gnu/java/rmi/activation/DefaultActivationGroup.java
new file mode 100644
index 000000000..526d2ef40
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/activation/DefaultActivationGroup.java
@@ -0,0 +1,159 @@
+/* DefaultActivationGroup.java -- Default activation group.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.activation;
+
+import gnu.java.rmi.server.ActivatableServerRef;
+import gnu.java.rmi.server.UnicastServer;
+
+import java.lang.reflect.Constructor;
+import java.rmi.MarshalledObject;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.activation.ActivationDesc;
+import java.rmi.activation.ActivationException;
+import java.rmi.activation.ActivationGroup;
+import java.rmi.activation.ActivationGroupID;
+import java.rmi.activation.ActivationID;
+import java.rmi.activation.UnknownObjectException;
+
+/**
+ * The default activation group class. This activation group assumes that
+ * all classes are accessible via current thread context class loader.
+ * The remote class loading is not supported for security reasons. The
+ * activation always occurs in the current jre.
+ *
+ * @author Audrius Meskauskas (audriusa@Bioinformatics.org)
+ */
+public class DefaultActivationGroup
+ extends ActivationGroup
+{
+ /**
+ * Use the serialVersionUID for interoperability.
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Used during the group creation (required constructor).
+ */
+ static final Class[] cConstructorTypes = new Class[]
+ {
+ ActivationID.class,
+ MarshalledObject.class
+ };
+
+
+ /**
+ * Create the new default activation group.
+ *
+ * @param id the group activation id.
+ * @param data may contain the group initialization data (unused and can be
+ * null)
+ * @throws RemoteException if the super constructor does
+ */
+ public DefaultActivationGroup(ActivationGroupID id, MarshalledObject data)
+ throws RemoteException
+ {
+ super(id);
+ }
+
+
+ /**
+ * May be overridden and used as a hook. This method is called each time
+ * the new object is instantiated.
+ */
+ public void activeObject(ActivationID id, Remote obj)
+ throws ActivationException, UnknownObjectException, RemoteException
+ {
+ // Nothing to do (the monitor is already notified in newInstance)
+ }
+
+ /**
+ * Create the new instance of the object, using the class name and location
+ * information, stored in the passed descriptor. The method expects the object
+ * class to have the two parameter constructor, the first parameter being the
+ * {@link ActivationID} and the second the {@link MarshalledObject}.
+ *
+ * @param id the object activation id
+ * @param desc the activation descriptor, providing the information, necessary
+ * to create and activate the object
+ * @return the marshalled object, containing the exported stub of the created
+ * object
+ * @throws ActivationException if the activation fails due any reason
+ */
+ public MarshalledObject newInstance(ActivationID id, ActivationDesc desc)
+ throws ActivationException, RemoteException
+ {
+ try
+ {
+ if (ActivationSystemTransient.debug)
+ System.out.println("Instantiating "+desc.getClassName());
+
+ Remote object;
+ Class objectClass;
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ objectClass = loader.loadClass(desc.getClassName());
+ Constructor constructor = objectClass.getConstructor(cConstructorTypes);
+ object = (Remote) constructor.newInstance(
+ new Object[] { id, desc.getData() });
+
+ // Make the object accessible and create the stub.
+ ActivatableServerRef ref = UnicastServer.getActivatableRef(id);
+ Remote stub = ref.exportObject(object);
+
+ MarshalledObject marsh = new MarshalledObject(stub);
+
+ // Notify the activation monitor.
+ activeObject(id, marsh);
+
+ // Make call to the hook that may be overridden.
+ activeObject(id, stub);
+
+ return marsh;
+ }
+ catch (Exception e)
+ {
+ ActivationException acex = new ActivationException(
+ "Unable to activate "+ desc.getClassName()
+ + " from "+ desc.getLocation(), e);
+ throw acex;
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/activation/DefaultActivationSystem.java b/libjava/classpath/gnu/java/rmi/activation/DefaultActivationSystem.java
new file mode 100644
index 000000000..3d1625052
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/activation/DefaultActivationSystem.java
@@ -0,0 +1,118 @@
+/* DefaultActivationSystem.java -- Default RMI activation system
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.activation;
+
+import java.rmi.activation.ActivationSystem;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+
+/**
+ * Finds and returns the default activation system for this jre.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
+ */
+public abstract class DefaultActivationSystem
+{
+ /**
+ * The activation system (assigned if once found).
+ */
+ static ActivationSystem system;
+
+ /**
+ * The default activation registry port.
+ */
+ static int ACTIVATION_REGISTRY_PORT;
+
+ /**
+ * The name of the activation system registry port property.
+ */
+ static String AS_PORT_PROPERTY = "java.rmi.activation.port";
+
+ /**
+ * The defalut name of the activation system in the activation registry.
+ */
+ static String ACTIVATION_SYSTEM_NAME = "java.rmi.activation.ActivationSystem";
+
+ /**
+ * Get the activation system, default for this jre. If no external activation
+ * system exists, the internal activation system will be activated. This
+ * internal system is limited in capabilities and should be used exclusively
+ * for automated testing, to avoid necessity of starting rmi daemon during
+ * testing process.
+ */
+ public static ActivationSystem get()
+ {
+ if (system == null)
+ try
+ {
+ // Obtain the port:
+ String asr = System.getProperty("java.rmi.activation.port");
+
+ if (asr != null)
+ {
+ try
+ {
+ ACTIVATION_REGISTRY_PORT = Integer.parseInt(asr);
+ if (ACTIVATION_REGISTRY_PORT <= 0)
+ throw new InternalError("Invalid " + asr + " value, "
+ + ACTIVATION_REGISTRY_PORT);
+ }
+ catch (NumberFormatException e)
+ {
+ throw new InternalError("Unable to parse " + asr
+ + " to integer");
+ }
+ }
+ else
+ ACTIVATION_REGISTRY_PORT = ActivationSystem.SYSTEM_PORT;
+
+ // Expect the naming service running first.
+ // The local host may want to use the shared registry
+ Registry r = LocateRegistry.getRegistry(ACTIVATION_REGISTRY_PORT);
+ ActivationSystem system = (ActivationSystem) r.lookup(ACTIVATION_SYSTEM_NAME);
+ return system;
+ }
+ catch (Exception ex)
+ {
+ system = ActivationSystemTransient.getInstance();
+ }
+
+ return system;
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java
new file mode 100644
index 000000000..5efbf2796
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl.java
@@ -0,0 +1,182 @@
+/* DGCImpl.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.dgc;
+
+import gnu.java.rmi.server.UnicastServer;
+import gnu.java.rmi.server.UnicastServerRef;
+
+import java.rmi.RemoteException;
+import java.rmi.dgc.DGC;
+import java.rmi.dgc.Lease;
+import java.rmi.dgc.VMID;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMISocketFactory;
+import java.util.Collection;
+import java.util.TimerTask;
+
+/**
+ * The DGC implementation is used for the server side during the distributed
+ * garbage collection. This interface contains the two methods: dirty and clean.
+ * A dirty call is made when a remote reference is unmarshaled in a client. A
+ * corresponding clean call is made by client it no longer uses that remote
+ * reference. A reference to a remote object is also automatically released
+ * after so called lease period that starts after the dirty call is received. It
+ * is the client's responsibility to renew the leases, by making additional
+ * dirty calls before such leases expire.
+ */
+public class DGCImpl
+ extends UnicastServerRef
+ implements DGC
+{
+ /*
+ * The DGCImpl extends UnicastServerRef and not UnicastRemoteObject, because
+ * UnicastRemoteObject must exportObject automatically.
+ */
+
+ /**
+ * Use the serial version UID for interoperability.
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * Protects the array of object Id's for the scheduled period of time
+ * (lease). After the time expires, the protector is automatically discarded,
+ * making the references unprotected and hence applicable for the garbage
+ * collection.
+ */
+ class RefProtector extends TimerTask
+ {
+ /**
+ * The corresponding server references to protect. Each Id may contain
+ * multiple references that are stored to collection.
+ */
+ Collection[] references;
+
+ /**
+ * Create the new instance of the reference protector that protects the
+ * given array of ids and exists for the given period of time.
+ *
+ * @param ids the ids to protect.
+ */
+ RefProtector(ObjID[] ids, long timeToLive)
+ {
+ references = new Collection[ids.length];
+ for (int i = 0; i < ids.length; i++)
+ {
+ references[i] = UnicastServer.getExported(ids[i]);
+ }
+
+ // Schedule the existence.
+ LeaseRenewingTask.timer.schedule(this, timeToLive);
+ }
+
+ /**
+ * Break all links, ensuring easy collection of the references by the gc.
+ */
+ public void run()
+ {
+ for (int i = 0; i < references.length; i++)
+ {
+ references[i].clear();
+ references[i] = null;
+ }
+ }
+ }
+
+ /**
+ * This defauld lease value is used if the lease value, passed to the
+ * {@link #dirty} is equal to zero.
+ */
+ static final long LEASE_VALUE = 600000L;
+
+ /**
+ * Create the new DGC implementation.
+ *
+ * @throws RemoteException if the super constructor throws or the
+ * socket factory fails.
+ */
+ public DGCImpl() throws RemoteException
+ {
+ super(new ObjID(ObjID.DGC_ID), 0, RMISocketFactory.getSocketFactory());
+ }
+
+ /**
+ * Mark the given objects referecnes as used on the client side.
+ *
+ * @param ids the ids of the used objects.
+ * @param sequenceNum the number of the call (used to detect and discard late
+ * calls).
+ * @param lease the requested lease
+ * @return the granted lease
+ */
+ public Lease dirty(ObjID[] ids, long sequenceNum, Lease lease)
+ throws RemoteException
+ {
+ // We do not fill in VMID because in this implementation it is not used.
+ long leaseValue = lease.getValue();
+
+ // Grant the maximal default lease time if the passed value is zero.
+ if (leaseValue <= 0)
+ leaseValue = LEASE_VALUE;
+
+ // Create (and shedule of the given existence) the new reference
+ // protector.
+ new RefProtector(ids, leaseValue);
+
+ lease = new Lease(lease.getVMID(), leaseValue);
+ return lease;
+ }
+
+ /**
+ * Mark the given objects as no longer used on the client side.
+ *
+ * @param ids the ids of the objects that are no longer used.
+ * @param sequenceNum the number of the call (used to detect and discard late
+ * calls)
+ * @param vmid the VMID of the client.
+ * @param strong make the "strong" clean call.
+ */
+ public void clean(ObjID[] ids, long sequenceNum, VMID vmid, boolean strong)
+ throws RemoteException
+ {
+ // Not implemented
+ // TODO implement
+ }
+
+} // End of DGCImpl
diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java
new file mode 100644
index 000000000..a40b48ca0
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Skel.java
@@ -0,0 +1,144 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+public final class DGCImpl_Skel
+ implements java.rmi.server.Skeleton
+{
+ private static final long interfaceHash = -669196253586618813L;
+
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean"),
+ new java.rmi.server.Operation("java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease")
+ };
+
+ public java.rmi.server.Operation[] getOperations() {
+ return ((java.rmi.server.Operation[]) operations.clone());
+ }
+
+ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {
+ if (opnum < 0) {
+ if (hash == -5803803475088455571L) {
+ opnum = 0;
+ }
+ else if (hash == -8139341527526761862L) {
+ opnum = 1;
+ }
+ else {
+ throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
+ }
+ }
+ else if (hash != interfaceHash) {
+ throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
+ }
+
+ gnu.java.rmi.dgc.DGCImpl server = (gnu.java.rmi.dgc.DGCImpl)obj;
+ switch (opnum) {
+ case 0:
+ {
+ java.rmi.server.ObjID[] $param_0;
+ long $param_1;
+ java.rmi.dgc.VMID $param_2;
+ boolean $param_3;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.rmi.server.ObjID[])in.readObject();
+ $param_1 = (long)in.readLong();
+ $param_2 = (java.rmi.dgc.VMID)in.readObject();
+ $param_3 = (boolean)in.readBoolean();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ server.clean($param_0, $param_1, $param_2, $param_3);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 1:
+ {
+ java.rmi.server.ObjID[] $param_0;
+ long $param_1;
+ java.rmi.dgc.Lease $param_2;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.rmi.server.ObjID[])in.readObject();
+ $param_1 = (long)in.readLong();
+ $param_2 = (java.rmi.dgc.Lease)in.readObject();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ java.rmi.dgc.Lease $result = server.dirty($param_0, $param_1, $param_2);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ out.writeObject($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ default:
+ throw new java.rmi.UnmarshalException("invalid method number");
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java
new file mode 100644
index 000000000..dac8b6f4c
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java
@@ -0,0 +1,158 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+public final class DGCImpl_Stub
+ extends java.rmi.server.RemoteStub
+ implements java.rmi.dgc.DGC
+{
+ private static final long serialVersionUID = 2L;
+
+ private static final long interfaceHash = -669196253586618813L;
+
+ private static boolean useNewInvoke;
+
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)"),
+ new java.rmi.server.Operation("java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)")
+ };
+
+ private static java.lang.reflect.Method $method_clean_0;
+ private static java.lang.reflect.Method $method_dirty_1;
+
+ static {
+ try {
+ java.rmi.server.RemoteRef.class.getMethod("invoke", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class });
+ useNewInvoke = true;
+ $method_clean_0 = gnu.java.rmi.dgc.DGCImpl.class.getMethod("clean", new java.lang.Class[] {java.rmi.server.ObjID[].class, long.class, java.rmi.dgc.VMID.class, boolean.class});
+ $method_dirty_1 = gnu.java.rmi.dgc.DGCImpl.class.getMethod("dirty", new java.lang.Class[] {java.rmi.server.ObjID[].class, long.class, java.rmi.dgc.Lease.class});
+
+ }
+ catch (java.lang.NoSuchMethodException e) {
+ useNewInvoke = false;
+ }
+ }
+
+ public DGCImpl_Stub() {
+ super();
+ }
+ public DGCImpl_Stub(java.rmi.server.RemoteRef ref) {
+ super(ref);
+ }
+
+ public void clean(java.rmi.server.ObjID[] $param_0, long $param_1, java.rmi.dgc.VMID $param_2, boolean $param_3) throws java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ ref.invoke(this, $method_clean_0, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2, Boolean.valueOf($param_3)}, -5803803475088455571L);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 0, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ out.writeLong($param_1);
+ out.writeObject($param_2);
+ out.writeBoolean($param_3);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ public java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[] $param_0, long $param_1, java.rmi.dgc.Lease $param_2) throws java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ java.lang.Object $result = ref.invoke(this, $method_dirty_1, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2}, -8139341527526761862L);
+ return ((java.rmi.dgc.Lease)$result);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 1, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ out.writeLong($param_1);
+ out.writeObject($param_2);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ java.rmi.dgc.Lease $result;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $result = (java.rmi.dgc.Lease)in.readObject();
+ return ($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/dgc/LeaseRenewingTask.java b/libjava/classpath/gnu/java/rmi/dgc/LeaseRenewingTask.java
new file mode 100644
index 000000000..7995af744
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/dgc/LeaseRenewingTask.java
@@ -0,0 +1,234 @@
+/* LeaseRenewingTask.java -- The task to renew the lease.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.dgc;
+
+import gnu.java.rmi.server.UnicastRef;
+
+import java.lang.ref.WeakReference;
+import java.rmi.dgc.Lease;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.WeakHashMap;
+
+/**
+ * The task to renew the lease to some object reference. The UnicastRef
+ * being renewed is stored as a weak reference. So the presence of the
+ * sheduled task does not prevent it from being garbage collected. If the
+ * reference has not been garbage collected, the task is resheduled after
+ * the lease is renewed.
+ *
+ * @author Audrius Meskauskas (Audriusa@Bioinformatics.org)
+ */
+public class LeaseRenewingTask
+{
+ /**
+ * The sheduled timer task to call the renew() method.
+ */
+ class LeaseTimerTask extends TimerTask
+ {
+ public void run()
+ {
+ renew();
+ }
+ }
+
+ /**
+ * The default requested lease duration time (one minute by default).
+ */
+ public static long REQUEST_LEASE_DURATION = 60000;
+
+ /**
+ * The reference to the UnicastRef that must renew its lease until not
+ * garbage collected. The different members of this list may point to the
+ * different instances of the UnicastRef's, but these references are
+ * pointing to the same remote object (they .equals() returns
+ * true when comparing with each other). Using LinkedList to make
+ * frequent deletions from the middle easy.
+ */
+ LinkedList ref = new LinkedList();
+
+ /**
+ * The granted (or supposed) lease.
+ */
+ Lease lease = new Lease(null, REQUEST_LEASE_DURATION);
+
+ /**
+ * The timer, shared by all lease renewing tasks. The same instance is also
+ * used for the reference protector discarding in DGCImpl.
+ */
+ static Timer timer = new Timer(true);
+
+ /**
+ * Maps the UnicastRef to its renewing task.
+ */
+ static WeakHashMap existingTasks = new WeakHashMap();
+
+ /**
+ * Creates the lease renewing task that renews the lease of the given
+ * UnicastRef until it is not collected. This constructor requests the lease
+ * value from the server and schedules the lease renewal action.
+ *
+ * @param renewIt the reference that must be renewed.
+ */
+ public LeaseRenewingTask(UnicastRef renewIt)
+ {
+ lease = notifyDGC(renewIt);
+ if (lease != null)
+ {
+ schedule(lease);
+ ref.add(new WeakReference(renewIt));
+ }
+ }
+
+ /**
+ * Schedule periodic leases for the given UnicastRef reference.
+ *
+ * @param renewIt the reference, for that the leases must be scheduled.
+ */
+ public static void scheduleLeases(UnicastRef renewIt)
+ {
+ // No need to schedule leases for null.
+ if (renewIt == null)
+ return;
+ try {
+ synchronized (existingTasks)
+ {
+ // Check maybe the task for refreshing this remote object already
+ // exists.
+ LeaseRenewingTask task = (LeaseRenewingTask) existingTasks.get(renewIt);
+
+ if (task != null)
+ {
+ // Extend the reference list only. The scheduling must be
+ // alredy done with the previous lease.
+ synchronized (task.ref)
+ {
+ task.ref.add(new WeakReference(renewIt));
+ }
+ }
+ else
+ existingTasks.put(renewIt, new LeaseRenewingTask(renewIt));
+ }
+ }
+ catch (Exception ex)
+ {
+ InternalError ierr = new InternalError("Lease for "+renewIt);
+ ierr.initCause(ex);
+ throw ierr;
+ }
+ }
+
+ /**
+ * Shedule the renewing call, taking into consideration that the following
+ * lease was granted.
+ *
+ * @param lease the lease that was granted.
+ */
+ public void schedule(Lease lease)
+ {
+ long value = lease.getValue();
+
+ // Shedule a 10 % earlier because some time is needed for the message
+ // to reach the server.
+ long reduced = (value * 90)/100;
+ if (reduced == 0)
+ reduced = value;
+
+ timer.schedule(new LeaseTimerTask(), reduced);
+ }
+
+ /**
+ * Renew the lease.
+ */
+ public void renew()
+ {
+ Object renewIt = null;
+ // Iterate throw the list of associated references. If all are
+ // discarded, there is no need to renew.
+ synchronized (ref)
+ {
+ Iterator iter = ref.iterator();
+ WeakReference w;
+ while (iter.hasNext() && renewIt == null)
+ {
+ w = (WeakReference) iter.next();
+ renewIt = w.get();
+ if (renewIt == null)
+ // Discard the weak reference if its target has been garbage
+ // collected.
+ iter.remove();
+ }
+ }
+
+ if (renewIt!=null)
+ {
+ Lease lease = notifyDGC( (UnicastRef) renewIt);
+
+ // Schedule the next renewing session.
+ if (lease!=null)
+ schedule(lease);
+ }
+ {
+ // All references collected - discard this entry.
+ }
+ }
+
+ /**
+ * Notify DGC that we still hold this reference.
+ *
+ * @param renewIt the reference we still have (must not be null).
+ */
+ public Lease notifyDGC(UnicastRef renewIt)
+ {
+ try
+ {
+ return renewIt.notifyDGC(lease);
+ }
+ catch (Exception e)
+ {
+ // Failed to notify.
+ // TODO Take some relevant action in the case if we failed
+ // to notify the remote object owner.
+ return null;
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/dgc/package.html b/libjava/classpath/gnu/java/rmi/dgc/package.html
new file mode 100644
index 000000000..3ed81cfdd
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/dgc/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.rmi.dgc package.
+ Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.rmi.dgc</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/rmi/package.html b/libjava/classpath/gnu/java/rmi/package.html
new file mode 100644
index 000000000..53b5f5e57
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.rmi package.
+ Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.rmi</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java
new file mode 100644
index 000000000..acdd463b1
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl.java
@@ -0,0 +1,154 @@
+/* RegistryImpl.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005, 2008, 2009, 2010, 2011
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.registry;
+
+import gnu.java.rmi.server.UnicastServerRef;
+
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+public class RegistryImpl
+ extends UnicastRemoteObject implements Registry {
+
+private Hashtable bindings = new Hashtable();
+
+public RegistryImpl(int port) throws RemoteException {
+ this(port, RMISocketFactory.getSocketFactory(), RMISocketFactory.getSocketFactory());
+}
+
+public RegistryImpl(int port, RMIClientSocketFactory cf, RMIServerSocketFactory sf) throws RemoteException {
+ super(new UnicastServerRef(new ObjID(ObjID.REGISTRY_ID), port, sf));
+ // The following is unnecessary, because UnicastRemoteObject export itself automatically.
+ //((UnicastServerRef)getRef()).exportObject(this);
+}
+
+public Remote lookup(String name) throws RemoteException, NotBoundException, AccessException {
+ Object obj = bindings.get(name);
+ if (obj == null) {
+ throw new NotBoundException(name);
+ }
+ return ((Remote)obj);
+}
+
+public void bind(String name, Remote obj) throws RemoteException, AlreadyBoundException, AccessException {
+ if (bindings.containsKey(name)) {
+ throw new AlreadyBoundException(name);
+ }
+ bindings.put(name, obj);
+}
+
+public void unbind(String name) throws RemoteException, NotBoundException, AccessException {
+ Object obj = bindings.remove(name);
+ if (obj == null) {
+ throw new NotBoundException(name);
+ }
+}
+
+public void rebind(String name, Remote obj) throws RemoteException, AccessException {
+ bindings.put(name, obj);
+}
+
+public String[] list() throws RemoteException, AccessException {
+ int size = bindings.size();
+ String[] strings = new String[size];
+ Enumeration e = bindings.keys();
+ for (int i = 0; i < size; i++) {
+ strings[i] = (String)e.nextElement();
+ }
+ return (strings);
+}
+
+public static void version() {
+ System.out.println("rmiregistry ("
+ + System.getProperty("java.vm.name")
+ + ") "
+ + System.getProperty("java.vm.version"));
+ System.out.println("Copyright 2011 Free Software Foundation, Inc.");
+ System.out.println("This is free software; see the source for copying conditions. There is NO");
+ System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
+ System.exit(0);
+}
+
+public static void help() {
+ System.out.println(
+"Usage: rmiregistry [OPTION | PORT]\n" +
+"\n" +
+" --help Print this help, then exit\n" +
+" --version Print version number, then exit\n");
+ System.exit(0);
+}
+
+public static void main(String[] args) {
+ int port = Registry.REGISTRY_PORT;
+ if (args.length > 0) {
+ if (args[0].equals("--version")) {
+ version();
+ }
+ else if (args[0].equals("--help")) {
+ help();
+ }
+ try {
+ port = Integer.parseInt(args[0]);
+ }
+ catch (NumberFormatException _) {
+ System.err.println("Bad port number - using default");
+ }
+ }
+
+ try {
+ Registry impl = LocateRegistry.createRegistry(port);
+ }
+ catch (RemoteException _) {
+ System.err.println("Registry failed");
+ }
+}
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java
new file mode 100644
index 000000000..defa3bf61
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Skel.java
@@ -0,0 +1,227 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+public final class RegistryImpl_Skel
+ implements java.rmi.server.Skeleton
+{
+ private static final long interfaceHash = 4905912898345647071L;
+
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote"),
+ new java.rmi.server.Operation("java.lang.String[] list("),
+ new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String"),
+ new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote"),
+ new java.rmi.server.Operation("void unbind(java.lang.String")
+ };
+
+ public java.rmi.server.Operation[] getOperations() {
+ return ((java.rmi.server.Operation[]) operations.clone());
+ }
+
+ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {
+ if (opnum < 0) {
+ if (hash == 7583982177005850366L) {
+ opnum = 0;
+ }
+ else if (hash == 2571371476350237748L) {
+ opnum = 1;
+ }
+ else if (hash == -7538657168040752697L) {
+ opnum = 2;
+ }
+ else if (hash == -8381844669958460146L) {
+ opnum = 3;
+ }
+ else if (hash == 7305022919901907578L) {
+ opnum = 4;
+ }
+ else {
+ throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
+ }
+ }
+ else if (hash != interfaceHash) {
+ throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
+ }
+
+ gnu.java.rmi.registry.RegistryImpl server = (gnu.java.rmi.registry.RegistryImpl)obj;
+ switch (opnum) {
+ case 0:
+ {
+ java.lang.String $param_0;
+ java.rmi.Remote $param_1;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.lang.String)in.readObject();
+ $param_1 = (java.rmi.Remote)in.readObject();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ server.bind($param_0, $param_1);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 1:
+ {
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ java.lang.String[] $result = server.list();
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ out.writeObject($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 2:
+ {
+ java.lang.String $param_0;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.lang.String)in.readObject();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ java.rmi.Remote $result = server.lookup($param_0);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ out.writeObject($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 3:
+ {
+ java.lang.String $param_0;
+ java.rmi.Remote $param_1;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.lang.String)in.readObject();
+ $param_1 = (java.rmi.Remote)in.readObject();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ server.rebind($param_0, $param_1);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 4:
+ {
+ java.lang.String $param_0;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_0 = (java.lang.String)in.readObject();
+
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ catch (java.lang.ClassCastException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ }
+ finally {
+ call.releaseInputStream();
+ }
+ server.unbind($param_0);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ default:
+ throw new java.rmi.UnmarshalException("invalid method number");
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java
new file mode 100644
index 000000000..786a5e180
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java
@@ -0,0 +1,293 @@
+/* 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+public final class RegistryImpl_Stub
+ extends java.rmi.server.RemoteStub
+ implements java.rmi.registry.Registry
+{
+ private static final long serialVersionUID = 2L;
+
+ private static final long interfaceHash = 4905912898345647071L;
+
+ private static boolean useNewInvoke;
+
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("java.lang.String[] list()"),
+ new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"),
+ new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("void unbind(java.lang.String)")
+ };
+
+ private static java.lang.reflect.Method $method_bind_0;
+ private static java.lang.reflect.Method $method_list_1;
+ private static java.lang.reflect.Method $method_lookup_2;
+ private static java.lang.reflect.Method $method_rebind_3;
+ private static java.lang.reflect.Method $method_unbind_4;
+
+ static {
+ try {
+ java.rmi.server.RemoteRef.class.getMethod("invoke", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class });
+ useNewInvoke = false;
+ $method_bind_0 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("bind", new java.lang.Class[] {java.lang.String.class, java.rmi.Remote.class});
+ $method_list_1 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("list", new java.lang.Class[] {});
+ $method_lookup_2 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("lookup", new java.lang.Class[] {java.lang.String.class});
+ $method_rebind_3 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("rebind", new java.lang.Class[] {java.lang.String.class, java.rmi.Remote.class});
+ $method_unbind_4 = gnu.java.rmi.registry.RegistryImpl.class.getMethod("unbind", new java.lang.Class[] {java.lang.String.class});
+
+ }
+ catch (java.lang.NoSuchMethodException e) {
+ useNewInvoke = false;
+ }
+ }
+
+ public RegistryImpl_Stub() {
+ super();
+ }
+ public RegistryImpl_Stub(java.rmi.server.RemoteRef ref) {
+ super(ref);
+ }
+
+ public void bind(java.lang.String $param_0, java.rmi.Remote $param_1) throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ ref.invoke(this, $method_bind_0, new java.lang.Object[] {$param_0, $param_1}, 7583982177005850366L);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 0, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ out.writeObject($param_1);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.AccessException e) {
+ throw e;
+ }
+ catch (java.rmi.AlreadyBoundException e) {
+ throw e;
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ public java.lang.String[] list() throws java.rmi.AccessException, java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ java.lang.Object $result = ref.invoke(this, $method_list_1, null, 2571371476350237748L);
+ return ((java.lang.String[])$result);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 1, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ java.lang.String[] $result;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $result = (java.lang.String[])in.readObject();
+ return ($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.AccessException e) {
+ throw e;
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ public java.rmi.Remote lookup(java.lang.String $param_0) throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ java.lang.Object $result = ref.invoke(this, $method_lookup_2, new java.lang.Object[] {$param_0}, -7538657168040752697L);
+ return ((java.rmi.Remote)$result);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 2, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ java.rmi.Remote $result;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $result = (java.rmi.Remote)in.readObject();
+ return ($result);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.AccessException e) {
+ throw e;
+ }
+ catch (java.rmi.NotBoundException e) {
+ throw e;
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ public void rebind(java.lang.String $param_0, java.rmi.Remote $param_1) throws java.rmi.AccessException, java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ ref.invoke(this, $method_rebind_3, new java.lang.Object[] {$param_0, $param_1}, -8381844669958460146L);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 3, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ out.writeObject($param_1);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.AccessException e) {
+ throw e;
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ public void unbind(java.lang.String $param_0) throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
+ try {
+ if (useNewInvoke) {
+ ref.invoke(this, $method_unbind_4, new java.lang.Object[] {$param_0}, 7305022919901907578L);
+ }
+ else {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 4, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_0);
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ }
+ catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ }
+ finally {
+ ref.done(call);
+ }
+ }
+ }
+ catch (java.rmi.AccessException e) {
+ throw e;
+ }
+ catch (java.rmi.NotBoundException e) {
+ throw e;
+ }
+ catch (java.rmi.RemoteException e) {
+ throw e;
+ }
+ catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/registry/package.html b/libjava/classpath/gnu/java/rmi/registry/package.html
new file mode 100644
index 000000000..3750359d6
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/registry/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.rmi.registry package.
+ Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.rmi.registry</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>
diff --git a/libjava/classpath/gnu/java/rmi/server/ActivatableRef.java b/libjava/classpath/gnu/java/rmi/server/ActivatableRef.java
new file mode 100644
index 000000000..a6faaca2e
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/ActivatableRef.java
@@ -0,0 +1,179 @@
+/* ActivatableRef.java -- Activatable server reference
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.activation.ActivationException;
+import java.rmi.activation.ActivationID;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteRef;
+
+/**
+ * The activatable reference works like UnicastRef, but if the remote object
+ * appears to be not accessible, it tries to reactivate it before reporting
+ * any errors. Apart the fields of the UnicastRef, the activatable reference
+ * contains the ActivationID that is used for this activation.
+ *
+ * @author Audrius Meskauskas (Audriusa@Bioinformatics.org)
+ */
+public class ActivatableRef extends UnicastRef
+{
+ /**
+ * Use serial version UID for iteroperability
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * The activation id.
+ */
+ ActivationID actId;
+
+ /**
+ * Delegate call to the superclass.
+ */
+ public ActivatableRef()
+ {
+ super();
+ }
+
+ /**
+ * Delegate call to the superclass.
+ */
+ public ActivatableRef(ObjID objid, String host, int port,
+ RMIClientSocketFactory csf)
+ {
+ super(objid, host, port, csf);
+ }
+
+ /**
+ * Delegate call to the superclass.
+ */
+ public ActivatableRef(ObjID objid)
+ {
+ super(objid);
+ }
+
+ /**
+ * Get the referencing class.
+ */
+ public String getRefClass(ObjectOutput out)
+ {
+ return "ActivatableRef";
+ }
+
+ /**
+ * Read the content from the input stream.
+ */
+ public void readExternal(ObjectInput in) throws IOException,
+ ClassNotFoundException
+ {
+ actId = (ActivationID) in.readObject();
+ String type = in.readUTF();
+ // XXX handle type.equals("") (null reference)
+ super.readExternal(in);
+ }
+
+ /**
+ * Write the content to the output stream.
+ */
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ out.writeObject(actId);
+ // XXX write a "" if the "nested" reference is a null reference
+ out.writeUTF("UnicastRef2");
+ super.writeExternal(out);
+ }
+
+ /**
+ * Invoke the remote method on the given object and try to activate the object
+ * if it is not reacheable with the current manager.
+ */
+ protected Object invokeCommon(Remote obj, Method method, Object[] params,
+ int opnum, long hash) throws Exception
+ {
+ UnicastConnection conn;
+ try
+ {
+ conn = manager.getConnection();
+ }
+ catch (IOException e1)
+ {
+ // Connection failed: try to activate.
+ Remote reactivated = actId.activate(false);
+
+ if (reactivated instanceof RemoteObject)
+ {
+ RemoteRef ref = ((RemoteObject) reactivated).getRef();
+ manager = ((UnicastRef) ref).manager;
+ }
+ else if (Proxy.isProxyClass(reactivated.getClass()))
+ {
+ RemoteObjectInvocationHandler hander =
+ (RemoteObjectInvocationHandler)
+ Proxy.getInvocationHandler(reactivated);
+
+ RemoteRef ref = hander.getRef();
+ manager = ((UnicastRef) ref).manager;
+ }
+ else
+ throw new ActivationException("Activating into unsupported class "
+ + reactivated.getClass());
+
+ try
+ {
+ conn = manager.getConnection();
+ }
+ catch (IOException e2)
+ {
+ throw new RemoteException("connection failed to host: "
+ + manager.serverName, e1);
+ }
+ }
+ return invokeCommon(conn, obj, method, params, opnum, hash);
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java b/libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java
new file mode 100644
index 000000000..31e825a25
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java
@@ -0,0 +1,227 @@
+/* ActivatableServerRef.java -- The activatable server reference
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.activation.ActivationID;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.Skeleton;
+
+/**
+ * The activatable server reference works like UnicastServerReference, but it
+ * additionally activates the associated object on demand, during the first
+ * incoming call. When UnicastServerReference takes the working reference,
+ * the ActivatableServerRef takes the activation id instead.
+ *
+ * @author Audrius Meskauskas (Audriusa@Bioinformatics.org)
+ */
+public class ActivatableServerRef extends UnicastServerRef
+{
+ /**
+ * Use SVUID for interoperability
+ */
+ private static final long serialVersionUID = 1;
+
+ /**
+ * The object activation id.
+ */
+ public ActivationID actId;
+
+ /**
+ * Used by serialization only
+ */
+ public ActivatableServerRef()
+ {
+ super();
+ }
+
+ /**
+ * Create the new activatable server reference that will activate object on
+ * the first call using the given activation id.
+ */
+ public ActivatableServerRef(ObjID id, ActivationID anId, int aPort,
+ RMIServerSocketFactory ssFactory)
+ throws RemoteException
+ {
+ super(id, aPort, ssFactory);
+ actId = anId;
+
+ // The object ID will be placed in the object map and should deliver
+ // incoming call to {@link #incommingMessageCall}. The object itself
+ // is currently null.
+ UnicastServer.exportActivatableObject(this);
+ }
+
+ /**
+ * Inactivate the object (stop the server).
+ */
+ public void inactivate()
+ {
+ manager.stopServer();
+ }
+
+ /**
+ * Activate the object (normally during the first call).
+ */
+ protected void activate() throws RemoteException
+ {
+ try
+ {
+ Remote self = actId.activate(false);
+
+ // This will call UnicastServer.exportObject, replacing null by
+ // the activated object (self) in the object map.
+ exportObject(self);
+ }
+ catch (RemoteException rex)
+ {
+ throw rex;
+ }
+ catch (Exception exc)
+ {
+ RemoteException rx = new RemoteException("Activation failed.");
+ rx.detail = exc;
+ throw rx;
+ }
+ }
+
+ /**
+ * If the object is not active, activate it first.
+ */
+ public Object incomingMessageCall(UnicastConnection conn, int method,
+ long hash) throws Exception
+ {
+ if (myself == null)
+ activate();
+ return super.incomingMessageCall(conn, method, hash);
+ }
+
+ /**
+ * Export object and ensure it is present in the server activation table
+ * as well.
+ */
+ public Remote exportObject(Remote obj) throws RemoteException
+ {
+ Remote r = super.exportObject(obj);
+ UnicastServer.registerActivatable(this);
+ return r;
+ }
+
+ /**
+ * Export object and ensure it is present in the server activation table as
+ * well.
+ *
+ * @param aClass the class being exported, must implement Remote.
+ */
+ public Remote exportClass(Class aClass) throws RemoteException
+ {
+ if (!Remote.class.isAssignableFrom(aClass))
+ throw new InternalError(aClass.getName()+" must implement Remote");
+
+ String ignoreStubs;
+
+ ClassLoader loader =aClass.getClassLoader();
+
+ // Stubs are always searched for the bootstrap classes that may have
+ // obsolete pattern and may still need also skeletons.
+ if (loader==null)
+ ignoreStubs = "false";
+ else
+ ignoreStubs = System.getProperty("java.rmi.server.ignoreStubClasses",
+ "false");
+
+ if (! ignoreStubs.equals("true"))
+ {
+ // Find and install the stub
+ Class cls = aClass;
+
+ // where ist the _Stub? (check superclasses also)
+ Class expCls = findStubSkelClass(cls);
+
+ if (expCls != null)
+ {
+ stub = (RemoteStub) getHelperClass(expCls, "_Stub");
+ // Find and install the skeleton (if there is one)
+ skel = (Skeleton) getHelperClass(expCls, "_Skel");
+ }
+ }
+
+ if (stub == null)
+ stub = createProxyStub(aClass, this);
+
+ // Build hash of methods which may be called.
+ buildMethodHash(aClass, true);
+
+ UnicastServer.registerActivatable(this);
+ return stub;
+ }
+
+ /**
+ * Get the referencing class.
+ */
+ public String getRefClass(ObjectOutput out)
+ {
+ return "ActivatableRef";
+ }
+
+ /**
+ * Read the content from the input stream.
+ */
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
+ {
+ super.readExternal(in);
+ actId = (ActivationID) in.readObject();
+ }
+
+ /**
+ * Write the content to the output stream.
+ */
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ super.writeExternal(out);
+ out.writeObject(actId);
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java b/libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java
new file mode 100644
index 000000000..3d01d0987
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java
@@ -0,0 +1,135 @@
+/* CombinedClassLoader.java -- Multiple class loader support for proxy.
+ Copyright (C) 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * This class supports the multiple class loaders to load the resources. It is
+ * used for constructing proxy classes that implement interfaces, loaded by
+ * the several different class loaders.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+public class CombinedClassLoader extends ClassLoader
+{
+ /**
+ * The class loader array.
+ */
+ ClassLoader[] loaders;
+
+ /**
+ * Create a new combined class loader that uses the given collection of
+ * loaders to load the classes and resources. The loader order is equal to
+ * the order, returned by the collection interator. The duplicate loaders
+ * are discarded and the system class loader is added as the last loader.
+ *
+ * @param a_loaders the loadery collection (may contain duplicate instances
+ * that will be discarded.
+ */
+ public CombinedClassLoader(Collection a_loaders)
+ {
+ ArrayList sLoaders = new ArrayList(a_loaders.size());
+
+ Iterator iter = a_loaders.iterator();
+ Object cl;
+ while (iter.hasNext())
+ {
+ cl = iter.next();
+ if (cl!=null && !sLoaders.contains(cl))
+ sLoaders.add(cl);
+ }
+
+ loaders = new ClassLoader[sLoaders.size()];
+
+ for (int i = 0; i < loaders.length; i++)
+ loaders[i] = (ClassLoader) sLoaders.get(i);
+ }
+
+ /**
+ * Find the class with the given name.
+ */
+ protected Class findClass(String name) throws ClassNotFoundException
+ {
+ for (int i = 0; i < loaders.length; i++)
+ {
+ try
+ {
+ return loaders[i].loadClass(name);
+ }
+ catch (ClassNotFoundException e)
+ {
+ // try another.
+ }
+ }
+ return super.findClass(name);
+ }
+
+ /**
+ * Find resource with the given name.
+ */
+ protected URL findResource(String name)
+ {
+ for (int i = 0; i < loaders.length; i++)
+ {
+ URL resource = loaders[i].getResource(name);
+ if (resource != null)
+ return resource;
+ }
+ return super.findResource(name);
+ }
+
+ /**
+ * Find resources with the given name.
+ */
+ protected Enumeration findResources(String name) throws IOException
+ {
+ for (int i = 0; i < loaders.length; i++)
+ {
+ Enumeration resource = loaders[i].getResources(name);
+ if (resource != null)
+ return resource;
+ }
+ return super.findResources(name); }
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java b/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java
new file mode 100644
index 000000000..86660fea7
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/ConnectionRunnerPool.java
@@ -0,0 +1,156 @@
+/* gnu.java.rmi.server.ConnectionRunnerPool
+ Copyright (C) 2002, 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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();
+ }
+
+ }
+
+ // Should this value equal to number of CPU?
+ private static int size = 5;
+ private static int max_size = 10;
+
+ // Package-private to avoid a trampoline.
+ 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, Integer.toString(i));
+ 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 static synchronized ConnectionRunner getConnectionRunner()
+ {
+ if(freelist.size() == 0){
+ if(size < max_size){
+ ++size;
+ ConnectionRunner a = new ConnectionRunner(group, Integer.toString(size));
+ a.start();
+ freelist.add(a);
+ }else
+ while(freelist.size() == 0)
+ try{
+ ConnectionRunnerPool.class.wait();
+ }catch(InterruptedException e){}
+ }
+
+ // always let the first in pool most busy or other scheduling plan??
+ ConnectionRunner a = (ConnectionRunner)freelist.get(0);
+ freelist.remove(a);
+ return a;
+ }
+
+ public static void dispatchConnection(UnicastConnection conn)
+ {
+ ConnectionRunner r = getConnectionRunner();
+ r.dispatch(conn);
+ }
+
+ public static void exit()
+ {
+ Thread[] list = new Thread[group.activeCount()];
+ group.enumerate(list);
+ for(int i = 0; i < list.length; i++)
+ ((ConnectionRunner)list[i]).exit();
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java b/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java
new file mode 100644
index 000000000..72fbefe61
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/ProtocolConstants.java
@@ -0,0 +1,62 @@
+/* ProtocolConstants.java --
+ Copyright (c) 1996, 1997, 1998, 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.rmi.server;
+
+public interface ProtocolConstants
+{
+ int PROTOCOL_HEADER = 0x4a524d49; // JRMI
+ int PROTOCOL_VERSION = 2;
+
+ int STREAM_PROTOCOL = 0x4b;
+ int SINGLE_OP_PROTOCOL = 0x4c;
+ int MULTIPLEX_PROTOCOL = 0x4d;
+
+ int PROTOCOL_ACK = 0x4e;
+ int PROTOCOL_NACK = 0x4f;
+
+ int MESSAGE_CALL = 0x50;
+ int MESSAGE_CALL_ACK = 0x51;
+ int MESSAGE_PING = 0x52;
+ int MESSAGE_PING_ACK = 0x53;
+ int MESSAGE_DGCACK = 0x54;
+
+ int RETURN_ACK = 0x01;
+ int RETURN_NACK = 0x02;
+
+ int DEFAULT_PROTOCOL = STREAM_PROTOCOL;
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java b/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java
new file mode 100644
index 000000000..b090d3444
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java
@@ -0,0 +1,357 @@
+/* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose
+ Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.lang.CPStringBuilder;
+
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.rmi.server.RMIClassLoaderSpi;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+/**
+ * The default implementation of {@link java.rmi.server.RMIClassLoaderSpi}.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class RMIClassLoaderImpl extends RMIClassLoaderSpi
+{
+ private static class MyClassLoader extends URLClassLoader
+ {
+ // Package-private to avoid a trampoline constructor.
+ MyClassLoader (URL[] urls, ClassLoader parent, String annotation)
+ {
+ super (urls, parent);
+ this.annotation = annotation;
+ }
+
+ public static String urlToAnnotation (URL[] urls)
+ {
+ if (urls.length == 0)
+ return null;
+
+ CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
+
+ for (int i = 0; i < urls.length; i++)
+ {
+ annotation.append (urls [i].toExternalForm());
+ annotation.append (' ');
+ }
+
+ return annotation.toString();
+ }
+
+ public final String getClassAnnotation()
+ {
+ return annotation;
+ }
+
+ private final String annotation;
+ }
+
+ /**
+ * This class is used to identify a cached classloader by its codebase and
+ * the context classloader that is its parent.
+ */
+ private static class CacheKey
+ {
+ private String mCodeBase;
+ private ClassLoader mContextClassLoader;
+
+ public CacheKey (String theCodebase, ClassLoader theContextClassLoader)
+ {
+ mCodeBase = theCodebase;
+ mContextClassLoader = theContextClassLoader;
+ }
+
+ /**
+ * @return true if the codebase and the context classloader are equal
+ */
+ public boolean equals (Object theOther)
+ {
+ if (theOther instanceof CacheKey)
+ {
+ CacheKey key = (CacheKey) theOther;
+
+ return (equals (this.mCodeBase,key.mCodeBase)
+ && equals (this.mContextClassLoader, key.mContextClassLoader));
+ }
+ return false;
+ }
+
+ /**
+ * Test if the two objects are equal or both null.
+ * @param theOne
+ * @param theOther
+ * @return
+ */
+ private boolean equals (Object theOne, Object theOther)
+ {
+ return theOne != null ? theOne.equals (theOther) : theOther == null;
+ }
+
+ /**
+ * @return hashCode
+ */
+ public int hashCode()
+ {
+ return ((mCodeBase != null ? mCodeBase.hashCode() : 0)
+ ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1));
+ }
+
+ public String toString()
+ {
+ return "[" + mCodeBase + "," + mContextClassLoader + "]";
+ }
+
+ }
+
+ private static RMIClassLoaderImpl instance = null;
+
+ private static Map cacheLoaders; //map annotations to loaders
+ private static Map cacheAnnotations; //map loaders to annotations
+ //class loader for defaultAnnotation
+ private static MyClassLoader defaultClassLoader;
+
+ //defaultAnnotation is got from system property
+ // "java.rmi.server.defaultAnnotation"
+ private static String defaultAnnotation;
+
+ //URL object for defaultAnnotation
+ private static URL defaultCodebase;
+
+ static
+ {
+ // 89 is a nice prime number for Hashtable initial capacity
+ cacheLoaders = new Hashtable (89);
+ cacheAnnotations = new Hashtable (89);
+
+ defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation");
+
+ try
+ {
+ if (defaultAnnotation != null)
+ defaultCodebase = new URL (defaultAnnotation);
+ }
+ catch (Exception _)
+ {
+ defaultCodebase = null;
+ }
+
+ if (defaultCodebase != null)
+ {
+ defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null,
+ defaultAnnotation);
+ // XXX using getContextClassLoader here *cannot* be right
+ cacheLoaders.put (new CacheKey (defaultAnnotation,
+ Thread.currentThread().getContextClassLoader()),
+ defaultClassLoader);
+ }
+ }
+
+ /**
+ * This is a singleton class and may only be instantiated once from within
+ * the {@link #getInstance} method.
+ */
+ private RMIClassLoaderImpl()
+ {
+ }
+
+ /**
+ * Returns an instance of RMIClassLoaderImpl.
+ *
+ * @return an instance of RMIClassLoaderImpl
+ */
+ public static RMIClassLoaderSpi getInstance()
+ {
+ if (instance == null)
+ instance = new RMIClassLoaderImpl();
+ return instance;
+ }
+
+ public Class loadClass(String codeBase, String name,
+ ClassLoader defaultLoader)
+ throws MalformedURLException, ClassNotFoundException
+ {
+ try
+ {
+ if (defaultLoader != null)
+ return Class.forName(name, false, defaultLoader);
+ }
+ catch (ClassNotFoundException e)
+ {
+ }
+
+ return Class.forName(name, false, getClassLoader(codeBase));
+ }
+
+ public Class loadProxyClass(String codeBase, String[] interfaces,
+ ClassLoader defaultLoader)
+ throws MalformedURLException, ClassNotFoundException
+ {
+ Class clss[] = new Class[interfaces.length];
+
+ for (int i = 0; i < interfaces.length; i++)
+ {
+ clss[i] = loadClass(codeBase, interfaces[i], defaultLoader);
+ }
+
+ // Chain all class loaders (they may differ).
+ ArrayList loaders = new ArrayList(clss.length);
+ ClassLoader loader = null;
+ for (int i = 0; i < clss.length; i++)
+ {
+ loader = clss[i].getClassLoader();
+ if (! loaders.contains(loader))
+ {
+ loaders.add(0, loader);
+ }
+ }
+ if (loaders.size() > 1)
+ {
+ loader = new CombinedClassLoader(loaders);
+ }
+
+ try
+ {
+ return Proxy.getProxyClass(loader, clss);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ClassNotFoundException(null, e);
+ }
+ }
+
+ /**
+ * Gets a classloader for the given codebase and with the current
+ * context classloader as parent.
+ *
+ * @param codebase
+ *
+ * @return a classloader for the given codebase
+ *
+ * @throws MalformedURLException if the codebase contains a malformed URL
+ */
+ public ClassLoader getClassLoader(String codebase)
+ throws MalformedURLException
+ {
+ if (codebase == null || codebase.length() == 0)
+ return Thread.currentThread().getContextClassLoader();
+
+ ClassLoader loader;
+ CacheKey loaderKey = new CacheKey
+ (codebase, Thread.currentThread().getContextClassLoader());
+ loader = (ClassLoader) cacheLoaders.get (loaderKey);
+
+ if (loader == null)
+ {
+ //create an entry in cacheLoaders mapping a loader to codebases.
+ // codebases are separated by " "
+ StringTokenizer tok = new StringTokenizer (codebase, " ");
+ 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(),
+ codebase);
+ cacheLoaders.put (loaderKey, loader);
+ }
+
+ return loader;
+ }
+
+ /**
+ * Returns a string representation of the network location where a remote
+ * endpoint can get the class-definition of the given class.
+ *
+ * @param cl
+ *
+ * @return a space seperated list of URLs where the class-definition
+ * of cl may be found
+ */
+ public String getClassAnnotation(Class cl)
+ {
+ ClassLoader loader = cl.getClassLoader();
+
+ if (loader == null
+ || loader == ClassLoader.getSystemClassLoader())
+ {
+ return System.getProperty ("java.rmi.server.codebase");
+ }
+
+ if (loader instanceof MyClassLoader)
+ {
+ return ((MyClassLoader) loader).getClassAnnotation();
+ }
+
+ String s = (String) cacheAnnotations.get (loader);
+
+ if (s != null)
+ return s;
+
+ if (loader instanceof URLClassLoader)
+ {
+ URL[] urls = ((URLClassLoader) loader).getURLs();
+
+ if (urls.length == 0)
+ return null;
+
+ CPStringBuilder annotation = new CPStringBuilder (64 * urls.length);
+
+ for (int i = 0; i < urls.length; i++)
+ {
+ annotation.append (urls [i].toExternalForm());
+ annotation.append (' ');
+ }
+
+ s = annotation.toString();
+ cacheAnnotations.put (loader, s);
+ return s;
+ }
+
+ return System.getProperty ("java.rmi.server.codebase");
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java b/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java
new file mode 100644
index 000000000..7115ba543
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIDefaultSocketFactory.java
@@ -0,0 +1,59 @@
+/* RMIDefaultSocketFactory.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.rmi.server.RMISocketFactory;
+
+public class RMIDefaultSocketFactory
+ extends RMISocketFactory {
+
+public RMIDefaultSocketFactory() {
+}
+
+public Socket createSocket(String host, int port) throws IOException {
+ return (new Socket(host, port));
+}
+
+public ServerSocket createServerSocket(int port) throws IOException {
+ return (new ServerSocket(port));
+}
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIHashes.java b/libjava/classpath/gnu/java/rmi/server/RMIHashes.java
new file mode 100644
index 000000000..03eb09fd0
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIHashes.java
@@ -0,0 +1,99 @@
+/* RMIHashes.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.lang.CPStringBuilder;
+
+import gnu.java.lang.reflect.TypeSignature;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.lang.reflect.Method;
+import java.security.MessageDigest;
+
+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)
+ {
+ //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);
+
+ CPStringBuilder sbuf = new CPStringBuilder();
+ 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)
+ {
+ return clazz.hashCode ();
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java b/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java
new file mode 100644
index 000000000..352b48b31
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIIncomingThread.java
@@ -0,0 +1,58 @@
+/* RMIIncomingThread.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.java.rmi.server;
+
+public class RMIIncomingThread extends Thread {
+
+ private String clientHost = null;
+
+ public RMIIncomingThread(Runnable runnable, String s_clientHost) {
+ super(runnable);
+ clientHost = s_clientHost;
+ }
+
+ public String toString() {
+ return "RMIIncoming from " + clientHost + " " + super.toString();
+ }
+
+ public String getClientHost() {
+ return clientHost;
+ }
+
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java
new file mode 100644
index 000000000..4ac7a0ae8
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java
@@ -0,0 +1,118 @@
+/* RMIObjectInputStream.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 2006
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.classpath.VMStackWalker;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.net.MalformedURLException;
+import java.rmi.server.RMIClassLoader;
+
+public class RMIObjectInputStream
+ extends ObjectInputStream {
+
+public RMIObjectInputStream(InputStream strm) throws IOException {
+ super(strm);
+ enableResolveObject(true);
+}
+
+protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
+ try {
+ return RMIClassLoader.loadClass(
+ (String)getAnnotation(),
+ desc.getName(),
+ VMStackWalker.firstNonNullClassLoader());
+ }
+ catch (MalformedURLException x) {
+ throw new ClassNotFoundException(desc.getName(), x);
+ }
+}
+
+//Separate it for override by MarshalledObject
+protected Object getAnnotation()
+ throws IOException, ClassNotFoundException
+{
+ return readObject();
+}
+
+
+ protected Class resolveProxyClass(String intfs[]) throws IOException,
+ ClassNotFoundException
+ {
+ try
+ {
+ return RMIClassLoader.loadProxyClass(
+ (String)getAnnotation(),
+ intfs,
+ VMStackWalker.firstNonNullClassLoader());
+ }
+ catch (MalformedURLException x)
+ {
+ throw new ClassNotFoundException(null, x);
+ }
+ }
+
+protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException {
+ if(valueClass.isPrimitive()){
+ if(valueClass == Boolean.TYPE)
+ return Boolean.valueOf(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();
+}
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java b/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java
new file mode 100644
index 000000000..aaf09860c
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIObjectOutputStream.java
@@ -0,0 +1,114 @@
+/* RMIObjectOutputStream.java -
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.rmi.Remote;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.RemoteStub;
+
+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 {
+ 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 = UnicastServer.getExportedRef((Remote)obj);
+ if (ref != null)
+ return ref.getStub();
+ }
+ return obj;
+}
+
+protected void writeValue(Object value, Class valueClass) throws IOException{
+ if(valueClass.isPrimitive()){
+ if(valueClass == Boolean.TYPE)
+ writeBoolean(((Boolean)value).booleanValue());
+ else
+ if(valueClass == Byte.TYPE)
+ writeByte(((Byte)value).byteValue());
+ else
+ if(valueClass == Character.TYPE)
+ writeChar(((Character)value).charValue());
+ else
+ if(valueClass == Short.TYPE)
+ writeShort(((Short)value).shortValue());
+ else
+ if(valueClass == Integer.TYPE)
+ writeInt(((Integer)value).intValue());
+ else
+ if(valueClass == Long.TYPE)
+ writeLong(((Long)value).longValue());
+ else
+ if(valueClass == Float.TYPE)
+ writeFloat(((Float)value).floatValue());
+ else
+ if(valueClass == Double.TYPE)
+ writeDouble(((Double)value).doubleValue());
+ else
+ throw new Error("Unsupported primitive class: " + valueClass);
+ } else
+ writeObject(value);
+}
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java b/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java
new file mode 100644
index 000000000..8e5546d35
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/RMIVoidValue.java
@@ -0,0 +1,51 @@
+/* RMIVoidValue.java --
+ Copyright (c) 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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;
+
+/**
+ * Package private class used to indicate a void return type.
+ * INSTANCE is the only object of this class ever made.
+ */
+final class RMIVoidValue
+{
+ static RMIVoidValue INSTANCE = new RMIVoidValue();
+
+ private RMIVoidValue()
+ {
+ }
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java b/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java
new file mode 100644
index 000000000..8245e0469
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastConnection.java
@@ -0,0 +1,231 @@
+/* UnicastConnection.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.rmi.RemoteException;
+
+public class UnicastConnection
+ implements Runnable, ProtocolConstants {
+
+UnicastConnectionManager manager;
+Socket sock;
+DataInputStream din;
+DataOutputStream dout;
+ObjectInputStream oin;
+ObjectOutputStream oout;
+
+// reviveTime and expireTime make UnicastConnection pool-able
+long reviveTime = 0;
+long expireTime = Long.MAX_VALUE;
+
+UnicastConnection(UnicastConnectionManager man, Socket sock) {
+ this.manager = man;
+ this.sock = sock;
+}
+
+void acceptConnection() throws IOException {
+//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) {
+ throw new IOException("bad protocol header");
+ }
+ short ver = din.readShort();
+ if (ver != PROTOCOL_VERSION) {
+ throw new IOException("bad protocol version");
+ }
+ int protocol = din.readUnsignedByte();
+ if (protocol != SINGLE_OP_PROTOCOL) {
+ // Send an ACK
+ dout.writeByte(PROTOCOL_ACK);
+
+ // Send my hostname and port
+ dout.writeUTF(manager.serverName);
+ dout.writeInt(manager.serverPort);
+ dout.flush();
+
+ // Read their hostname and port
+ String rhost = din.readUTF();
+ int rport = din.readInt();
+ }
+ // Okay, ready to roll ...
+}
+
+void makeConnection(int protocol) throws IOException {
+ //Use BufferedXXXStream would be more efficient
+ din = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
+
+ dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
+
+ // Send header
+ dout.writeInt(PROTOCOL_HEADER);
+ dout.writeShort(PROTOCOL_VERSION);
+ dout.writeByte(protocol);
+ dout.flush();
+
+ if (protocol != SINGLE_OP_PROTOCOL) {
+ // Get back ack.
+ int ack = din.readUnsignedByte();
+ if (ack != PROTOCOL_ACK) {
+ throw new RemoteException("Unsupported protocol");
+ }
+
+ // Read in host and port
+ String dicard_rhost = din.readUTF();
+ int discard_rport = din.readInt();
+
+ // Send them my endpoint
+ dout.writeUTF(manager.serverName);
+ dout.writeInt(manager.serverPort);
+ dout.flush();
+ }
+ // Okay, ready to roll ...
+}
+
+DataInputStream getDataInputStream() throws IOException {
+ return (din);
+}
+
+DataOutputStream getDataOutputStream() throws IOException {
+ return (dout);
+}
+
+/*
+*
+* get ObjectInputStream for reading more objects
+*
+*/
+ObjectInputStream getObjectInputStream() throws IOException {
+ if (oin == null) {
+ throw new IOException("no ObjectInputtream for reading more objects");
+ }
+ return (oin);
+}
+
+/**
+*
+* starts ObjectInputStream.
+*
+*/
+ObjectInputStream startObjectInputStream() throws IOException {
+ return (oin = new RMIObjectInputStream(din));
+}
+
+/**
+*
+* get ObjectOutputStream for sending more objects
+*
+*/
+ObjectOutputStream getObjectOutputStream() throws IOException {
+ if (oout == null) {
+ throw new IOException("no ObjectOutputStream for sending more objects");
+ }
+ return (oout);
+}
+
+/**
+*
+* starts ObjectOutputStream.
+*
+*/
+ObjectOutputStream startObjectOutputStream() throws IOException {
+ return (oout = new RMIObjectOutputStream(dout));
+}
+
+void disconnect() {
+ try {
+ if(oout != null)
+ oout.close();
+ sock.close();
+ }
+ catch (IOException _) {
+ }
+
+ oin = null;
+ oout = null;
+ din = null;
+ dout = null;
+ sock = null;
+}
+
+public static final long CONNECTION_TIMEOUT = 10000L;
+
+static boolean isExpired(UnicastConnection conn, long l){
+ if (l <= conn.expireTime )
+ return false;
+ return true;
+}
+
+static void resetTime(UnicastConnection conn){
+ long l = System.currentTimeMillis();
+ conn.reviveTime = l;
+ conn.expireTime = l + CONNECTION_TIMEOUT;
+}
+
+/**
+ * We run connects on the server. Dispatch it then discard it.
+ */
+public void run() {
+ do{
+ try {
+ UnicastServer.dispatch(this);
+ //don't discardConnection explicitly, only when
+ // exception happens or the connection's expireTime
+ // comes
+ } catch (Exception e ){
+ manager.discardConnection(this);
+ break;
+ }
+ }while(true);
+}
+
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java b/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java
new file mode 100644
index 000000000..981d11792
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastConnectionManager.java
@@ -0,0 +1,468 @@
+/* UnicastConnectionManager.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.rmi.RemoteException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+public class UnicastConnectionManager
+ implements Runnable, ProtocolConstants {
+
+private static String localhost;
+// use different maps for server/client type UnicastConnectionManager
+private static Hashtable servers = new Hashtable();
+// Package-private to avoid trampolines.
+static Hashtable clients = new Hashtable();
+ArrayList connections; //client connection pool
+
+// make serverThread volatile for poll
+private volatile Thread serverThread;
+private ServerSocket ssock;
+String serverName;
+int serverPort;
+
+// Package-private to avoid a trampoline.
+static Thread scavenger;
+
+// If client and server are in the same VM, serverobj represents server
+Object serverobj;
+
+private static RMISocketFactory defaultSocketFactory = RMISocketFactory.getSocketFactory();
+private RMIServerSocketFactory serverFactory;
+private RMIClientSocketFactory clientFactory;
+
+// The following is for debug
+private static int ncsock = 0; //count of client socket
+private static int nssock = 0; //count of server socket
+private static int ncmanager = 0; //count of client manager
+private static int nsmanager = 0; //count of server manager
+
+private static final boolean debug = false;
+
+private static final Object GLOBAL_LOCK = new Object();
+
+static {
+ try {
+ //Use host address instead of host name to avoid name resolving issues
+ //localhost = InetAddress.getLocalHost().getHostName();
+ localhost = InetAddress.getLocalHost().getHostAddress();
+ }
+ catch (UnknownHostException _) {
+ localhost = "localhost";
+ }
+
+
+}
+
+//Only one scavenger thread running globally
+private static void startScavenger(){
+ scavenger = new Thread(new Runnable(){
+ public void run(){
+ if (debug) System.out.println("************* start scavenger.");
+ boolean liveon = true;
+ while (liveon){
+ // Sleep for the expire timeout
+ try{
+ Thread.sleep(UnicastConnection.CONNECTION_TIMEOUT);
+ }catch(InterruptedException _ie){
+ break;
+ }
+ liveon = false;
+ // Scavenge all clients' connections that're expired
+ Iterator iter = clients.values().iterator();
+ long l = System.currentTimeMillis();
+ try{
+ while(iter.hasNext()){
+ UnicastConnectionManager man = (UnicastConnectionManager)iter.next();
+ ArrayList conns = man.connections;
+ synchronized(conns) { // is the lock a little coarser?
+ for (int last = conns.size() - 1;
+ last >= 0;
+ --last)
+ {
+ UnicastConnection conn = (UnicastConnection)conns.get(last);
+ if (UnicastConnection.isExpired(conn, l)){
+ conns.remove(last);
+ conn.disconnect();
+ conn = null;
+ }else
+ liveon = true; //there're still live connections
+ }
+ }
+ }
+ }catch(ConcurrentModificationException cme) {
+ // handle it lazily
+ liveon = true;
+ }
+ }
+ scavenger = null;
+ if (debug) System.out.println("************* exit scavenger.");
+ }
+ });
+ // As it is used for client connection, we may put this thread
+ // in daemon state to prevent the VM from blocking when exiting.
+ scavenger.setDaemon(true);
+ scavenger.start();
+}
+
+/**
+ * Client UnicastConnectionManager constructor
+ */
+private UnicastConnectionManager(String host, int port, RMIClientSocketFactory csf) {
+ ssock = null;
+ serverName = host;
+ serverPort = port;
+ serverFactory = null;
+ clientFactory = csf;
+ connections = new ArrayList();
+}
+
+/**
+ * Server UnicastConnectionManager constructor
+ */
+private UnicastConnectionManager(int port, RMIServerSocketFactory ssf) throws RemoteException {
+
+ try {
+ ssock = ssf.createServerSocket(port);
+ serverPort = ssock.getLocalPort();
+ }
+ catch (IOException ioex) {
+ ssock = null;
+ serverPort = 0;
+ throw new java.rmi.server.ExportException("can not create Server Socket on port " + port,ioex);
+ }
+ // Note that for compatibility the serverName is "localhost",
+ // not UnicastConnectionManager.localhost, which is the name
+ // of the local box. A server listening on localhost:port is
+ // listening on the loopback interface, 127.0.0.1, but
+ // UnicastConnectionManager.localhost is an externally
+ // accessible IP address.
+ serverName = "localhost";
+ serverFactory = ssf;
+ clientFactory = null;
+}
+
+/**
+ * Return a client connection manager which will connect to the given
+ * host/port.
+ */
+public static synchronized UnicastConnectionManager getInstance(String host, int port, RMIClientSocketFactory csf) {
+//System.out.println("getInstance: " + host + "," + port + "," + csf);
+ if (csf == null) {
+ csf = defaultSocketFactory;
+ }
+ // 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)clients.get(key);
+ if (man == null) {
+ man = new UnicastConnectionManager(host, port, csf);
+ if (debug) {
+ ncmanager++;
+ System.out.println("\n\n ====== " + ncmanager + " client managers.\n\n");
+ }
+ clients.put(key, man);
+
+ // Detect if client and server are in the same VM, i.e., their keys are equal
+ UnicastConnectionManager svrman = (UnicastConnectionManager)servers.get(key);
+ if(svrman != null){ // server and client are in the same VM
+ man.serverobj = svrman.serverobj;
+ }
+ }
+ return (man);
+}
+
+/**
+ * Return a server connection manager which will accept connection on the
+ * given port.
+ */
+public static synchronized UnicastConnectionManager getInstance(int port, RMIServerSocketFactory ssf) throws RemoteException {
+//System.out.println("getInstance: " + port + "," + ssf);
+ if (ssf == null) {
+ ssf = defaultSocketFactory;
+ }
+ TripleKey key = new TripleKey(localhost, port, ssf);
+ UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key);
+ if (man == null) {
+ man = new UnicastConnectionManager(port, ssf);
+ if (debug) {
+ nsmanager++;
+ System.out.println("\n\n ****** " + nsmanager + " server managers.\n\n");
+ }
+ // The provided port might not be the set port.
+ key.port = man.serverPort;
+ servers.put(key, man);
+ }
+ return (man);
+}
+
+/**
+ * Get a connection from this manager.
+ */
+public UnicastConnection getConnection() throws IOException {
+ if (ssock == null) {
+ return (getClientConnection());
+ }
+ else {
+ return (getServerConnection());
+ }
+}
+
+/**
+ * Accept a connection to this server.
+ */
+private UnicastConnection getServerConnection() throws IOException {
+ Socket sock = ssock.accept();
+ sock.setTcpNoDelay(true); //??
+ UnicastConnection conn = new UnicastConnection(this, sock);
+ conn.acceptConnection();
+ if (debug){
+ nssock++;
+ System.out.println("\n\n ****** " + nssock + " server socks.\n\n");
+ }
+ //System.out.println("Server connection " + sock);
+ return (conn);
+}
+
+/**
+ * Make a conection from this client to the server.
+ */
+private UnicastConnection getClientConnection() throws IOException {
+ ArrayList conns = connections;
+ UnicastConnection conn;
+
+ synchronized(conns) {
+ int nconn = conns.size() - 1;
+
+ // if there're free connections in connection pool
+ if(nconn >= 0) {
+ conn = (UnicastConnection)conns.get(nconn);
+ //Should we check if conn is alive using Ping??
+ conns.remove(nconn);
+
+ // Check if the connection is already expired
+ long l = System.currentTimeMillis();
+ if (!UnicastConnection.isExpired(conn, l)){
+ return conn;
+ }else {
+ conn.disconnect();
+ conn = null;
+ }
+ }
+ }
+
+ Socket sock = clientFactory.createSocket(serverName, serverPort);
+ conn = new UnicastConnection(this, sock);
+ conn.makeConnection(DEFAULT_PROTOCOL);
+
+ if (debug) {
+ ncsock++;
+ System.out.println("\n\n ====== " + ncsock + " client socks.\n\n");
+ }
+
+ return (conn);
+}
+
+/**
+ * Get the string representation, describing the connection.
+ */
+public String toString()
+{
+ return serverName+":"+serverPort+" ("+serverobj+")";
+}
+
+/**
+ * Discard a connection when we're done with it - maybe it can be
+ * recycled.
+ */
+public void discardConnection(UnicastConnection conn) {
+//System.out.println("Discarding connection " + conn);
+ //conn.disconnect();
+ if (ssock != null) //server connection
+ conn.disconnect();
+ else {
+ // To client connection, we'd like to return back to pool
+ UnicastConnection.resetTime(conn);
+ //Ensure there're only one scavenger globally
+ synchronized(GLOBAL_LOCK) {
+ connections.add(conn); //borrow this lock to garantee thread safety
+ if (scavenger == null)
+ startScavenger();
+ }
+ }
+}
+
+/**
+ * Start a server on this manager if it's a server socket and we've not
+ * already got one running.
+ */
+public void startServer() {
+ synchronized(this) {
+ if (ssock == null || serverThread != null) {
+ return;
+ }
+ serverThread = new Thread(this);
+ // The following is not necessary when java.lang.Thread's constructor do this.
+ // serverThread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
+ }
+ serverThread.start();
+}
+
+/**
+ * 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 (;serverThread != null;) { // if serverThread==null, then exit thread
+ try {
+//System.out.println("Waiting for connection on " + serverPort);
+ UnicastConnection conn = getServerConnection();
+
+ // get address of remote host for the RMIIncomingThread object
+ String remoteHost = null;
+ if (conn.sock != null) {
+ remoteHost = conn.sock.getInetAddress().getHostAddress();
+ }
+
+ // use a thread pool to improve performance
+ //ConnectionRunnerPool.dispatchConnection(conn);
+ (new RMIIncomingThread(conn, remoteHost)).start();
+// (new Thread(conn)).start();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+
+/**
+ * Serialization routine.
+ */
+void write(ObjectOutput out) throws IOException {
+ out.writeUTF(serverName);
+ out.writeInt(serverPort);
+}
+
+/**
+ * Serialization routine.
+ */
+static UnicastConnectionManager read(ObjectInput in) throws IOException {
+ String host = in.readUTF();
+ int port = in.readInt();
+ //RMIClientSocketFactory csf = ((RMIObjectInputStream)in).manager.clientFactory;
+ //return (getInstance(host, port, csf));
+ return (getInstance(host, port, null));
+}
+
+}
+
+/**
+ * This is use as the hashkey for the client/server connections.
+ */
+class TripleKey {
+
+String host;
+int port;
+Object other;
+
+TripleKey(String host, int port, Object other) {
+ this.host = host;
+ this.port = port;
+ this.other = other;
+}
+
+/**
+ * Hash code just include the host and other - we ignore the port since
+ * this has unusual matching behaviour.
+ */
+public int hashCode() {
+ return (host.hashCode() ^ other.hashCode());
+}
+
+public boolean equals(Object obj) {
+ if (obj instanceof TripleKey) {
+ TripleKey other = (TripleKey)obj;
+ if (this.host.equals(other.host) &&
+ this.other == other.other &&
+ (this.port == other.port /* || this.port == 0 || other.port == 0*/)) {
+ return (true);
+ }
+ }
+ return (false);
+}
+
+ /**
+ * Get the string representation, describing the connection.
+ */
+ public String toString()
+ {
+ return host+":"+port+" ("+other+")";
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRef.java b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java
new file mode 100644
index 000000000..ca2bab51a
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastRef.java
@@ -0,0 +1,524 @@
+/* UnicastRef.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005, 2006
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.rmi.dgc.LeaseRenewingTask;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.rmi.ConnectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.dgc.Lease;
+import java.rmi.server.ObjID;
+import java.rmi.server.Operation;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RemoteCall;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+import java.rmi.server.UID;
+
+public class UnicastRef
+ implements RemoteRef, ProtocolConstants
+{
+
+ /**
+ * Use serial version UID for iteroperability
+ */
+ private static final long serialVersionUID = 1;
+
+ public ObjID objid;
+
+ UnicastConnectionManager manager;
+
+ /**
+ * Used by serialization, and let subclass capable of having default
+ * constructor
+ */
+ // must be public otherwise java.rmi.RemoteObject cannot instantiate this
+ // class
+ // -- iP
+ public UnicastRef()
+ {
+ }
+
+ public UnicastRef(ObjID objid, String host, int port,
+ RMIClientSocketFactory csf)
+ {
+ this(objid);
+ manager = UnicastConnectionManager.getInstance(host, port, csf);
+ }
+
+ public UnicastRef(ObjID objid)
+ {
+ this.objid = objid;
+ }
+
+ public Object invoke(Remote obj, Method method, Object[] params, long opnum)
+ throws Exception
+ {
+ // Check if client and server are in the same VM, then local call can be
+ // used to
+ // replace remote call, but it's somewhat violating remote semantic.
+ Object svrobj = manager.serverobj;
+
+ // Make sure that the server object is compatible. It could be loaded from a
+ // different
+ // classloader --iP
+ if (svrobj != null && method.getDeclaringClass().isInstance(svrobj))
+ {
+ // local call
+ Object ret = null;
+ try
+ {
+ ret = method.invoke(svrobj, params);
+ }
+ catch (InvocationTargetException e)
+ {
+ throw (Exception) e.getTargetException();
+ }
+ // System.out.println("\n\n ***** local call: " + method + "\nreturn: "
+ // + ret + "\n\n");
+ return ret;
+ }
+ // System.out.println("***************** remote call:" +
+ // manager.serverPort);
+ return (invokeCommon(obj, method, params, - 1, opnum));
+ }
+
+ /**
+ * The ordinary number of the DGC messages.
+ */
+ static long dgcSequence;
+
+ /**
+ * The DGC object id, also serves as a synchronization target to increment the
+ * dgcSequence safely.
+ */
+ static final ObjID dgcId = new ObjID(ObjID.DGC_ID);
+
+ ObjID[] this_id;
+
+ /**
+ * The number of the method "dirty" in the DGC.
+ */
+ static int DIRTY = 1;
+
+ /**
+ * The DGC interface hash code.
+ */
+ static final long dgcInterfaceHash = - 669196253586618813L;
+
+ /**
+ * Notify the DGC of the remote side that we still hold this object.
+ */
+ public Lease notifyDGC(Lease lease) throws Exception
+ {
+ long seq;
+ synchronized (dgcId)
+ {
+ seq = dgcSequence++;
+ }
+
+ if (this_id == null)
+ this_id = new ObjID[] { objid };
+
+ UnicastConnection conn;
+ try
+ {
+ conn = manager.getConnection();
+ }
+ catch (IOException e1)
+ {
+ throw new RemoteException("connection failed to host: "
+ + manager.serverName, e1);
+ }
+
+ ObjectOutputStream out;
+ DataOutputStream dout;
+ try
+ {
+ dout = conn.getDataOutputStream();
+ dout.writeByte(MESSAGE_CALL);
+
+ out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
+
+ dgcId.write(out);
+ // The number of the operation is 1 ("dirty")
+ out.writeInt(DIRTY);
+ out.writeLong(dgcInterfaceHash);
+
+ RMIObjectOutputStream rout = (RMIObjectOutputStream) out;
+
+ rout.writeValue(this_id, this_id.getClass());
+ rout.writeLong(seq);
+ rout.writeValue(lease, lease.getClass());
+
+ out.flush();
+ }
+ catch (IOException e2)
+ {
+ throw new RemoteException("DGC call failed: ", e2);
+ }
+
+ int returncode;
+ Object returnval;
+ DataInputStream din;
+ ObjectInputStream in;
+ UID ack;
+ try
+ {
+ din = conn.getDataInputStream();
+
+ if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK)
+ {
+ conn.disconnect();
+ throw new RemoteException("DGC Call not acked:" + returncode);
+ }
+
+ in = conn.startObjectInputStream(); // (re)start ObjectInputStream
+ returncode = in.readUnsignedByte();
+ ack = UID.read(in);
+
+ if (returncode == RETURN_NACK)
+ {
+ returnval = in.readObject(); // get Exception
+
+ }
+ else
+ {
+ returnval = ((RMIObjectInputStream) in).readValue(Lease.class);
+ }
+ }
+ catch (IOException e3)
+ {
+ throw new RemoteException("DGC call return failed: ", e3);
+ }
+
+ manager.discardConnection(conn);
+
+ if (returncode != RETURN_ACK && returnval != null)
+ {
+ if (returncode == RETURN_NACK)
+ throw (Exception) returnval;
+ else
+ throw new RemoteException("DGC unexpected returncode: " + returncode);
+ }
+
+ return (Lease) returnval;
+ }
+ /**
+ * Invoke the remote method on the given object. This part is overridden by
+ * the activatable objects.
+ */
+ protected Object invokeCommon(Remote obj, Method method, Object[] params,
+ int opnum, long hash) throws Exception
+ {
+ UnicastConnection conn;
+ try
+ {
+ conn = manager.getConnection();
+ return invokeCommon(conn, obj, method, params, opnum, hash);
+ }
+ catch (IOException e1)
+ {
+ throw new RemoteException("connection failed to host: "
+ + manager.serverName, e1);
+ }
+ }
+
+ /**
+ * Invoke the remote method on the given object when connection is already
+ * established.
+ */
+ protected Object invokeCommon(UnicastConnection conn, Remote obj,
+ Method method, Object[] params, int opnum,
+ long hash) throws Exception
+ {
+ ObjectOutputStream out;
+ DataOutputStream dout;
+ try
+ {
+ dout = conn.getDataOutputStream();
+ dout.writeByte(MESSAGE_CALL);
+
+ out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
+
+ objid.write(out);
+ out.writeInt(opnum);
+ out.writeLong(hash);
+
+ // 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();
+ }
+ catch (IOException e2)
+ {
+ throw new RemoteException("call failed: ", e2);
+ }
+
+ int returncode;
+ Object returnval;
+ DataInputStream din;
+ ObjectInputStream in;
+ UID ack;
+ try
+ {
+ din = conn.getDataInputStream();
+
+ if ((returncode = din.readUnsignedByte()) != MESSAGE_CALL_ACK)
+ {
+ conn.disconnect();
+ throw new RemoteException("Call not acked:" + returncode);
+ }
+
+ in = conn.startObjectInputStream(); // (re)start ObjectInputStream
+ returncode = in.readUnsignedByte();
+ ack = UID.read(in);
+
+ Class cls = method.getReturnType();
+
+ if (returncode == RETURN_NACK)
+ {
+ returnval = in.readObject(); // get Exception
+
+ }
+ else if (cls == Void.TYPE)
+ {
+ returnval = null;
+ // in.readObject() // not required! returntype 'void' means no field
+ // is returned.
+ }
+ else
+ {
+ returnval = ((RMIObjectInputStream) in).readValue(cls); // get
+ // returnvalue
+ }
+ }
+ catch (IOException e3)
+ {
+ // for debug: e3.printStackTrace();
+ 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 && returnval != null)
+ {
+ if (returncode == RETURN_NACK)
+ throw (Exception) returnval;
+ else
+ throw new RemoteException("unexpected returncode: " + returncode);
+ }
+
+ return (returnval);
+ }
+
+ /**
+ * @deprecated
+ */
+ public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum,
+ long hash) throws RemoteException
+ {
+ UnicastConnection conn;
+
+ try
+ {
+ conn = manager.getConnection();
+ }
+ catch (IOException e1)
+ {
+ throw new ConnectException("connection failed to host: "
+ + manager.serverName, e1);
+ }
+
+ // obj: useless?
+
+ return (new UnicastRemoteCall(conn, objid, opnum, hash));
+ }
+
+ /**
+ * @deprecated
+ */
+ public void invoke(RemoteCall call) throws Exception
+ {
+ UnicastRemoteCall c = (UnicastRemoteCall) call;
+ call.executeCall();
+ }
+
+ /**
+ * @deprecated
+ */
+ public void done(RemoteCall call) throws RemoteException
+ {
+ UnicastRemoteCall c = (UnicastRemoteCall) call;
+ try
+ {
+ c.done();
+ }
+ catch (IOException e)
+ {
+ }
+ UnicastConnection conn = c.getConnection();
+ manager.discardConnection(conn);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException
+ {
+ if (manager == null)
+ {
+ throw new IOException("no connection");
+ }
+ manager.write(out);
+ objid.write(out);
+ // 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);
+ 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");
+ }
+
+ // Notify the DGC of the remote side that we hold the reference to the
+ // received object. Do not notify if the client and server are on the
+ // same virtual machine.
+ if (manager.serverobj == null)
+ LeaseRenewingTask.scheduleLeases(this);
+ }
+
+ public boolean remoteEquals(RemoteRef ref)
+ {
+ throw new Error("Not implemented");
+ }
+
+ public int remoteHashCode()
+ {
+ throw new Error("Not implemented");
+ }
+
+ public String getRefClass(ObjectOutput out)
+ {
+ return ("UnicastRef");
+ }
+
+ /**
+ * Return the string representing the remote reference information.
+ */
+ public String remoteToString()
+ {
+ if (manager!=null)
+ return manager.toString();
+ else
+ return "null manager";
+ }
+
+ public void dump(UnicastConnection conn)
+ {
+ try
+ {
+ DataInputStream din = conn.getDataInputStream();
+ for (;;)
+ {
+ int b = din.readUnsignedByte();
+ System.out.print(Integer.toHexString(b));
+ if (b >= 32 && b < 128)
+ {
+ System.out.print(": " + (char) b);
+ }
+ System.out.println();
+ }
+ }
+ catch (IOException _)
+ {
+ }
+ }
+
+ /**
+ * Check if this UnicastRef points to the object as the passed UnicastRef.
+ * Both the object Id and manager must be the same.
+ *
+ * @return true if the passed reference points to the same remote object as
+ * this reference, false otherwise.
+ */
+ public boolean equals(Object other)
+ {
+ if (other instanceof UnicastRef)
+ {
+ UnicastRef r = (UnicastRef) other;
+ return r.manager.equals(manager) && r.objid.equals(objid);
+ }
+ else
+ return false;
+ }
+
+ /**
+ * Get the hash code of this UnicastRef, combining hash code of the manager
+ * with hash code of the object id.
+ */
+ public int hashCode()
+ {
+ return manager.hashCode() ^ objid.hashCode();
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java
new file mode 100644
index 000000000..d0d77304c
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteCall.java
@@ -0,0 +1,525 @@
+/* UnicastRemoteCall.java
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 2005
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.StreamCorruptedException;
+import java.rmi.MarshalException;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.ObjID;
+import java.rmi.server.RemoteCall;
+import java.rmi.server.UID;
+import java.util.Vector;
+
+public class UnicastRemoteCall
+ implements RemoteCall, ProtocolConstants
+{
+
+ private UnicastConnection conn;
+ private Object result;
+ private Object object;
+ private int opnum;
+ private long hash;
+ // These are package-private due to inner class access.
+ Vector vec;
+ int ptr;
+ private ObjID objid;
+
+ private ObjectOutput oout;
+ private ObjectInput oin;
+
+ /**
+ * Incoming call.
+ */
+ UnicastRemoteCall(UnicastConnection conn)
+ {
+ this.conn = conn;
+ }
+
+ /**
+ * Outgoing call.
+ */
+ UnicastRemoteCall(UnicastConnection conn, ObjID objid, int opnum, long hash)
+ throws RemoteException
+ {
+ this.conn = conn;
+ this.opnum = opnum;
+ this.hash = hash;
+ this.objid = objid;
+ }
+
+ UnicastConnection getConnection()
+ {
+ return conn;
+ }
+
+ public ObjectOutput getOutputStream() throws IOException
+ {
+ if (vec == null)
+ vec = new Vector();
+ return (new DummyObjectOutputStream());
+ }
+
+ public void releaseOutputStream() throws IOException
+ {
+ if (vec != null)
+ {
+ oout = conn.getObjectOutputStream();
+
+ for (int i = 0; i < vec.size(); i += 2)
+ {
+ boolean primitive = ((Boolean)vec.elementAt(i)).booleanValue();
+ Object data = vec.elementAt(i+1);
+
+ // No type, this is
+ if (!primitive)
+ oout.writeObject(data);
+ else
+ {
+ if (data instanceof Boolean)
+ oout.writeBoolean(((Boolean)data).booleanValue());
+ else if (data instanceof Character)
+ oout.writeChar(((Character)data).charValue());
+ else if (data instanceof Byte)
+ oout.writeByte(((Byte)data).byteValue());
+ else if (data instanceof Short)
+ oout.writeShort(((Short)data).shortValue());
+ else if (data instanceof Integer)
+ oout.writeInt(((Integer)data).intValue());
+ else if (data instanceof Long)
+ oout.writeLong(((Long)data).longValue());
+ }
+ }
+ vec = null;
+ }
+ if(oout != null)
+ oout.flush();
+ }
+
+ /**
+ *
+ * (re)starts ObjectInputStream
+ *
+ */
+ public ObjectInput startInputStream() throws IOException
+ {
+ if (conn != null) {
+ return (oin = conn.startObjectInputStream());
+ } else {
+ return getInputStream(); // dummy Input Stream
+ }
+
+ }
+
+ public ObjectInput getInputStream() throws IOException
+ {
+ if (conn != null)
+ {
+ if(oin == null)
+ return (oin = conn.getObjectInputStream());
+ else
+ return oin;
+ }
+ else
+ {
+ ptr = 0;
+ return (new DummyObjectInputStream());
+ }
+ }
+
+ public void releaseInputStream() throws IOException
+ {
+ // Does nothing.
+ }
+
+ public ObjectOutput getResultStream(boolean success)
+ throws IOException, StreamCorruptedException
+ {
+ vec = new Vector();
+ return new DummyObjectOutputStream();
+ }
+
+ public void executeCall() throws Exception
+ {
+ byte returncode;
+ ObjectInput oin;
+
+ // signal the call when constructing
+ try
+ {
+ DataOutputStream dout = conn.getDataOutputStream();
+ dout.write(MESSAGE_CALL);
+
+ oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
+ objid.write(oout);
+ oout.writeInt(opnum);
+ oout.writeLong(hash);
+ }
+ catch(IOException ex)
+ {
+ throw new MarshalException("Try to write header but failed.", ex);
+ }
+
+ try
+ {
+ releaseOutputStream();
+ DataInputStream din = conn.getDataInputStream();
+ if (din.readByte() != MESSAGE_CALL_ACK)
+ throw new RemoteException("Call not acked");
+
+ oin = startInputStream();
+ returncode = oin.readByte();
+ UID.read(oin);
+ }
+ catch(IOException ex)
+ {
+ throw new UnmarshalException("Try to read header but failed:", ex);
+ }
+
+ //check return code
+ switch(returncode)
+ {
+ case RETURN_ACK: //it's ok
+ return;
+ case RETURN_NACK:
+ Object returnobj;
+ try
+ {
+ returnobj = oin.readObject();
+ }
+ catch(Exception ex2)
+ {
+ throw new UnmarshalException
+ ("Try to read exception object but failed", ex2);
+ }
+
+ if(!(returnobj instanceof Exception))
+ throw new UnmarshalException("Should be Exception type here: "
+ + returnobj);
+ throw (Exception)returnobj;
+
+ default:
+ throw new UnmarshalException("Invalid return code");
+ }
+ }
+
+ public void done() throws IOException
+ {
+ // conn.disconnect();
+ }
+
+ boolean isReturnValue()
+ {
+ return vec.size() > 0;
+ }
+
+ Object returnValue()
+ {
+ // This is not the first one (Boolean) but the second.
+ return vec.elementAt(1);
+ }
+
+ Object[] getArguments()
+ {
+ return vec.toArray();
+ }
+
+ Object getObject()
+ {
+ return object;
+ }
+
+ int getOpnum()
+ {
+ return opnum;
+ }
+
+ long getHash()
+ {
+ return hash;
+ }
+
+ void setReturnValue(Object obj)
+ {
+ vec.removeAllElements();
+ vec.addElement(obj);
+ }
+
+ /**
+ * Dummy object output class.
+ */
+ private class DummyObjectOutputStream implements ObjectOutput
+ {
+ /**
+ * Non-private constructor to reduce bytecode emitted.
+ */
+ DummyObjectOutputStream()
+ {
+ }
+
+ public void writeBoolean(boolean v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(Boolean.valueOf(v));
+ }
+
+ public void writeByte(int v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Byte((byte) v));
+ }
+
+ public void writeChar(int v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Character((char) v));
+ }
+
+ public void writeDouble(double v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Double(v));
+ }
+
+ public void writeFloat(float v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Float(v));
+ }
+
+ public void writeInt(int v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Integer(v));
+ }
+
+ public void writeLong(long v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Long(v));
+ }
+
+ public void writeShort(int v) throws IOException
+ {
+ vec.addElement(Boolean.TRUE);
+ vec.addElement(new Short((short) v));
+ }
+
+ public void writeObject(Object obj) throws IOException
+ {
+ vec.addElement(Boolean.FALSE);
+ vec.addElement(obj);
+ }
+
+ public void write(byte b[]) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void write(byte b[], int off, int len) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void write(int b) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void writeBytes(String s) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void writeChars(String s) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void writeUTF(String str) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void flush() throws IOException
+ {
+ }
+
+ public void close() throws IOException
+ {
+ }
+ } // class DummyObjectOutputStream
+
+ /**
+ * Dummy object input class.
+ */
+ private class DummyObjectInputStream implements ObjectInput
+ {
+ /**
+ * Non-private constructor to reduce bytecode emitted.
+ */
+ DummyObjectInputStream()
+ {
+ }
+
+ public boolean readBoolean() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Boolean) obj).booleanValue();
+ }
+
+ public byte readByte() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Byte) obj).byteValue();
+ }
+
+ public char readChar() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Character) obj).charValue();
+ }
+
+ public double readDouble() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Double) obj).doubleValue();
+ }
+
+ public float readFloat() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Float) obj).floatValue();
+ }
+
+ public int readInt() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Integer) obj).intValue();
+ }
+
+ public long readLong() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Long) obj).longValue();
+ }
+
+ public short readShort() throws IOException
+ {
+ Object obj = vec.elementAt(ptr++);
+ return ((Short) obj).shortValue();
+ }
+
+ public Object readObject() throws IOException
+ {
+ return vec.elementAt(ptr++);
+ }
+
+ public int read(byte b[]) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int read(byte b[], int off, int len) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int read() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public long skip(long n) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int available() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void readFully(byte b[]) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void readFully(byte b[], int off, int len) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public String readLine() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public String readUTF() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int readUnsignedByte() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int readUnsignedShort() throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public int skipBytes(int n) throws IOException
+ {
+ throw new IOException("not required");
+ }
+
+ public void close() throws IOException
+ {
+ }
+ } // class DummyObjectInputStream
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java
new file mode 100644
index 000000000..179f30179
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastRemoteStub.java
@@ -0,0 +1,50 @@
+/* UnicastRemoteStub.java --
+ Copyright (c) 1996, 1997, 1998, 1999 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.rmi.server.RemoteRef;
+import java.rmi.server.RemoteStub;
+
+public class UnicastRemoteStub
+ extends RemoteStub {
+
+public static void setStubRef(RemoteStub stub, RemoteRef ref) {
+ setRef(stub, ref);
+}
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastServer.java b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java
new file mode 100644
index 000000000..db2bd2ff8
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java
@@ -0,0 +1,321 @@
+/* UnicastServer.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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 gnu.java.rmi.dgc.DGCImpl;
+import gnu.java.util.WeakIdentityHashMap;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.ServerError;
+import java.rmi.activation.ActivationException;
+import java.rmi.activation.ActivationID;
+import java.rmi.server.ObjID;
+import java.rmi.server.UID;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+public class UnicastServer
+ implements ProtocolConstants
+{
+
+ /**
+ * Mapping OBJID to server ref by .equals().
+ */
+ static private Map objects = Collections.synchronizedMap(new WeakHashMap());
+
+ /**
+ * Mapping obj itself to server ref by identity.
+ */
+ static private Map refcache = Collections.synchronizedMap(new WeakIdentityHashMap());
+
+ /**
+ * Mapping the registered activatable objects into they server references.
+ */
+ public static Map actIds = new Hashtable();
+
+ /**
+ * The reference to the local distributed garbage collector.
+ */
+ static private DGCImpl dgc;
+
+ /**
+ * Connect this server reference to the server, allowing the local
+ * implementation, associated with this object, to receive remote calls.
+ *
+ * @param obj the server reference, encloses the (usually local) remote
+ * object.
+ */
+ public static void exportObject(UnicastServerRef obj)
+ {
+ startDGC();
+ objects.put(obj.objid, obj);
+ refcache.put(obj.myself, obj);
+ obj.manager.startServer();
+ }
+
+ /**
+ * Register the activatable object into the table of the activatable
+ * objects.
+ */
+ public static void registerActivatable(ActivatableServerRef ref)
+ {
+ actIds.put(ref.actId, ref);
+ }
+
+ /**
+ * Export tha activatable object. The object id is placed into the map,
+ * but the object itself not. This is enough to deliver call to
+ * the ref.incomingMessageCall where the object will be instantiated,
+ * if not present.
+ */
+ public static void exportActivatableObject(ActivatableServerRef ref)
+ {
+ startDGC();
+ objects.put(ref.objid, ref);
+ ref.manager.startServer();
+ actIds.put(ref.actId, ref);
+ }
+
+
+ /**
+ * Get the activatable server reference that is handling activation of the
+ * given activation id.
+ */
+ public static ActivatableServerRef getActivatableRef(ActivationID id)
+ throws ActivationException
+ {
+ ActivatableServerRef ref = (ActivatableServerRef) actIds.get(id);
+ if (ref == null)
+ throw new ActivationException(id + " was not registered with this server");
+ return ref;
+ }
+
+ /**
+ * Unregister the previously registered activatable server reference.
+ */
+ public static void unregisterActivatable(ActivationID id)
+ {
+ actIds.remove(id);
+ }
+
+ // FIX ME: I haven't handle force parameter
+ /**
+ * Remove the given server reference. The remote object, associated with
+ * this reference, will no longer receive remote calls via this server.
+ */
+ public static boolean unexportObject(UnicastServerRef obj, boolean force)
+ {
+ objects.remove(obj.objid);
+ refcache.remove(obj.myself);
+ obj.manager.stopServer();
+
+ if (obj instanceof ActivatableServerRef)
+ {
+ ActivationID id = ((ActivatableServerRef) obj).actId;
+ unregisterActivatable(id);
+ }
+ return true;
+ }
+
+ /**
+ * Get the exported reference of the given Remote. The identity map is used,
+ * the non-null value will only be returned if exactly the passed remote
+ * is part of the registered UnicastServerRef.
+ *
+ * @param remote the Remote that is connected to this server via
+ * {@link UnicastServerRef}.
+ *
+ * @return the UnicastServerRef that is used to connect the passed
+ * remote with this server or null, if this Remote is not connected
+ * to this server.
+ */
+ public static UnicastServerRef getExportedRef(Remote remote)
+ {
+ return (UnicastServerRef) refcache.get(remote);
+ }
+
+ /**
+ * Get the server references to the object, previously exported via this
+ * server. As the identity map is scanned, more than one reference may match
+ * this Id.
+ *
+ * @param id the id of the exported object
+ * @return the server reference to this object, null if none.
+ */
+ public static Collection getExported(Object id)
+ {
+ synchronized (objects)
+ {
+ ArrayList list = new ArrayList();
+ Iterator iter = objects.entrySet().iterator();
+ Map.Entry e;
+ Object key;
+ while (iter.hasNext())
+ {
+ e = (Map.Entry) iter.next();
+ key = e.getKey();
+ if (key != null && key.equals(id))
+ list.add(e.getValue());
+ }
+ return list;
+ }
+ }
+
+ private static synchronized void startDGC()
+ {
+ if (dgc == null)
+ {
+ try
+ {
+ dgc = new DGCImpl();
+ // Changed DGCImpl to inherit UnicastServerRef directly
+ // ((UnicastServerRef)dgc.getRef()).exportObject(dgc);
+ dgc.exportObject(dgc);
+ }
+ catch (RemoteException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void dispatch(UnicastConnection conn) throws Exception
+ {
+ switch (conn.getDataInputStream().readUnsignedByte())
+ {
+ case MESSAGE_CALL:
+ incomingMessageCall(conn);
+ break;
+ case MESSAGE_PING:
+ // jdk sends a ping before each method call -> answer it!
+ DataOutputStream out = conn.getDataOutputStream();
+ out.writeByte(MESSAGE_PING_ACK);
+ out.flush();
+ break;
+ default:
+ throw new Exception("bad method type");
+ }
+ }
+
+ /**
+ * This method is invoked when the remote call is received. The method
+ * dispatches the call to the responsible object, connected to this
+ * server via UnicastServerReference.
+ */
+ private static void incomingMessageCall(UnicastConnection conn)
+ throws IOException
+ {
+ ObjectInputStream in = conn.startObjectInputStream(); // (re)start
+ // ObjectInputStream
+
+ ObjID objid = ObjID.read(in);
+ int method = in.readInt();
+ long hash = in.readLong();
+
+ // System.out.println("ObjID: " + objid + ", method: " + method + ", hash: "
+ // + hash);
+
+ // Use the objid to locate the relevant UnicastServerRef
+ 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;
+ returncode = RETURN_NACK;
+ }
+ catch (Error e)
+ {
+ returnval = new ServerError(
+ "Server error, ObjID: " + objid +
+ ", method: " + method + ", hash: "+ hash, e);
+ returncode = RETURN_NACK;
+ }
+ }
+ else
+ {
+ returnval = new NoSuchObjectException("ObjID: " + objid);
+ returncode = RETURN_NACK;
+ }
+
+ conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
+
+ ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start
+ // ObjectOutputStream
+
+ out.writeByte(returncode);
+ (new UID()).write(out);
+
+ // System.out.println("returnval=" + returnval + " returncls=" + returncls);
+
+ if (returnval != null && returncls != null)
+ ((RMIObjectOutputStream) out).writeValue(returnval, returncls);
+
+ // 1.1/1.2 void return type detection:
+ else if (! (returnval instanceof RMIVoidValue || returncls == Void.TYPE))
+ out.writeObject(returnval);
+
+ out.flush();
+ }
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java b/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java
new file mode 100644
index 000000000..59a9f080b
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/UnicastServerRef.java
@@ -0,0 +1,481 @@
+/* UnicastServerRef.java --
+ Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
+ 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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.io.ObjectInputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.ObjID;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteRef;
+import java.rmi.server.RemoteServer;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.Skeleton;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+
+/**
+ * This class connects the local, remotely available (exported) object to
+ * the local RMI server that accepts the remote calls.
+ */
+public class UnicastServerRef
+ extends UnicastRef
+{
+
+ /**
+ * Use GNU Classpath v 0.20 SVUID for interoperability
+ */
+ private static final long serialVersionUID = - 5585608108300801246L;
+
+ /**
+ * The class array, defining parameters of the jdk 1.2 RMI stub constructor.
+ */
+ private static final Class[] stubprototype = new Class[] { RemoteRef.class };
+
+ /**
+ * The exported remote object itself.
+ */
+ Remote myself; // save the remote object itself
+
+ /**
+ * The skeleton (if any), associated with the exported remote object.
+ */
+ protected Skeleton skel;
+
+ /**
+ * The stub, associated with the exported remote object (may be proxy class).
+ */
+ protected Remote stub;
+
+ /**
+ * The method table (RMI hash code to method) of the methods of the
+ * exported object.
+ */
+ protected Hashtable methods = new Hashtable();
+
+ /**
+ * Used by serialization.
+ */
+ UnicastServerRef()
+ {
+ }
+
+ public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf)
+ throws RemoteException
+ {
+ super(id);
+ manager = UnicastConnectionManager.getInstance(port, ssf);
+ }
+
+ /**
+ * Export the object and return its remote stub. The method tries to locate
+ * existing stubs and skeletons. If this fails, the method instantiates the
+ * proxy stub class.
+ *
+ * Stubs and skeletons are always ignored (even if present) if the
+ * java.rmi.server.ignoreStubClasses property is set to true.
+ *
+ * @param obj the object being exported.
+ * @return the stub (existing class or proxy) of the exported object.
+ * @throws RemoteException if the export failed due any reason
+ */
+ public Remote exportObject(Remote obj) throws RemoteException
+ {
+ if (myself == null)
+ {
+ myself = obj;
+ // Save it to server manager, to let client calls in the same VM to
+ // issue local call
+ manager.serverobj = obj;
+
+ String ignoreStubs;
+
+ ClassLoader loader =obj.getClass().getClassLoader();
+
+ // Stubs are always searched for the bootstrap classes that may have
+ // obsolete pattern and may still need also skeletons.
+ if (loader==null)
+ ignoreStubs = "false";
+ else
+ ignoreStubs = System.getProperty("java.rmi.server.ignoreStubClasses",
+ "false");
+
+ if (! ignoreStubs.equals("true"))
+ {
+ // Find and install the stub
+ Class cls = obj.getClass();
+
+ // where ist the _Stub? (check superclasses also)
+ Class expCls = findStubSkelClass(cls);
+
+ if (expCls != null)
+ {
+ stub = (RemoteStub) getHelperClass(expCls, "_Stub");
+ // Find and install the skeleton (if there is one)
+ skel = (Skeleton) getHelperClass(expCls, "_Skel");
+ }
+ }
+
+ if (stub == null)
+ stub = createProxyStub(obj.getClass(), this);
+
+ // Build hash of methods which may be called.
+ buildMethodHash(obj.getClass(), true);
+
+ // Export it.
+ UnicastServer.exportObject(this);
+ }
+
+ return stub;
+ }
+
+ /**
+ * Get the stub (actual class or proxy) of the exported remote object.
+ *
+ * @return the remote stub (null if exportObject has not been called).
+ */
+ public Remote getStub()
+ {
+ return stub;
+ }
+
+ /**
+ * Unexport the object (remove methods from the method hashcode table
+ * and call UnicastServer.unexportObject.
+ *
+ * @param obj the object being unexported
+ * @param force passed to the UnicastServer.unexportObject.
+ * @return value, returned by the UnicastServer.unexportObject.
+ */
+ public boolean unexportObject(Remote obj, boolean force)
+ {
+ // Remove all hashes of methods which may be called.
+ buildMethodHash(obj.getClass(), false);
+ return UnicastServer.unexportObject(this, force);
+ }
+
+ /**
+ * Return the class in the hierarchy for that the stub class is defined.
+ * The Subs/Skels might not there for the actual class, but maybe for one of
+ * the superclasses.
+ *
+ * @return the class having stub defined, null if none.
+ */
+ protected Class findStubSkelClass(Class startCls)
+ {
+ Class cls = startCls;
+
+ while (true)
+ {
+ try
+ {
+ String stubClassname = cls.getName() + "_Stub";
+ ClassLoader cl = cls.getClassLoader();
+ Class scls = cl == null ? Class.forName(stubClassname)
+ : cl.loadClass(stubClassname);
+ return cls; // found it
+ }
+ catch (ClassNotFoundException e)
+ {
+ Class superCls = cls.getSuperclass();
+ if (superCls == null
+ || superCls == java.rmi.server.UnicastRemoteObject.class)
+ {
+ return null;
+ }
+ cls = superCls;
+ }
+ }
+ }
+
+ /**
+ * Get the helper (assisting) class with the given type.
+ *
+ * @param cls the class, for that the helper class is requested. This class
+ * and the requested helper class must share the same class loader.
+ *
+ * @param type the type of the assisting helper. The only currently supported
+ * non deprecated value is "_Stub" (load jdk 1.1 or 1.2 RMI stub). Another
+ * (deprecated) value is "_Skel" (load skeleton).
+ *
+ * @return the instantiated instance of the helper class or null if the
+ * helper class cannot be found or instantiated.
+ */
+ protected Object getHelperClass(Class cls, String type)
+ {
+ try
+ {
+ String classname = cls.getName();
+ ClassLoader cl = cls.getClassLoader();
+ Class scls = cl == null ? Class.forName(classname + type)
+ : cl.loadClass(classname + type);
+ if (type.equals("_Stub"))
+ {
+ try
+ {
+ // JDK 1.2 stubs
+ Constructor con = scls.getConstructor(stubprototype);
+ return (con.newInstance(new Object[] { this }));
+ }
+ catch (NoSuchMethodException e)
+ {
+ }
+ catch (InstantiationException e)
+ {
+ }
+ catch (IllegalAccessException e)
+ {
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ catch (InvocationTargetException e)
+ {
+ }
+ // JDK 1.1 stubs
+ RemoteStub stub = (RemoteStub) scls.newInstance();
+ UnicastRemoteStub.setStubRef(stub, this);
+ return (stub);
+ }
+ else
+ {
+ // JDK 1.1 skel
+ return (scls.newInstance());
+ }
+ }
+ catch (ClassNotFoundException e)
+ {
+ }
+ catch (InstantiationException e)
+ {
+ }
+ catch (IllegalAccessException e)
+ {
+ }
+ return (null);
+ }
+
+ public String getClientHost() throws ServerNotActiveException
+ {
+ return RemoteServer.getClientHost();
+ }
+
+ /**
+ * Build the method has code table and put it into {@link #methods}
+ * (mapping RMI hashcode tos method). The same method is used to remove
+ * the table.
+ *
+ * @param cls the class for that the method table is built.
+ * @param build if true, the class methods are added to the table. If
+ * false, they are removed from the table.
+ */
+ protected 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 */
+ if (meths[i].getDeclaringClass().getName().startsWith("java."))
+ {
+ continue;
+ }
+ long hash = RMIHashes.getMethodHash(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;
+ }
+
+ /**
+ * This method is called from the {@link UnicastServer#incomingMessageCall}
+ * to deliver the remote call to this object.
+ */
+ 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
+ // to locate the method
+ if (method == - 1)
+ {
+ Method meth = (Method) methods.get(new Long(hash));
+ // System.out.println("class = " + myself.getClass() + ", meth = " +
+ // meth);
+ if (meth == null)
+ {
+ throw new NoSuchMethodException(
+ myself.getClass().getName()+" hash "+hash);
+ }
+
+ ObjectInputStream in = conn.getObjectInputStream();
+ int nrargs = meth.getParameterTypes().length;
+ Object[] args = new Object[nrargs];
+ for (int i = 0; i < nrargs; i++)
+ {
+ /**
+ * For debugging purposes - we don't handle CodeBases quite right so
+ * we don't always find the stubs. This lets us know that.
+ */
+ try
+ {
+ // need to handle primitive types
+ args[i] = ((RMIObjectInputStream) in)
+ .readValue(meth.getParameterTypes()[i]);
+
+ }
+ catch (Exception t)
+ {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+ //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)
+ {
+ Throwable cause = e.getTargetException();
+ if (cause instanceof Exception)
+ {
+ throw (Exception) cause;
+ }
+ else if (cause instanceof Error)
+ {
+ throw (Error) cause;
+ }
+ else
+ {
+ throw new Error(
+ "The remote method threw a java.lang.Throwable that"+
+ " is neither java.lang.Exception nor java.lang.Error.",
+ e);
+ }
+ }
+ 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
+ // connection system in a UnicastRemoteCall so it appears in a
+ // way the Skeleton can handle.
+ else
+ {
+ if (skel == null)
+ throw new NoSuchMethodException("JDK 1.1 call - Skeleton required");
+
+ UnicastRemoteCall call = new UnicastRemoteCall(conn);
+ skel.dispatch(myself, call, method, hash);
+ if (! call.isReturnValue())
+ return RMIVoidValue.INSTANCE;
+ else
+ return (call.returnValue());
+ }
+ }
+
+ /**
+ * Create the 1.2 proxy stub in the case when the pre-generated stub is not
+ * available of the system is explicitly instructed to use proxy stubs.
+ *
+ * @param stubFor the class for that the proxy class must be constructed.
+ * @param reference the remote reference, used to find the given object
+ *
+ * @return the applicable proxy stub.
+ *
+ * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
+ */
+ Remote createProxyStub(Class stubFor, RemoteRef reference)
+ {
+ // Collect all interfaces, implemented by stubFor and derived from
+ // Remote (also Remote itself):
+ HashSet interfaces = new HashSet();
+ Class c = stubFor;
+ Class[] intfs;
+
+ while (c != null)
+ {
+ intfs = c.getInterfaces();
+ for (int i = 0; i < intfs.length; i++)
+ {
+ if (Remote.class.isAssignableFrom(intfs[i]))
+ interfaces.add(intfs[i]);
+ }
+ c = c.getSuperclass();
+ }
+
+ intfs = new Class[interfaces.size()];
+ Iterator it = interfaces.iterator();
+
+ for (int i = 0; i < intfs.length; i++)
+ intfs[i] = (Class) it.next();
+
+ RemoteObjectInvocationHandler handler =
+ new RemoteObjectInvocationHandler(reference);
+
+ Object proxy =
+ Proxy.newProxyInstance(stubFor.getClassLoader(), intfs, handler);
+
+ return (Remote) proxy;
+ }
+
+
+}
diff --git a/libjava/classpath/gnu/java/rmi/server/package.html b/libjava/classpath/gnu/java/rmi/server/package.html
new file mode 100644
index 000000000..08c105b49
--- /dev/null
+++ b/libjava/classpath/gnu/java/rmi/server/package.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!-- package.html - describes classes in gnu.java.rmi.server package.
+ Copyright (C) 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 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. -->
+
+<html>
+<head><title>GNU Classpath - gnu.java.rmi.server</title></head>
+
+<body>
+<p></p>
+
+</body>
+</html>