Imported GNU Classpath 0.90
Imported GNU Classpath 0.90 * scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. From-SVN: r111942
This commit is contained in:
parent
27079765d0
commit
8aa540d2f7
1367 changed files with 188789 additions and 22762 deletions
|
@ -8,7 +8,7 @@ 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
|
||||
|
@ -49,70 +49,146 @@ import java.rmi.server.RMISocketFactory;
|
|||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* I let DGCImpl to extend UnicastServerRef, but not
|
||||
* UnicastRemoteObject, because UnicastRemoteObject must
|
||||
* exportObject automatically.
|
||||
*/
|
||||
* 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 {
|
||||
extends UnicastServerRef
|
||||
implements DGC
|
||||
{
|
||||
/*
|
||||
* The DGCImpl extends UnicastServerRef and not UnicastRemoteObject, because
|
||||
* UnicastRemoteObject must exportObject automatically.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
private static final long LEASE_VALUE = 600000L;
|
||||
// leaseCache caches a LeaseRecord associated with a vmid
|
||||
private Hashtable leaseCache = new Hashtable();
|
||||
// leaseCache caches a LeaseRecord associated with a vmid
|
||||
Hashtable leaseCache = new Hashtable();
|
||||
|
||||
public DGCImpl() throws RemoteException {
|
||||
super(new ObjID(ObjID.DGC_ID), 0, RMISocketFactory.getSocketFactory());
|
||||
}
|
||||
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
|
||||
{
|
||||
VMID vmid = lease.getVMID();
|
||||
if (vmid == null)
|
||||
vmid = new VMID();
|
||||
|
||||
long leaseValue = lease.getValue();
|
||||
if (leaseValue <= 0)
|
||||
leaseValue = LEASE_VALUE;
|
||||
|
||||
public Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) throws RemoteException {
|
||||
VMID vmid = lease.getVMID();
|
||||
if (vmid == null)
|
||||
vmid = new VMID();
|
||||
long leaseValue = LEASE_VALUE;
|
||||
//long leaseValue = lease.getValue();
|
||||
lease = new Lease(vmid, leaseValue);
|
||||
synchronized(leaseCache){
|
||||
LeaseRecord lr = (LeaseRecord)leaseCache.get(vmid);
|
||||
if (lr != null)
|
||||
lr.reset(leaseValue);
|
||||
else{
|
||||
lr = new LeaseRecord(vmid, leaseValue);
|
||||
leaseCache.put(vmid, lr);
|
||||
}
|
||||
}
|
||||
|
||||
return (lease);
|
||||
}
|
||||
|
||||
public void clean(ObjID[] ids, long sequenceNum, VMID vmid, boolean strong) throws RemoteException {
|
||||
// Not implemented
|
||||
}
|
||||
LeaseRecord lr = (LeaseRecord) leaseCache.get(vmid);
|
||||
if (lr != null)
|
||||
lr.reset(leaseValue);
|
||||
else
|
||||
{
|
||||
lr = new LeaseRecord(vmid, leaseValue, ids);
|
||||
leaseCache.put(vmid, lr);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* LeaseRecord associates a vmid to expireTime.
|
||||
*/
|
||||
private static class LeaseRecord{
|
||||
private VMID vmid;
|
||||
private long expireTime;
|
||||
static class LeaseRecord
|
||||
{
|
||||
/**
|
||||
* The lease id.
|
||||
*/
|
||||
final VMID vmid;
|
||||
|
||||
/**
|
||||
* The lease expiration time.
|
||||
*/
|
||||
long expireTime;
|
||||
|
||||
LeaseRecord(VMID vmid, long leaseValue){
|
||||
/**
|
||||
* The array of ObjeID's that must be protected from being garbage
|
||||
* collected.
|
||||
*/
|
||||
final ObjID [] objects;
|
||||
|
||||
/**
|
||||
* Create the new lease record.
|
||||
*
|
||||
* @param vmid lease id.
|
||||
* @param leaseValue lease value
|
||||
*/
|
||||
LeaseRecord(VMID vmid, long leaseValue, ObjID [] an_objects)
|
||||
{
|
||||
this.vmid = vmid;
|
||||
reset(leaseValue);
|
||||
objects = an_objects;
|
||||
}
|
||||
|
||||
// reset expireTime
|
||||
void reset(long leaseValue){
|
||||
|
||||
/**
|
||||
* Prolong the expiration time till current time + passed value
|
||||
*
|
||||
* @param leaseValue the value after that (since the current moment)
|
||||
* the lease should expire in the future.
|
||||
*/
|
||||
void reset(long leaseValue)
|
||||
{
|
||||
long l = System.currentTimeMillis();
|
||||
expireTime = l + leaseValue;
|
||||
}
|
||||
|
||||
boolean isExpired(){
|
||||
|
||||
/**
|
||||
* Check if the lease has been expired.
|
||||
*
|
||||
* @return true if the lease has been expired, false if it is still valid.
|
||||
*/
|
||||
boolean isExpired()
|
||||
{
|
||||
long l = System.currentTimeMillis();
|
||||
if ( l > expireTime)
|
||||
return true;
|
||||
if (l > expireTime)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
} //End of LeaseRecord
|
||||
|
||||
} //End of DGCImpl
|
||||
} // End of LeaseRecord
|
||||
|
||||
} // End of DGCImpl
|
||||
|
|
|
@ -111,7 +111,7 @@ public static void version() {
|
|||
+ System.getProperty("java.vm.name")
|
||||
+ ") "
|
||||
+ System.getProperty("java.vm.version"));
|
||||
System.out.println("Copyright 2005 Free Software Foundation, Inc.");
|
||||
System.out.println("Copyright 2006 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);
|
||||
|
|
149
libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java
Normal file
149
libjava/classpath/gnu/java/rmi/server/CombinedClassLoader.java
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* 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 (!sLoaders.contains(cl))
|
||||
sLoaders.add(iter.next());
|
||||
}
|
||||
|
||||
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 findClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
// try another.
|
||||
}
|
||||
}
|
||||
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.
|
||||
*/
|
||||
protected URL findResource(String name)
|
||||
{
|
||||
for (int i = 0; i < loaders.length; i++)
|
||||
{
|
||||
URL resource = findResource(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 = findResources(name);
|
||||
if (resource != null)
|
||||
return resource;
|
||||
}
|
||||
return super.findResources(name); }
|
||||
}
|
|
@ -46,6 +46,7 @@ import java.io.ObjectStreamClass;
|
|||
import java.lang.reflect.Proxy;
|
||||
import java.net.MalformedURLException;
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RMIObjectInputStream
|
||||
extends ObjectInputStream {
|
||||
|
@ -76,28 +77,51 @@ protected Object getAnnotation()
|
|||
return readObject();
|
||||
}
|
||||
|
||||
protected Class resolveProxyClass(String intfs[])
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
String annotation = (String)getAnnotation();
|
||||
|
||||
|
||||
protected Class resolveProxyClass(String intfs[]) throws IOException,
|
||||
ClassNotFoundException
|
||||
{
|
||||
String annotation = (String) getAnnotation();
|
||||
|
||||
Class clss[] = new Class[intfs.length];
|
||||
if(annotation == null)
|
||||
clss[0] = RMIClassLoader.loadClass(intfs[0]);
|
||||
else
|
||||
clss[0] = RMIClassLoader.loadClass(annotation, intfs[0]);
|
||||
|
||||
//assume all interfaces can be loaded by the same classloader
|
||||
ClassLoader loader = clss[0].getClassLoader();
|
||||
|
||||
for (int i = 0; i < intfs.length; i++)
|
||||
clss[i] = Class.forName(intfs[i], false, loader);
|
||||
|
||||
try {
|
||||
return Proxy.getProxyClass(loader, clss);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ClassNotFoundException(null, e);
|
||||
}
|
||||
}
|
||||
{
|
||||
if (annotation == null)
|
||||
clss[i] = RMIClassLoader.loadClass(intfs[i]);
|
||||
else
|
||||
clss[i] = RMIClassLoader.loadClass(annotation, intfs[i]);
|
||||
}
|
||||
|
||||
ClassLoader loader;
|
||||
|
||||
if (clss.length > 0)
|
||||
{
|
||||
// Chain all class loaders (they may differ).
|
||||
ArrayList loaders = new ArrayList(intfs.length);
|
||||
ClassLoader cx;
|
||||
for (int i = 0; i < clss.length; i++)
|
||||
{
|
||||
cx = clss[i].getClassLoader();
|
||||
if (!loaders.contains(cx))
|
||||
{
|
||||
loaders.add(0, cx);
|
||||
}
|
||||
}
|
||||
loader = new CombinedClassLoader(loaders);
|
||||
}
|
||||
else
|
||||
loader = ClassLoader.getSystemClassLoader();
|
||||
|
||||
try
|
||||
{
|
||||
return Proxy.getProxyClass(loader, clss);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
throw new ClassNotFoundException(null, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException {
|
||||
if(valueClass.isPrimitive()){
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* UnicastServerRef.java --
|
||||
Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004
|
||||
Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
@ -43,263 +43,433 @@ 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.ServerRef;
|
||||
import java.rmi.server.Skeleton;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class UnicastServerRef
|
||||
extends UnicastRef
|
||||
implements ServerRef{ //SHOULD implement ServerRef
|
||||
extends UnicastRef
|
||||
{
|
||||
|
||||
final static private Class[] stubprototype = new Class[] { RemoteRef.class };
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private Skeleton skel;
|
||||
|
||||
/**
|
||||
* The stub, associated with the exported remote object (may be proxy class).
|
||||
*/
|
||||
private Remote stub;
|
||||
|
||||
/**
|
||||
* The method table (RMI hash code to method) of the methods of the
|
||||
* exported object.
|
||||
*/
|
||||
private Hashtable methods = new Hashtable();
|
||||
|
||||
Remote myself; //save the remote object itself
|
||||
private Skeleton skel;
|
||||
private RemoteStub stub;
|
||||
private Hashtable methods = new Hashtable();
|
||||
/**
|
||||
* Used by serialization.
|
||||
*/
|
||||
UnicastServerRef()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) throws RemoteException {
|
||||
super(id);
|
||||
manager = UnicastConnectionManager.getInstance(port, ssf);
|
||||
}
|
||||
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();
|
||||
|
||||
public RemoteStub 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;
|
||||
// where ist the _Stub? (check superclasses also)
|
||||
Class expCls = expCls = findStubSkelClass(cls);
|
||||
|
||||
// Find and install the stub
|
||||
Class cls = obj.getClass();
|
||||
Class expCls;
|
||||
try {
|
||||
// where ist the _Stub? (check superclasses also)
|
||||
expCls = findStubSkelClass(cls);
|
||||
} catch (Exception ex) {
|
||||
throw new RemoteException("can not find stubs for class: " + cls, ex);
|
||||
}
|
||||
if (expCls != null)
|
||||
{
|
||||
stub = (RemoteStub) getHelperClass(expCls, "_Stub");
|
||||
// Find and install the skeleton (if there is one)
|
||||
skel = (Skeleton) getHelperClass(expCls, "_Skel");
|
||||
}
|
||||
}
|
||||
|
||||
stub = (RemoteStub)getHelperClass(expCls, "_Stub");
|
||||
if (stub == null) {
|
||||
throw new RemoteException("failed to export: " + cls);
|
||||
}
|
||||
if (stub == null)
|
||||
stub = createProxyStub(obj.getClass(), this);
|
||||
|
||||
// Find and install the skeleton (if there is one)
|
||||
skel = (Skeleton)getHelperClass(expCls, "_Skel");
|
||||
// Build hash of methods which may be called.
|
||||
buildMethodHash(obj.getClass(), true);
|
||||
|
||||
// Build hash of methods which may be called.
|
||||
buildMethodHash(obj.getClass(), true);
|
||||
// Export it.
|
||||
UnicastServer.exportObject(this);
|
||||
}
|
||||
|
||||
// Export it.
|
||||
UnicastServer.exportObject(this);
|
||||
}
|
||||
|
||||
return (stub);
|
||||
}
|
||||
|
||||
public RemoteStub exportObject(Remote remote, Object obj)
|
||||
throws RemoteException
|
||||
{
|
||||
//FIX ME
|
||||
return exportObject(remote);
|
||||
}
|
||||
|
||||
public RemoteStub getStub(){
|
||||
return stub;
|
||||
}
|
||||
|
||||
|
||||
public boolean unexportObject(Remote obj, boolean force) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* The Subs/Skels might not there for the actual class, but maybe
|
||||
* for one of the superclasses.
|
||||
*
|
||||
*/
|
||||
private Class findStubSkelClass(Class startCls) throws Exception {
|
||||
Class cls = startCls;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private 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)
|
||||
{
|
||||
throw new Exception("Neither " + startCls
|
||||
+ " nor one of their superclasses (like" + cls + ")"
|
||||
+ " has a _Stub");
|
||||
}
|
||||
cls = superCls;
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
*/
|
||||
private 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.
|
||||
*/
|
||||
private void buildMethodHash(Class cls, boolean build)
|
||||
{
|
||||
Method[] meths = cls.getMethods();
|
||||
for (int i = 0; i < meths.length; i++)
|
||||
{
|
||||
/* Don't need to include any java.xxx related stuff */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private 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();
|
||||
}
|
||||
|
||||
private void buildMethodHash(Class cls, boolean build) {
|
||||
Method[] meths = cls.getMethods();
|
||||
for (int i = 0; i < meths.length; i++) {
|
||||
/* Don't need to include any java.xxx related stuff */
|
||||
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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throws Exception {
|
||||
//System.out.println("method = " + method + ", hash = " + hash);
|
||||
// If method is -1 then this is JDK 1.2 RMI - so use the hash
|
||||
// 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();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
UnicastRemoteCall call = new UnicastRemoteCall(conn);
|
||||
skel.dispatch(myself, call, method, hash);
|
||||
if (!call.isReturnValue())
|
||||
return RMIVoidValue.INSTANCE;
|
||||
else
|
||||
return (call.returnValue());
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue