Imported GNU Classpath 0.90
Imported GNU Classpath 0.90 * scripts/makemake.tcl: LocaleData.java moved to gnu/java/locale. * sources.am: Regenerated. * gcj/javaprims.h: Regenerated. * Makefile.in: Regenerated. * gcj/Makefile.in: Regenerated. * include/Makefile.in: Regenerated. * testsuite/Makefile.in: Regenerated. * gnu/java/lang/VMInstrumentationImpl.java: New override. * gnu/java/net/local/LocalSocketImpl.java: Likewise. * gnu/classpath/jdwp/VMMethod.java: Likewise. * gnu/classpath/jdwp/VMVirtualMachine.java: Update to latest interface. * java/lang/Thread.java: Add UncaughtExceptionHandler. * java/lang/reflect/Method.java: Implements GenericDeclaration and isSynthetic(), * java/lang/reflect/Field.java: Likewise. * java/lang/reflect/Constructor.java * java/lang/Class.java: Implements Type, GenericDeclaration, getSimpleName() and getEnclosing*() methods. * java/lang/Class.h: Add new public methods. * java/lang/Math.java: Add signum(), ulp() and log10(). * java/lang/natMath.cc (log10): New function. * java/security/VMSecureRandom.java: New override. * java/util/logging/Logger.java: Updated to latest classpath version. * java/util/logging/LogManager.java: New override. From-SVN: r113887
This commit is contained in:
parent
eaec4980e1
commit
4f9533c772
1640 changed files with 126485 additions and 104808 deletions
175
libjava/classpath/gnu/java/rmi/server/ActivatableRef.java
Normal file
175
libjava/classpath/gnu/java/rmi/server/ActivatableRef.java
Normal file
|
@ -0,0 +1,175 @@
|
|||
/* 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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
227
libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java
Normal file
227
libjava/classpath/gnu/java/rmi/server/ActivatableServerRef.java
Normal file
|
@ -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 = 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -77,8 +77,8 @@ public class CombinedClassLoader extends ClassLoader
|
|||
while (iter.hasNext())
|
||||
{
|
||||
cl = iter.next();
|
||||
if (!sLoaders.contains(cl))
|
||||
sLoaders.add(iter.next());
|
||||
if (cl!=null && !sLoaders.contains(cl))
|
||||
sLoaders.add(cl);
|
||||
}
|
||||
|
||||
loaders = new ClassLoader[sLoaders.size()];
|
||||
|
@ -96,7 +96,7 @@ public class CombinedClassLoader extends ClassLoader
|
|||
{
|
||||
try
|
||||
{
|
||||
return findClass(name);
|
||||
return loaders[i].loadClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
|
@ -106,20 +106,6 @@ public class CombinedClassLoader extends ClassLoader
|
|||
return super.findClass(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the library with the given name
|
||||
*/
|
||||
protected String findLibrary(String name)
|
||||
{
|
||||
for (int i = 0; i < loaders.length; i++)
|
||||
{
|
||||
String lib = findLibrary(name);
|
||||
if (lib != null)
|
||||
return lib;
|
||||
}
|
||||
return super.findLibrary(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find resource with the given name.
|
||||
*/
|
||||
|
@ -127,7 +113,7 @@ public class CombinedClassLoader extends ClassLoader
|
|||
{
|
||||
for (int i = 0; i < loaders.length; i++)
|
||||
{
|
||||
URL resource = findResource(name);
|
||||
URL resource = loaders[i].getResource(name);
|
||||
if (resource != null)
|
||||
return resource;
|
||||
}
|
||||
|
@ -141,7 +127,7 @@ public class CombinedClassLoader extends ClassLoader
|
|||
{
|
||||
for (int i = 0; i < loaders.length; i++)
|
||||
{
|
||||
Enumeration resource = findResources(name);
|
||||
Enumeration resource = loaders[i].getResources(name);
|
||||
if (resource != null)
|
||||
return resource;
|
||||
}
|
||||
|
|
|
@ -310,6 +310,14 @@ private UnicastConnection getClientConnection() throws IOException {
|
|||
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.
|
||||
|
@ -443,4 +451,12 @@ public boolean equals(Object obj) {
|
|||
return (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string representation, describing the connection.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return host+":"+port+" ("+other+")";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* UnicastRef.java --
|
||||
Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005
|
||||
Copyright (c) 1996, 1997, 1998, 1999, 2002, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
@ -36,8 +36,11 @@ 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;
|
||||
|
@ -50,6 +53,7 @@ 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;
|
||||
|
@ -59,221 +63,462 @@ import java.rmi.server.RemoteRef;
|
|||
import java.rmi.server.UID;
|
||||
|
||||
public class UnicastRef
|
||||
implements RemoteRef, ProtocolConstants {
|
||||
implements RemoteRef, ProtocolConstants
|
||||
{
|
||||
|
||||
public ObjID objid;
|
||||
UnicastConnectionManager manager;
|
||||
/**
|
||||
* Use serial version UID for iteroperability
|
||||
*/
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
/**
|
||||
* 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 ObjID objid;
|
||||
|
||||
public UnicastRef(ObjID objid, String host, int port, RMIClientSocketFactory csf) {
|
||||
this(objid);
|
||||
manager = UnicastConnectionManager.getInstance(host, port, csf);
|
||||
}
|
||||
UnicastConnectionManager manager;
|
||||
|
||||
public UnicastRef(ObjID objid) {
|
||||
this.objid = objid;
|
||||
}
|
||||
/**
|
||||
* 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 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
|
||||
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
|
||||
|
||||
// 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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
private Object invokeCommon(Remote obj, Method method, Object[] params, int opnum, long hash) throws Exception {
|
||||
UnicastConnection conn;
|
||||
try {
|
||||
conn = manager.getConnection();
|
||||
}
|
||||
catch (IOException e1) {
|
||||
throw new RemoteException("connection failed to host: " + manager.serverName, e1);
|
||||
}
|
||||
/**
|
||||
* The ordinary number of the DGC messages.
|
||||
*/
|
||||
static long dgcSequence;
|
||||
|
||||
ObjectOutputStream out;
|
||||
DataOutputStream dout;
|
||||
try {
|
||||
dout = conn.getDataOutputStream();
|
||||
dout.writeByte(MESSAGE_CALL);
|
||||
/**
|
||||
* The DGC object id, also serves as a synchronization target to increment the
|
||||
* dgcSequence safely.
|
||||
*/
|
||||
static final ObjID dgcId = new ObjID(ObjID.DGC_ID);
|
||||
|
||||
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]);
|
||||
ObjID[] this_id;
|
||||
|
||||
out.flush();
|
||||
}
|
||||
catch (IOException e2) {
|
||||
throw new RemoteException("call failed: ", e2);
|
||||
}
|
||||
/**
|
||||
* The number of the method "dirty" in the DGC.
|
||||
*/
|
||||
static int DIRTY = 1;
|
||||
|
||||
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);
|
||||
}
|
||||
/**
|
||||
* The DGC interface hash code.
|
||||
*/
|
||||
static final long dgcInterfaceHash = - 669196253586618813L;
|
||||
|
||||
in = conn.startObjectInputStream(); // (re)start ObjectInputStream
|
||||
returncode = in.readUnsignedByte();
|
||||
ack = UID.read(in);
|
||||
/**
|
||||
* 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++;
|
||||
}
|
||||
|
||||
Class cls = method.getReturnType();
|
||||
if (this_id == null)
|
||||
this_id = new ObjID[] { objid };
|
||||
|
||||
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);
|
||||
}
|
||||
try
|
||||
{
|
||||
conn = manager.getConnection();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
throw new RemoteException("connection failed to host: "
|
||||
+ manager.serverName, e1);
|
||||
}
|
||||
|
||||
//obj: useless?
|
||||
ObjectOutputStream out;
|
||||
DataOutputStream dout;
|
||||
try
|
||||
{
|
||||
dout = conn.getDataOutputStream();
|
||||
dout.writeByte(MESSAGE_CALL);
|
||||
|
||||
return (new UnicastRemoteCall(conn, objid, opnum, hash));
|
||||
}
|
||||
out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void invoke(RemoteCall call) throws Exception {
|
||||
UnicastRemoteCall c = (UnicastRemoteCall)call;
|
||||
call.executeCall();
|
||||
}
|
||||
dgcId.write(out);
|
||||
// The number of the operation is 1 ("dirty")
|
||||
out.writeInt(DIRTY);
|
||||
out.writeLong(dgcInterfaceHash);
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void done(RemoteCall call) throws RemoteException {
|
||||
UnicastRemoteCall c = (UnicastRemoteCall)call;
|
||||
try{
|
||||
c.done();
|
||||
} catch(IOException e){}
|
||||
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);
|
||||
}
|
||||
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 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");
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
public boolean remoteEquals(RemoteRef ref) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
// 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 int remoteHashCode() {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
public boolean remoteEquals(RemoteRef ref)
|
||||
{
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
public String getRefClass(ObjectOutput out) {
|
||||
return ("UnicastRef");
|
||||
}
|
||||
public int remoteHashCode()
|
||||
{
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
public String remoteToString() {
|
||||
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 _) {
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ 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;
|
||||
|
@ -49,122 +50,272 @@ 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.Map;
|
||||
import java.util.Hashtable;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class UnicastServer
|
||||
implements ProtocolConstants {
|
||||
implements ProtocolConstants
|
||||
{
|
||||
|
||||
static private Hashtable objects = new Hashtable(); //mapping OBJID to server ref
|
||||
static private Map refcache = Collections.synchronizedMap(new IdentityHashMap()); //mapping obj itself to server ref
|
||||
static private DGCImpl dgc;
|
||||
/**
|
||||
* Mapping OBJID to server ref by .equals().
|
||||
*/
|
||||
static private Map objects = Collections.synchronizedMap(new WeakHashMap());
|
||||
|
||||
public static void exportObject(UnicastServerRef obj) {
|
||||
startDGC();
|
||||
objects.put(obj.objid, obj);
|
||||
refcache.put(obj.myself, obj);
|
||||
obj.manager.startServer();
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
// FIX ME: I haven't handle force parameter
|
||||
public static boolean unexportObject(UnicastServerRef obj, boolean force) {
|
||||
objects.remove(obj.objid);
|
||||
refcache.remove(obj.myself);
|
||||
obj.manager.stopServer();
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
public static UnicastServerRef getExportedRef(Remote remote){
|
||||
return (UnicastServerRef)refcache.get(remote);
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
ObjID objid = ObjID.read(in);
|
||||
int method = in.readInt();
|
||||
long hash = in.readLong();
|
||||
|
||||
private static void incomingMessageCall(UnicastConnection conn) throws IOException {
|
||||
ObjectInputStream in = conn.startObjectInputStream(); // (re)start ObjectInputStream
|
||||
// System.out.println("ObjID: " + objid + ", method: " + method + ", hash: "
|
||||
// + hash);
|
||||
|
||||
ObjID objid = ObjID.read(in);
|
||||
int method = in.readInt();
|
||||
long hash = in.readLong();
|
||||
// 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;
|
||||
}
|
||||
|
||||
//System.out.println("ObjID: " + objid + ", method: " + method + ", hash: " + hash);
|
||||
conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
|
||||
|
||||
// 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 ("An Error is thrown while processing the invocation on the server", e);
|
||||
returncode = RETURN_NACK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
returnval = new NoSuchObjectException("");
|
||||
returncode = RETURN_NACK;
|
||||
}
|
||||
ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start
|
||||
// ObjectOutputStream
|
||||
|
||||
conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);
|
||||
out.writeByte(returncode);
|
||||
(new UID()).write(out);
|
||||
|
||||
ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
|
||||
// System.out.println("returnval=" + returnval + " returncls=" + returncls);
|
||||
|
||||
out.writeByte(returncode);
|
||||
(new UID()).write(out);
|
||||
if (returnval != null && returncls != null)
|
||||
((RMIObjectOutputStream) out).writeValue(returnval, returncls);
|
||||
|
||||
//System.out.println("returnval=" + returnval + " returncls=" + returncls);
|
||||
// 1.1/1.2 void return type detection:
|
||||
else if (! (returnval instanceof RMIVoidValue || returncls == Void.TYPE))
|
||||
out.writeObject(returnval);
|
||||
|
||||
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();
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,10 @@ 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
|
||||
{
|
||||
|
@ -80,18 +84,18 @@ public class UnicastServerRef
|
|||
/**
|
||||
* The skeleton (if any), associated with the exported remote object.
|
||||
*/
|
||||
private Skeleton skel;
|
||||
protected Skeleton skel;
|
||||
|
||||
/**
|
||||
* The stub, associated with the exported remote object (may be proxy class).
|
||||
*/
|
||||
private Remote stub;
|
||||
protected Remote stub;
|
||||
|
||||
/**
|
||||
* The method table (RMI hash code to method) of the methods of the
|
||||
* exported object.
|
||||
*/
|
||||
private Hashtable methods = new Hashtable();
|
||||
protected Hashtable methods = new Hashtable();
|
||||
|
||||
/**
|
||||
* Used by serialization.
|
||||
|
@ -125,8 +129,7 @@ public class UnicastServerRef
|
|||
{
|
||||
myself = obj;
|
||||
// Save it to server manager, to let client calls in the same VM to
|
||||
// issue
|
||||
// local call
|
||||
// issue local call
|
||||
manager.serverobj = obj;
|
||||
|
||||
String ignoreStubs;
|
||||
|
@ -202,7 +205,7 @@ public class UnicastServerRef
|
|||
*
|
||||
* @return the class having stub defined, null if none.
|
||||
*/
|
||||
private Class findStubSkelClass(Class startCls)
|
||||
protected Class findStubSkelClass(Class startCls)
|
||||
{
|
||||
Class cls = startCls;
|
||||
|
||||
|
@ -242,7 +245,7 @@ public class UnicastServerRef
|
|||
* @return the instantiated instance of the helper class or null if the
|
||||
* helper class cannot be found or instantiated.
|
||||
*/
|
||||
private Object getHelperClass(Class cls, String type)
|
||||
protected Object getHelperClass(Class cls, String type)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -310,7 +313,7 @@ public class UnicastServerRef
|
|||
* @param build if true, the class methods are added to the table. If
|
||||
* false, they are removed from the table.
|
||||
*/
|
||||
private void buildMethodHash(Class cls, boolean build)
|
||||
protected void buildMethodHash(Class cls, boolean build)
|
||||
{
|
||||
Method[] meths = cls.getMethods();
|
||||
for (int i = 0; i < meths.length; i++)
|
||||
|
@ -339,7 +342,11 @@ public class UnicastServerRef
|
|||
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
|
||||
{
|
||||
|
@ -353,7 +360,8 @@ public class UnicastServerRef
|
|||
// meth);
|
||||
if (meth == null)
|
||||
{
|
||||
throw new NoSuchMethodException();
|
||||
throw new NoSuchMethodException(
|
||||
myself.getClass().getName()+" hash "+hash);
|
||||
}
|
||||
|
||||
ObjectInputStream in = conn.getObjectInputStream();
|
||||
|
@ -413,9 +421,8 @@ public class UnicastServerRef
|
|||
else
|
||||
{
|
||||
if (skel == null)
|
||||
{
|
||||
throw new NoSuchMethodException();
|
||||
}
|
||||
throw new NoSuchMethodException("JDK 1.1 call - Skeleton required");
|
||||
|
||||
UnicastRemoteCall call = new UnicastRemoteCall(conn);
|
||||
skel.dispatch(myself, call, method, hash);
|
||||
if (! call.isReturnValue())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue