summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/java/rmi/server
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/rmi/server')
-rw-r--r--libjava/classpath/java/rmi/server/ObjID.java202
-rw-r--r--libjava/classpath/java/rmi/server/Operation.java8
-rw-r--r--libjava/classpath/java/rmi/server/RemoteObject.java124
-rw-r--r--libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java10
-rw-r--r--libjava/classpath/java/rmi/server/RemoteServer.java99
-rw-r--r--libjava/classpath/java/rmi/server/UID.java262
6 files changed, 497 insertions, 208 deletions
diff --git a/libjava/classpath/java/rmi/server/ObjID.java b/libjava/classpath/java/rmi/server/ObjID.java
index 07cbbde3a62..1aaa223602c 100644
--- a/libjava/classpath/java/rmi/server/ObjID.java
+++ b/libjava/classpath/java/rmi/server/ObjID.java
@@ -1,5 +1,6 @@
-/* ObjID.java --
- Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+/* ObjID.java -- Unique object id with respect to the given host.
+ Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,59 +46,152 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
-public final class ObjID implements Serializable
+/**
+ * Represents the object identifier, unique for the host that generated it.
+ * The ObjID contains inside the integer object identifier that, if needed,
+ * may indicated that this is a reference to one of the well known objects
+ * on that host (registry, activator or dgc) and the {@link UID} that
+ * ensures uniqueness.
+ */
+public final class ObjID
+ implements Serializable
{
-static final long serialVersionUID = -6386392263968365220L;
-private static long next = 0x8000000000000000L;
-private static final Object lock = ObjID.class;
-
-public static final int REGISTRY_ID = 0;
-public static final int ACTIVATOR_ID = 1;
-public static final int DGC_ID = 2;
-
-private long objNum;
-private UID space;
-
-public ObjID() {
- synchronized (lock) {
- objNum = next++;
- }
- space = new UID();
-}
-
-public ObjID(int num) {
- objNum = (long)num;
- space = new UID((short)0);
-}
-
-public void write(ObjectOutput out) throws IOException {
- DataOutput dout = (DataOutput)out;
- dout.writeLong(objNum);
- space.write(dout);
-}
-
-public static ObjID read(ObjectInput in) throws IOException {
- DataInput din = (DataInput)in;
- ObjID id = new ObjID();
- id.objNum = din.readLong();
- id.space = UID.read(din);
- return (id);
-}
-
-public int hashCode() {
- return ((int)objNum);
-}
-
-public boolean equals(Object obj) {
- if (obj instanceof ObjID && this.objNum == ((ObjID)obj).objNum) {
- return (true);
- }
- return (false);
-}
-
-public String toString() {
- return ("[objNum: " + objNum + ", " + space + "]");
-}
+ /**
+ * Use serial version uid for interoperability.
+ */
+ static final long serialVersionUID = - 6386392263968365220L;
+
+ /**
+ * The object counter, which value is assigned when creating the ordinary
+ * objects without the known object id. The counter is incremented each time
+ * the new ObjID is constructed.
+ */
+ private static long next = 0x8000000000000000L;
+
+ /**
+ * The object to put the lock on when incrementing {@link #next}
+ */
+ private static final Object lock = ObjID.class;
+
+ /**
+ * Defines the ID of the naming service.
+ */
+ public static final int REGISTRY_ID = 0;
+
+ /**
+ * Defines the ID of the activator.
+ */
+ public static final int ACTIVATOR_ID = 1;
+
+ /**
+ * Defines the ID of the distributed garbage collector.
+ */
+ public static final int DGC_ID = 2;
+
+ /**
+ * The object Id (either well-known value or the value of the incrementing
+ * object counter.
+ */
+ long objNum;
+
+ /**
+ * The object unique identifier, generated individually for each object.
+ */
+ UID space;
+
+ /**
+ * Create the new object id, unique for this host.
+ */
+ public ObjID()
+ {
+ synchronized (lock)
+ {
+ objNum = next++;
+ }
+ space = new UID();
+ }
+
+ /**
+ * Create the new object id defining the well known remotely accessible
+ * object, present in this host. The well - known objects are:
+ * <ul>
+ * <li>{@link #REGISTRY_ID} - RMI naming service.</li>
+ * <li>{@link #ACTIVATOR_ID} - activator</li>
+ * <li>{@link #DGC_ID} - distributed garbage collector (grants lease
+ * durations to keep the object before it is garbage collected.</li>
+ * </ul>
+ *
+ * @param id the well known object id, one of the above.
+ */
+ public ObjID(int id)
+ {
+ objNum = (long) id;
+ space = new UID((short) 0);
+ }
+
+ /**
+ * Write object id as long, then the object {@link UID}.
+ */
+ public void write(ObjectOutput out) throws IOException
+ {
+ DataOutput dout = (DataOutput) out;
+ dout.writeLong(objNum);
+ space.write(dout);
+ }
+
+ /**
+ * Read object id (as long), then the object {@link UID}.
+ */
+ public static ObjID read(ObjectInput in) throws IOException
+ {
+ DataInput din = (DataInput) in;
+ ObjID id = new ObjID();
+ id.objNum = din.readLong();
+ id.space = UID.read(din);
+ return (id);
+ }
+
+ /**
+ * Get the hashcode.
+ */
+ public int hashCode()
+ {
+ return space == null ? (int) objNum : space.hashCode() ^ (int) objNum;
+ }
+
+ /**
+ * Compare for equality.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof ObjID)
+ {
+ ObjID that = (ObjID) obj;
+ return that.objNum == objNum && eq(that.space, space);
+ }
+ else
+ return false;
+ }
+
+ /**
+ * Compare by .equals if both a and b are not null, compare directly if at
+ * least one of them is null.
+ */
+ static final boolean eq(Object a, Object b)
+ {
+ if (a == null || b == null)
+ return a == b;
+ else
+ return a.equals(b);
+ }
+
+ /**
+ * Get the string representation.
+ */
+ public String toString()
+ {
+ return (objNum + ":" + space);
+ }
}
diff --git a/libjava/classpath/java/rmi/server/Operation.java b/libjava/classpath/java/rmi/server/Operation.java
index 64faf66e2f8..f7b5f02cc0b 100644
--- a/libjava/classpath/java/rmi/server/Operation.java
+++ b/libjava/classpath/java/rmi/server/Operation.java
@@ -38,6 +38,9 @@ exception statement from your version. */
package java.rmi.server;
/**
+ * This class was used with jdk 1.1 stubs and skeletons. It is no longer
+ * needed since jdk 1.2 and higher.
+ *
* @deprecated
*/
public class Operation
@@ -45,6 +48,7 @@ public class Operation
private String operation;
/**
+ * Create operation with the given name.
* @deprecated
*/
public Operation (String op)
@@ -53,6 +57,8 @@ public class Operation
}
/**
+ * Get the name of the operation.
+ *
* @deprecated
*/
public String getOperation ()
@@ -61,6 +67,8 @@ public class Operation
}
/**
+ * Return the name of the operation.
+ *
* @deprecated
*/
public String toString ()
diff --git a/libjava/classpath/java/rmi/server/RemoteObject.java b/libjava/classpath/java/rmi/server/RemoteObject.java
index 60e57dc2428..5b926bfc34e 100644
--- a/libjava/classpath/java/rmi/server/RemoteObject.java
+++ b/libjava/classpath/java/rmi/server/RemoteObject.java
@@ -39,6 +39,7 @@ package java.rmi.server;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.rmi.NoSuchObjectException;
@@ -101,6 +102,9 @@ public boolean equals(Object obj) {
return (this == obj);
}
+/**
+ * Get the string representation of this remote object.
+ */
public String toString()
{
if (ref == null)
@@ -108,55 +112,91 @@ public boolean equals(Object obj) {
return (ref.toString ());
}
- private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+ /**
+ * Read the remote object from the input stream. Expects the class name
+ * without package first. Then the method creates and assigns the {@link #ref}
+ * an instance of this class and calls its .readExternal method. The standard
+ * packageless class names are UnicastRef, UnicastRef2, UnicastServerRef,
+ * UnicastServerRef2, ActivatableRef or ActivatableServerRef.
+ *
+ * @param in the stream to read from
+ * @throws IOException if the IO exception occurs
+ * @throws ClassNotFoundException if the class with the given name is not
+ * present in the package gnu.java.rmi.server (for the case of the
+ * GNU Classpath.
+ */
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException
{
String cname = in.readUTF();
- if (!cname.equals(""))
+ if (! cname.equals(""))
{
- if (cname.equals ("UnicastRef2"))
- {
- // hack for interoperating with JDK
- cname = "UnicastRef";
- in.read (); //some unknown UnicastRef2 field
- }
-
- // It would be nice to use RemoteRef.packagePrefix here, but for binary
- // compatibility with the JDK that has to contain "sun.rmi.server"...
- cname = "gnu.java.rmi.server." + cname;
- try
- {
- Class cls = Class.forName(cname);
- ref = (RemoteRef)cls.newInstance();
- }
- catch (InstantiationException e1)
- {
- throw new UnmarshalException("failed to create ref", e1);
- }
- catch (IllegalAccessException e2)
- {
- throw new UnmarshalException("failed to create ref", e2);
- }
- ref.readExternal(in);
+ if (cname.equals("UnicastRef2"))
+ {
+ // hack for interoperating with JDK
+ cname = "UnicastRef";
+ in.read(); // some unknown UnicastRef2 field
+ }
+
+ // It would be nice to use RemoteRef.packagePrefix here, but for binary
+ // compatibility with the JDK that has to contain "sun.rmi.server"...
+ cname = "gnu.java.rmi.server." + cname;
+ try
+ {
+ Class cls = Class.forName(cname);
+ ref = (RemoteRef) cls.newInstance();
+ }
+ catch (InstantiationException e1)
+ {
+ throw new UnmarshalException("failed to create ref", e1);
+ }
+ catch (IllegalAccessException e2)
+ {
+ throw new UnmarshalException("failed to create ref", e2);
+ }
+ ref.readExternal(in);
}
- else
+ else
{
- ref = (RemoteRef)in.readObject();
+ ref = (RemoteRef) in.readObject();
}
}
-private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException {
- if (ref == null) {
- throw new UnmarshalException("no ref to serialize");
- }
- String cname = ref.getRefClass(out);
- if (cname != null && cname.length() > 0) {
- out.writeUTF(cname);
- ref.writeExternal(out);
- }
- else {
- out.writeUTF("");
- out.writeObject(ref);
- }
-}
+ /**
+ * Write the remote object to the output stream. This method first calls
+ * {@link RemoteRef#getRefClass(ObjectOutput)} on the {@link #ref} to get the
+ * class name without package, writes this name and then calls the
+ * ref.writeObject to write the data. The standard packageless class names are
+ * UnicastRef, UnicastRef2, UnicastServerRef, UnicastServerRef2,
+ * ActivatableRef or ActivatableServerRef. The empty string with the
+ * subsequently following serialized ref instance be written if the
+ * ref.getRefClass returns null.
+ *
+ * @param out the stream to write to
+ * @throws IOException if one occurs during writing
+ * @throws ClassNotFoundException never in this implementation (specified as
+ * part of the API standard)
+ * @throws UnmarshalException if the remote reference of this remote object is
+ * null.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException,
+ ClassNotFoundException
+ {
+ if (ref == null)
+ {
+ throw new UnmarshalException("no ref to serialize");
+ }
+ String cname = ref.getRefClass(out);
+ if (cname != null && cname.length() > 0)
+ {
+ out.writeUTF(cname);
+ ref.writeExternal(out);
+ }
+ else
+ {
+ out.writeUTF("");
+ out.writeObject(ref);
+ }
+ }
}
diff --git a/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java b/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java
index afd1d592715..2c19cd5afc4 100644
--- a/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java
+++ b/libjava/classpath/java/rmi/server/RemoteObjectInvocationHandler.java
@@ -90,6 +90,11 @@ public class RemoteObjectInvocationHandler extends RemoteObject implements
static final Class[] anObjectC = new Class[] { Object.class };
/**
+ * The empty object array to replace null when no args are passed.
+ */
+ static final Object[] noArgs = new Object[0];
+
+ /**
* Construct the remote invocation handler that forwards calls to the given
* remote object.
*
@@ -143,6 +148,9 @@ public class RemoteObjectInvocationHandler extends RemoteObject implements
throw new IllegalAccessException(name + " does not implement "
+ Remote.class.getName());
}
+
+ if (parameters == null)
+ parameters = noArgs;
String name = method.getName();
switch (name.charAt(0))
@@ -172,7 +180,7 @@ public class RemoteObjectInvocationHandler extends RemoteObject implements
break;
case 't':
if (parameters.length == 0 && name.equals("toString"))
- return proxyInstance.toString();
+ return "Proxy stub:"+ref.remoteToString();
break;
default:
break;
diff --git a/libjava/classpath/java/rmi/server/RemoteServer.java b/libjava/classpath/java/rmi/server/RemoteServer.java
index 9efb12a782d..f022b732604 100644
--- a/libjava/classpath/java/rmi/server/RemoteServer.java
+++ b/libjava/classpath/java/rmi/server/RemoteServer.java
@@ -1,5 +1,6 @@
/* RemoteServer.java --
- Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+ Copyright (c) 1996, 1997, 1998, 1999, 2004, 2006
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,6 +36,7 @@ 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 java.rmi.server;
import gnu.java.rmi.server.RMIIncomingThread;
@@ -42,35 +44,72 @@ import gnu.java.rmi.server.RMIIncomingThread;
import java.io.OutputStream;
import java.io.PrintStream;
-public abstract class RemoteServer extends RemoteObject
+/**
+ * A common superclass for the server implementations.
+ */
+public abstract class RemoteServer
+ extends RemoteObject
{
-private static final long serialVersionUID = -4100238210092549637L;
-
-protected RemoteServer() {
- super();
-}
-
-protected RemoteServer(RemoteRef ref) {
- super(ref);
-}
-
-public static String getClientHost() throws ServerNotActiveException {
- Thread currThread = Thread.currentThread();
- if (currThread instanceof RMIIncomingThread) {
- RMIIncomingThread incomingThread = (RMIIncomingThread) currThread;
- return incomingThread.getClientHost();
- } else {
- throw new ServerNotActiveException(
- "Unknown client host - current thread not instance of 'RMIIncomingThread'");
- }
-}
-
-public static void setLog(OutputStream out) {
- throw new Error("Not implemented");
-}
-
-public static PrintStream getLog() {
- throw new Error("Not implemented");
-}
+ private static final long serialVersionUID = - 4100238210092549637L;
+
+ /**
+ * Does nothing, delegates to super().
+ */
+ protected RemoteServer()
+ {
+ super();
+ }
+
+ /**
+ * Does nothing, delegates to super(ref).
+ */
+ protected RemoteServer(RemoteRef ref)
+ {
+ super(ref);
+ }
+
+ /**
+ * Get the host of the calling client. The current thread must be an instance
+ * of the {@link RMIIncomingThread}.
+ *
+ * @return the client host address
+ *
+ * @throws ServerNotActiveException if the current thread is not an instance
+ * of the RMIIncomingThread.
+ */
+ public static String getClientHost() throws ServerNotActiveException
+ {
+ Thread currThread = Thread.currentThread();
+ if (currThread instanceof RMIIncomingThread)
+ {
+ RMIIncomingThread incomingThread = (RMIIncomingThread) currThread;
+ return incomingThread.getClientHost();
+ }
+ else
+ {
+ throw new ServerNotActiveException(
+ "Unknown client host - current thread not instance of 'RMIIncomingThread'");
+ }
+ }
+
+ /**
+ * Set the stream for logging RMI calls.
+ *
+ * @param out the stream to set or null to turn the logging off.
+ */
+ public static void setLog(OutputStream out)
+ {
+ throw new Error("Not implemented");
+ }
+
+ /**
+ * Get the stream for logging RMI calls.
+ *
+ * @return the associated stream.
+ */
+ public static PrintStream getLog()
+ {
+ throw new Error("Not implemented");
+ }
}
diff --git a/libjava/classpath/java/rmi/server/UID.java b/libjava/classpath/java/rmi/server/UID.java
index 0f492bae77a..35963042211 100644
--- a/libjava/classpath/java/rmi/server/UID.java
+++ b/libjava/classpath/java/rmi/server/UID.java
@@ -1,5 +1,5 @@
-/* UID.java --
- Copyright (c) 1996, 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+/* UID.java -- The unique object Id
+ Copyright (c) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,86 +42,186 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.io.Serializable;
-
-public final class UID implements Serializable
-{
-private static final long serialVersionUID = 1086053664494604050L;
-
-private static final Object lock = UID.class;
-private static long baseTime = System.currentTimeMillis();
-private static short nextCount = Short.MIN_VALUE;
-// This is sun's algorithm - don't ask me why ...
-private static final int uniqueNr = (new Object()).hashCode();
-
-private int unique;
-private long time;
-private short count;
+import java.net.InetAddress;
/**
- * This is sun's algorithm - don't ask me why ...
+ * Represents the unique identifier over time for the host which has generated
+ * it. It contains time (when created), counter (the number of the UID
+ * creation order) and virtual machine id components. The UID can also be
+ * constructed specifying a "well known" identifier in the for of short:
+ * this identifier defines the UID uniqueness alone.
+ *
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
-public UID() {
- synchronized (lock) {
- if (nextCount == Short.MAX_VALUE) {
- long newtime;
- for (;;) {
- newtime = System.currentTimeMillis();
- if (newtime - baseTime > 1000) {
- break;
- }
- try {
- Thread.sleep(1000);
- }
- catch (InterruptedException _) {
- }
- }
- baseTime = newtime;
- nextCount = Short.MIN_VALUE;
- }
- count = nextCount++;
- unique = uniqueNr;
- time = baseTime;
- }
-}
-
-public UID(short num) {
- unique = (int)num;
- time = 0;
- count = 0;
-}
-
-public int hashCode() {
- return (unique);
-}
-
-public boolean equals(Object obj) {
- if (obj instanceof UID) {
- UID uid = (UID)obj;
- if (this.unique == uid.unique &&
- this.time == uid.time &&
- this.count == uid.count) {
- return (true);
- }
- }
- return (false);
-}
-
-public String toString() {
- return ("[UID: " + unique + "," + time + "," + count + "]");
-}
-
-public void write(DataOutput out) throws IOException {
- out.writeInt(unique);
- out.writeLong(time);
- out.writeShort(count);
-}
-
-public static UID read(DataInput in) throws IOException {
- UID id = new UID();
- id.unique = in.readInt();
- id.time = in.readLong();
- id.count = in.readShort();
- return (id);
-}
-
+public final class UID
+ implements Serializable
+{
+ /**
+ * Use the serial version uid for interoperability.
+ */
+ private static final long serialVersionUID = 1086053664494604050L;
+
+ /**
+ * The UID counter (the ordinary number in the sequence of number of UID's,
+ * created during the recent millisecond). In the next millisecond, it
+ * starts from the minimal value again. In the unlikely case of creating
+ * more than 65536 uids per millisecond the process pauses till the next
+ * ms.
+ */
+ private static short uidCounter = Short.MIN_VALUE;
+
+ /**
+ * The time, when the last UID has been created.
+ */
+ private static long last;
+
+ /**
+ * This constant tries to be the unique identifier of the virtual machine.
+ */
+ private static final int machineId = getMachineId();
+
+ /**
+ * The UID number in the UID creation sequence.
+ */
+ private short count;
+
+ /**
+ * Always gets the uniqueNr value.
+ */
+ private int unique;
+
+ /**
+ * The time stamp, when the UID was created.
+ */
+ private long time;
+
+ /**
+ * Create the new UID that would have the described features of the
+ * uniqueness.
+ */
+ public UID()
+ {
+ time = System.currentTimeMillis();
+ unique = machineId;
+ if (time > last)
+ {
+ last = time;
+ count = uidCounter = Short.MIN_VALUE;
+ }
+ else
+ {
+ synchronized (UID.class)
+ {
+ if (uidCounter == Short.MAX_VALUE)
+ {
+ // Make a 2 ms pause if the counter has reached the maximal
+ // value. This should seldom happen.
+ try
+ {
+ Thread.sleep(2);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ uidCounter = Short.MIN_VALUE;
+ time = last = System.currentTimeMillis();
+ }
+
+ count = uidCounter++;
+ }
+ }
+ }
+
+ /**
+ * Create the new UID with the well known id (number). All UIDs, creates
+ * with the this constructor having the same parameter are equal to each
+ * other (regardless to the host and time where they were created.
+ *
+ * @param wellKnownId the well known UID.
+ */
+ public UID(short wellKnownId)
+ {
+ unique = wellKnownId;
+ }
+
+ /**
+ * Get the hashCode of this UID.
+ */
+ public int hashCode()
+ {
+ return (int) (unique ^ time ^ count);
+ }
+
+ /**
+ * Compare this UID with another UID for equality (not equal to other types of
+ * objects).
+ */
+ public boolean equals(Object other)
+ {
+ if (other instanceof UID)
+ {
+ UID ui = (UID) other;
+ return unique == ui.unique && time == ui.time && count == ui.count;
+ }
+ else
+ return false;
+ }
+
+ public static UID read(DataInput in) throws IOException
+ {
+ UID uid = new UID();
+ uid.unique = in.readInt();
+ uid.time = in.readLong();
+ uid.count = in.readShort();
+ return (uid);
+ }
+
+ public void write(DataOutput out) throws IOException
+ {
+ out.writeInt(unique);
+ out.writeLong(time);
+ out.writeShort(count);
+ }
+
+ /**
+ * Do our best to get the Id of this virtual machine.
+ */
+ static int getMachineId()
+ {
+ int hostIpHash;
+
+ try
+ {
+ // Try to get the host IP.
+ String host = InetAddress.getLocalHost().toString();
+ // This hash is content - based, not the address based.
+ hostIpHash = host.hashCode();
+ }
+ catch (Exception e)
+ {
+ // Failed due some reason.
+ hostIpHash = 0;
+ }
+
+ // Should be the unque address if hashcodes are addresses.
+ // Additionally, add the time when the RMI system was probably started
+ // (this class was first instantiated).
+ return new Object().hashCode() ^ (int) System.currentTimeMillis()
+ ^ hostIpHash;
+ }
+
+ /**
+ * Get the string representation of this UID.
+ *
+ * @return a string, uniquely identifying this id.
+ */
+ public String toString()
+ {
+ int max = Character.MAX_RADIX;
+ // Translate into object count, counting from 0.
+ long lc = (count + Short.MIN_VALUE) & 0xFFFF;
+ return Long.toString(time, max) + ":"
+ + Long.toString(unique, max) + ":"
+ + Long.toString(lc, max);
+ }
}
OpenPOWER on IntegriCloud