ObjectInputStream.java (resolveProxyClass): New method from Classpath.

* java/io/ObjectInputStream.java (resolveProxyClass): New method
	from Classpath.
	* Makefile.in: Rebuilt.
	* Makefile.am (rmi_java_source_files): Added new files.
	* gnu/java/rmi/RMIMarshalledObjectInputStream.java,
	gnu/java/rmi/RMIMarshalledObjectOutputStream.java,
	gnu/java/rmi/server/ConnectionRunnerPool.java: New files from
	Classpath.
	* gnu/java/rmi/dgc/DGCImpl.java,
	gnu/java/rmi/dgc/DGCImpl_Skel.java,
	gnu/java/rmi/dgc/DGCImpl_Stub.java,
	gnu/java/rmi/registry/RegistryImpl_Skel.java,
	gnu/java/rmi/registry/RegistryImpl_Stub.java,
	gnu/java/rmi/server/RMIHashes.java,
	gnu/java/rmi/server/RMIObjectInputStream.java,
	gnu/java/rmi/server/RMIObjectOutputStream.java,
	gnu/java/rmi/server/UnicastConnection.java,
	gnu/java/rmi/server/UnicastConnectionManager.java,
	gnu/java/rmi/server/UnicastRef.java,
	gnu/java/rmi/server/UnicastServer.java,
	gnu/java/rmi/server/UnicastServerRef.java,
	java/rmi/MarshalledObject.java,
	java/rmi/server/RMIClassLoader.java,
	java/rmi/server/RemoteObject.java,
	java/rmi/server/UnicastRemoteObject.java,
	java/security/SecureClassLoader.java: Merged from Classpath.

From-SVN: r57675
This commit is contained in:
Tom Tromey 2002-10-01 03:46:43 +00:00 committed by Tom Tromey
parent e3e3815b7f
commit d74732f5cd
28 changed files with 1175 additions and 156 deletions

View File

@ -1,3 +1,32 @@
2002-09-30 Tom Tromey <tromey@redhat.com>
* java/io/ObjectInputStream.java (resolveProxyClass): New method
from Classpath.
* Makefile.in: Rebuilt.
* Makefile.am (rmi_java_source_files): Added new files.
* gnu/java/rmi/RMIMarshalledObjectInputStream.java,
gnu/java/rmi/RMIMarshalledObjectOutputStream.java,
gnu/java/rmi/server/ConnectionRunnerPool.java: New files from
Classpath.
* gnu/java/rmi/dgc/DGCImpl.java,
gnu/java/rmi/dgc/DGCImpl_Skel.java,
gnu/java/rmi/dgc/DGCImpl_Stub.java,
gnu/java/rmi/registry/RegistryImpl_Skel.java,
gnu/java/rmi/registry/RegistryImpl_Stub.java,
gnu/java/rmi/server/RMIHashes.java,
gnu/java/rmi/server/RMIObjectInputStream.java,
gnu/java/rmi/server/RMIObjectOutputStream.java,
gnu/java/rmi/server/UnicastConnection.java,
gnu/java/rmi/server/UnicastConnectionManager.java,
gnu/java/rmi/server/UnicastRef.java,
gnu/java/rmi/server/UnicastServer.java,
gnu/java/rmi/server/UnicastServerRef.java,
java/rmi/MarshalledObject.java,
java/rmi/server/RMIClassLoader.java,
java/rmi/server/RemoteObject.java,
java/rmi/server/UnicastRemoteObject.java,
java/security/SecureClassLoader.java: Merged from Classpath.
2002-09-29 Anthony Green <green@redhat.com>
* java/lang/reflect/UndeclaredThrowableException.java: New file.

View File

@ -1284,6 +1284,8 @@ java/rmi/server/SocketSecurityException.java \
java/rmi/server/UID.java \
java/rmi/server/UnicastRemoteObject.java \
java/rmi/server/Unreferenced.java \
gnu/java/rmi/RMIMarshalledObjectInputStream.java \
gnu/java/rmi/RMIMarshalledObjectOutputStream.java \
gnu/java/rmi/dgc/DGCImpl.java \
gnu/java/rmi/dgc/DGCImpl_Skel.java \
gnu/java/rmi/dgc/DGCImpl_Stub.java \
@ -1295,6 +1297,7 @@ gnu/java/rmi/rmic/Compiler.java \
gnu/java/rmi/rmic/CompilerProcess.java \
gnu/java/rmi/rmic/RMIC.java \
gnu/java/rmi/rmic/TabbedWriter.java \
gnu/java/rmi/server/ConnectionRunnerPool.java \
gnu/java/rmi/server/ProtocolConstants.java \
gnu/java/rmi/server/RMIDefaultSocketFactory.java \
gnu/java/rmi/server/RMIHashes.java \

View File

@ -1,6 +1,6 @@
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -1042,6 +1042,8 @@ java/rmi/server/SocketSecurityException.java \
java/rmi/server/UID.java \
java/rmi/server/UnicastRemoteObject.java \
java/rmi/server/Unreferenced.java \
gnu/java/rmi/RMIMarshalledObjectInputStream.java \
gnu/java/rmi/RMIMarshalledObjectOutputStream.java \
gnu/java/rmi/dgc/DGCImpl.java \
gnu/java/rmi/dgc/DGCImpl_Skel.java \
gnu/java/rmi/dgc/DGCImpl_Stub.java \
@ -1053,6 +1055,7 @@ gnu/java/rmi/rmic/Compiler.java \
gnu/java/rmi/rmic/CompilerProcess.java \
gnu/java/rmi/rmic/RMIC.java \
gnu/java/rmi/rmic/TabbedWriter.java \
gnu/java/rmi/server/ConnectionRunnerPool.java \
gnu/java/rmi/server/ProtocolConstants.java \
gnu/java/rmi/server/RMIDefaultSocketFactory.java \
gnu/java/rmi/server/RMIHashes.java \
@ -2462,8 +2465,10 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/java/locale/LocaleInformation_zh_HK.P \
.deps/gnu/java/locale/LocaleInformation_zh_SG.P \
.deps/gnu/java/locale/LocaleInformation_zh_TW.P \
.deps/gnu/java/math/MPN.P .deps/gnu/java/rmi/dgc/DGCImpl.P \
.deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \
.deps/gnu/java/math/MPN.P \
.deps/gnu/java/rmi/RMIMarshalledObjectInputStream.P \
.deps/gnu/java/rmi/RMIMarshalledObjectOutputStream.P \
.deps/gnu/java/rmi/dgc/DGCImpl.P .deps/gnu/java/rmi/dgc/DGCImpl_Skel.P \
.deps/gnu/java/rmi/dgc/DGCImpl_Stub.P \
.deps/gnu/java/rmi/registry/RegistryImpl.P \
.deps/gnu/java/rmi/registry/RegistryImpl_Skel.P \
@ -2472,6 +2477,7 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/java/rmi/rmic/Compiler.P \
.deps/gnu/java/rmi/rmic/CompilerProcess.P \
.deps/gnu/java/rmi/rmic/RMIC.P .deps/gnu/java/rmi/rmic/TabbedWriter.P \
.deps/gnu/java/rmi/server/ConnectionRunnerPool.P \
.deps/gnu/java/rmi/server/ProtocolConstants.P \
.deps/gnu/java/rmi/server/RMIDefaultSocketFactory.P \
.deps/gnu/java/rmi/server/RMIHashes.P \
@ -3785,7 +3791,7 @@ maintainer-clean-recursive:
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" != "." || dot_seen=yes; \
test "$$subdir" = "." && dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \

View File

@ -1,6 +1,6 @@
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

View File

@ -0,0 +1,70 @@
/* gnu.java.rmi.RMIMarshalledObjectInputStream
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.rmi;
import gnu.java.rmi.server.RMIObjectInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
import java.io.ByteArrayInputStream;
/**
* This class is only for java.rmi.MarshalledObject to deserialize object from
* objBytes and locBytes
*/
public class RMIMarshalledObjectInputStream extends RMIObjectInputStream
{
private ObjectInputStream locStream;
public RMIMarshalledObjectInputStream(byte[] objBytes, byte[] locBytes) throws IOException
{
super(new ByteArrayInputStream(objBytes));
if(locBytes != null)
locStream = new ObjectInputStream(new ByteArrayInputStream(locBytes));
}
//This method overrides RMIObjectInputStream's
protected Object getAnnotation() throws IOException, ClassNotFoundException
{
if(locStream == null)
return null;
return locStream.readObject();
}
} // End of RMIMarshalledObjectInputStream

View File

@ -0,0 +1,103 @@
/* gnu.java.rmi.RMIMarshalledObjectOutputStream
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.rmi;
import java.io.OutputStream;
import java.io.ObjectOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.rmi.Remote;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteStub;
import gnu.java.rmi.server.RMIObjectOutputStream;
import gnu.java.rmi.server.UnicastServerRef;
/**
* This class is only for java.rmi.MarshalledObject to serialize object and
* got objBytes and locBytes
*/
public class RMIMarshalledObjectOutputStream extends RMIObjectOutputStream
{
private ObjectOutputStream locStream;
private ByteArrayOutputStream locBytesStream;
public RMIMarshalledObjectOutputStream(OutputStream objStream) throws IOException
{
super(objStream);
}
//This method overrides RMIObjectOutputStream's.
protected void setAnnotation(String annotation) throws IOException{
synchronized(this){
if(locStream == null){
locBytesStream = new ByteArrayOutputStream();
locStream = new ObjectOutputStream(locBytesStream);
}
}
locStream.writeObject(annotation);
}
//This method overrides ObjectOutputStream's to replace Remote to RemoteStub
protected Object replaceObject(Object obj) throws IOException
{
if((obj instanceof Remote) && !(obj instanceof RemoteStub))
{
UnicastServerRef ref = new UnicastServerRef(new ObjID(), 0, null);
try{
return ref.exportObject((Remote)obj);
}catch(Exception e){}
}
return obj;
}
public void flush() throws IOException {
super.flush();
if(locStream != null)
locStream.flush();
}
public byte[] getLocBytes(){
if(locStream != null)
return locBytesStream.toByteArray();
return null;
}
} // End of RMIMarshalledObjectOutputStream

View File

@ -49,12 +49,16 @@ import gnu.java.rmi.server.UnicastServerRef;
public class DGCImpl
extends UnicastRemoteObject implements DGC {
private static final long leaseValue = 600000L;
public DGCImpl() throws RemoteException {
super(new UnicastServerRef(new ObjID(ObjID.DGC_ID), 0, RMISocketFactory.getSocketFactory()));
}
public Lease dirty(ObjID[] ids, long sequenceNum, Lease lease) throws RemoteException {
System.out.println("DGCImpl.dirty - not implemented");
VMID vmid = lease.getVMID();
lease = new Lease(vmid, leaseValue);
System.out.println("DGCImpl.dirty - not completely implemented");
return (lease);
}

View File

@ -1,3 +1,41 @@
/* DGCImpl_Skel.java
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
// Skel class generated by rmic - DO NOT EDIT!
package gnu.java.rmi.dgc;

View File

@ -1,3 +1,41 @@
/* DGCImpl_Stub.java
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
// Stub class generated by rmic - DO NOT EDIT!
package gnu.java.rmi.dgc;

View File

@ -1,3 +1,41 @@
/* RegistryImpl_Skel.java
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
// Skel class generated by rmic - DO NOT EDIT!
package gnu.java.rmi.registry;

View File

@ -1,3 +1,41 @@
/* RegistryImpl_Stub.java
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
// Stub class generated by rmic - DO NOT EDIT!
package gnu.java.rmi.registry;

View File

@ -0,0 +1,154 @@
/* gnu.java.rmi.server.ConnectionRunnerPool
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package gnu.java.rmi.server;
import java.util.ArrayList;
import java.util.Arrays;
//Should I generalize this class?
class ConnectionRunnerPool
{
public static
class ConnectionRunner extends Thread{
private UnicastConnection conn;
private volatile boolean exiting = false;
public ConnectionRunner(ThreadGroup group, String id){
super(group, id);
}
public synchronized void run(){
while(!exiting){
if(conn == null)
try{
wait();
}catch(InterruptedException e){
continue;
}
else{
conn.run();
conn = null;
synchronized(ConnectionRunnerPool.class){
freelist.add(this);
if(freelist.size() == 1)
ConnectionRunnerPool.class.notifyAll();
}
}
}
}
public synchronized void dispatch(UnicastConnection conn){
this.conn = conn;
notify();
}
void exit(){
exiting = true;
if(conn != null)
try{
join(500);
}catch(InterruptedException e){}
interrupt();
}
}
private static int size = 5;
private static int max_size = 10;
private static ArrayList freelist;
private static ThreadGroup group = new ThreadGroup("pool");
static {
ConnectionRunner[] pools = new ConnectionRunner[size];
for(int i = 0; i < pools.length; i++){
pools[i] = new ConnectionRunner(group, new Integer(i).toString());
pools[i].setContextClassLoader(Thread.currentThread().getContextClassLoader());
pools[i].start();
}
freelist = new ArrayList(Arrays.asList(pools));
}
public static void setSize(int size_){
size = size_;
}
public static void setMaxSize(int size){
max_size = size;
}
private synchronized static ConnectionRunner getConnectionRunner()
{
if(freelist.size() == 0){
if(size < max_size){
++size;
ConnectionRunner a = new ConnectionRunner(group, new Integer(size).toString());
a.start();
freelist.add(a);
}else
while(freelist.size() == 0)
try{
ConnectionRunnerPool.class.wait();
}catch(InterruptedException e){}
}
// always let the first in pool most busy or other scheduling plan??
ConnectionRunner a = (ConnectionRunner)freelist.get(0);
freelist.remove(a);
return a;
}
public static void dispatchConnection(UnicastConnection conn)
{
ConnectionRunner r = getConnectionRunner();
r.dispatch(conn);
}
public static void exit()
{
Thread[] list = new Thread[group.activeCount()];
group.enumerate(list);
for(int i = 0; i < list.length; i++)
((ConnectionRunner)list[i]).exit();
}
}

View File

@ -39,13 +39,56 @@ package gnu.java.rmi.server;
import java.lang.reflect.Method;
import java.lang.Class;
import gnu.java.security.provider.SHA;
import gnu.java.io.NullOutputStream;
import gnu.java.lang.reflect.TypeSignature;
import java.security.MessageDigest;
import java.security.DigestOutputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;
public class RMIHashes
{
//There're other places using DigestOutputStream to generate hash in classpath, but I think the way I used
//here is more efficient, anyway, you can switch to DigestOutputStream by doing like "//or:" comments say.
//or:add this statement: private static final NullOutputStream nullOutputStream = new NullOutputStream ();
public static long getMethodHash(Method meth)
{
return meth.hashCode ();
//Object Serialization Spec 8.3
try
{
MessageDigest md = MessageDigest.getInstance ("SHA");
//or:remove this statement: DigestOutputStream digest_out = new DigestOutputStream (nullOutputStream, md);
ByteArrayOutputStream digest_out = new ByteArrayOutputStream();
DataOutputStream data_out = new DataOutputStream (digest_out);
StringBuffer sbuf = new StringBuffer();
sbuf.append(meth.getName());
sbuf.append('(');
Class params[] = meth.getParameterTypes();
for(int i = 0; i < params.length; i++)
sbuf.append(TypeSignature.getEncodingOfClass(params[i]));
sbuf.append(')');
Class rcls = meth.getReturnType();
if(rcls != Void.TYPE)
sbuf.append(TypeSignature.getEncodingOfClass(rcls));
else
sbuf.append('V');
data_out.writeUTF (sbuf.toString());
data_out.flush();
data_out.close ();
md.update(digest_out.toByteArray()); //or:remove this statement
byte[] sha = md.digest ();
long result = 0;
int len = sha.length < 8 ? sha.length : 8;
for (int i=0; i < len; i++)
result += (long)(sha[i] & 0xFF) << (8 * i);
return result;
}catch(Exception _){
return -1L;
}
}
public static long getInterfaceHash(Class clazz)
@ -53,3 +96,4 @@ public class RMIHashes
return clazz.hashCode ();
}
}

View File

@ -44,6 +44,8 @@ import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.rmi.server.RMIClassLoader;
import java.lang.ClassNotFoundException;
import java.lang.reflect.Proxy;
public class RMIObjectInputStream
extends ObjectInputStream {
@ -56,20 +58,80 @@ public RMIObjectInputStream(InputStream strm, UnicastConnectionManager man) thro
enableResolveObject(true);
}
public RMIObjectInputStream(InputStream strm) throws IOException {
this(strm, UnicastConnectionManager.getInstance(0, null));
}
protected Class resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
//System.out.println("Resolving class: " + desc.getName());
String annotation = (String)readObject();
if (annotation == null) {
return (super.resolveClass(desc));
String annotation = (String)getAnnotation();
try{
return super.resolveClass(desc);
}catch(ClassNotFoundException _){};
try {
if(annotation == null)
return (RMIClassLoader.loadClass(desc.getName()));
else
return (RMIClassLoader.loadClass(annotation, desc.getName()));
}
else {
try {
return (RMIClassLoader.loadClass(new URL(annotation), desc.getName()));
}
catch (MalformedURLException _) {
throw new ClassNotFoundException(desc.getName());
}
catch (MalformedURLException _) {
throw new ClassNotFoundException(desc.getName());
}
}
//Separate it for override by MarshalledObject
protected Object getAnnotation()
throws IOException, ClassNotFoundException
{
return readObject();
}
protected Class resolveProxyClass(String intfs[])
throws IOException, ClassNotFoundException
{
String annotation = (String)getAnnotation();
try{
return super.resolveProxyClass(intfs);
}catch(ClassNotFoundException _){};
Class clss[] = new Class[intfs.length];
if(annotation == null)
clss[0] = RMIClassLoader.loadClass(intfs[0]);
else
clss[0] = RMIClassLoader.loadClass(annotation, intfs[0]);
//assume all interfaces can be loaded by the same classloader
ClassLoader loader = clss[0].getClassLoader();
if(loader == null)
for(int i = 1; i < intfs.length; i++)
clss[i] = Class.forName(intfs[i]);
else
for(int i = 1; i < intfs.length; i++)
clss[i] = loader.loadClass(intfs[i]);
return Proxy.getProxyClass(loader, clss);
}
protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException {
if(valueClass.isPrimitive()){
if(valueClass == Boolean.TYPE)
return new Boolean(readBoolean());
if(valueClass == Byte.TYPE)
return new Byte(readByte());
if(valueClass == Character.TYPE)
return new Character(readChar());
if(valueClass == Short.TYPE)
return new Short(readShort());
if(valueClass == Integer.TYPE)
return new Integer(readInt());
if(valueClass == Long.TYPE)
return new Long(readLong());
if(valueClass == Float.TYPE)
return new Float(readFloat());
if(valueClass == Double.TYPE)
return new Double(readDouble());
else
throw new Error("Unsupported primitive class: " + valueClass);
} else
return readObject();
}
}

View File

@ -41,17 +41,74 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.rmi.server.RMIClassLoader;
import java.rmi.Remote;
import java.rmi.server.RemoteStub;
import java.rmi.server.ObjID;
public class RMIObjectOutputStream
extends ObjectOutputStream {
public RMIObjectOutputStream(OutputStream strm) throws IOException {
super(strm);
enableReplaceObject(true);
}
//Separate it for override by MarshalledObject
protected void setAnnotation(String annotation) throws IOException{
writeObject(annotation);
}
protected void annotateClass(Class cls) throws IOException {
//System.out.println("Annotating class: " + cls);
writeObject(RMIClassLoader.getClassAnnotation(cls));
setAnnotation(RMIClassLoader.getClassAnnotation(cls));
}
protected void annotateProxyClass(Class cls)
throws IOException
{
annotateClass(cls);
}
protected Object replaceObject(Object obj)
throws IOException
{
if((obj instanceof Remote) && !(obj instanceof RemoteStub)){
UnicastServerRef ref = new UnicastServerRef(new ObjID(), 0, null);
try{
return ref.exportObject((Remote)obj);
}catch(Exception e){}
}
return obj;
}
protected void writeValue(Object value, Class valueClass) throws IOException{
if(valueClass.isPrimitive()){
if(valueClass == Boolean.TYPE)
writeBoolean(((Boolean)value).booleanValue());
else
if(valueClass == Byte.TYPE)
writeByte(((Byte)value).byteValue());
else
if(valueClass == Character.TYPE)
writeChar(((Character)value).charValue());
else
if(valueClass == Short.TYPE)
writeShort(((Short)value).shortValue());
else
if(valueClass == Integer.TYPE)
writeInt(((Integer)value).intValue());
else
if(valueClass == Long.TYPE)
writeLong(((Long)value).longValue());
else
if(valueClass == Float.TYPE)
writeFloat(((Float)value).floatValue());
else
if(valueClass == Double.TYPE)
writeDouble(((Double)value).doubleValue());
else
throw new Error("Unsupported primitive class: " + valueClass);
} else
writeObject(value);
}
}

View File

@ -44,6 +44,8 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
@ -65,9 +67,10 @@ UnicastConnection(UnicastConnectionManager man, Socket sock) {
}
void acceptConnection() throws IOException {
//System.out.println("Accepting connection on " + lport);
din = new DataInputStream(sock.getInputStream());
dout = new DataOutputStream(sock.getOutputStream());
//System.out.println("Accepting connection on " + sock);
//Use BufferedXXXStream would be more efficient
din = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
int sig = din.readInt();
if (sig != PROTOCOL_HEADER) {
@ -85,6 +88,7 @@ void acceptConnection() throws IOException {
// Send my hostname and port
dout.writeUTF(manager.serverName);
dout.writeInt(manager.serverPort);
dout.flush();
// Read their hostname and port
String rhost = din.readUTF();
@ -94,14 +98,15 @@ void acceptConnection() throws IOException {
}
void makeConnection(int protocol) throws IOException {
dout = new DataOutputStream(sock.getOutputStream());
din = new DataInputStream(sock.getInputStream());
//Use BufferedXXXStream would be more efficient
din = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
dout = new DataOutputStream(new BufferedOutputStream(sock.getOutputStream()));
// Send header
dout.writeInt(PROTOCOL_HEADER);
dout.writeShort(PROTOCOL_VERSION);
dout.writeByte(protocol);
dout.flush();
dout.flush();
if (protocol != SINGLE_OP_PROTOCOL) {
// Get back ack.
@ -117,6 +122,7 @@ void makeConnection(int protocol) throws IOException {
// Send them my endpoint
dout.writeUTF(manager.serverName);
dout.writeInt(manager.serverPort);
dout.flush();
}
// Okay, ready to roll ...
}
@ -144,13 +150,15 @@ ObjectOutputStream getObjectOutputStream() throws IOException {
}
void disconnect() {
oin = null;
oout = null;
try {
sock.close();
if(oout != null)
oout.close();
}
catch (IOException _) {
}
}
oin = null;
oout = null;
din = null;
dout = null;
sock = null;

View File

@ -57,9 +57,12 @@ public class UnicastConnectionManager
implements Runnable, ProtocolConstants {
private static String localhost;
// use different maps for server/client type UnicastConnectionManager
private static Hashtable servers = new Hashtable();
private static Hashtable clients = new Hashtable();
private Thread serverThread;
// make serverThread volatile for poll
private volatile Thread serverThread;
private ServerSocket ssock;
String serverName;
int serverPort;
@ -68,7 +71,9 @@ private RMIClientSocketFactory clientFactory;
static {
try {
localhost = InetAddress.getLocalHost().getHostName();
//Use host address instead of host name to avoid name resolving issues
//localhost = InetAddress.getLocalHost().getHostName();
localhost = InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException _) {
localhost = "localhost";
@ -112,11 +117,16 @@ public static synchronized UnicastConnectionManager getInstance(String host, int
if (csf == null) {
csf = RMISocketFactory.getSocketFactory();
}
// change host name to host address to avoid name resolving issues
try{
host = InetAddress.getByName(host).getHostAddress();
}catch(Exception _){}
TripleKey key = new TripleKey(host, port, csf);
UnicastConnectionManager man = (UnicastConnectionManager)servers.get(key);
UnicastConnectionManager man = (UnicastConnectionManager)clients.get(key);
if (man == null) {
man = new UnicastConnectionManager(host, port, csf);
servers.put(key, man);
clients.put(key, man);
}
return (man);
}
@ -198,18 +208,34 @@ public void startServer() {
serverThread.start();
}
/**
* Stop a server on this manager
*/
public void stopServer() {
synchronized(this) {
if(serverThread != null){
serverThread = null;
try{
ssock.close();
}catch(Exception _){}
}
}
}
/**
* Server thread for connection manager.
*/
public void run() {
for (;;) {
for (;serverThread != null;) { // if serverThread==null, then exit thread
try {
//System.out.println("Waiting for connection on " + serverPort);
UnicastConnection conn = getServerConnection();
(new Thread(conn)).start();
// use a thread pool to improve performance
// (new Thread(conn)).start();
ConnectionRunnerPool.dispatchConnection(conn);
}
catch (Exception e) {
e.printStackTrace();
// e.printStackTrace();
}
}
}

View File

@ -107,6 +107,7 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu
objid.write(out);
out.writeInt(opnum);
out.writeLong(hash);
/*
if (params != null) {
for (int i = 0; i < params.length; i++) {
if (params[i] instanceof UnicastRemoteObject) {
@ -117,6 +118,11 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu
}
}
}
*/
// must handle primitive class and their wrapper classes
Class clss[] = method.getParameterTypes();
for(int i = 0; i < clss.length; i++)
((RMIObjectOutputStream)out).writeValue(params[i], clss[i]);
out.flush();
}
@ -139,12 +145,25 @@ private Object invokeCommon(Remote obj, Method method, Object[] params, int opnu
returncode = in.readUnsignedByte();
ack = UID.read(in);
returnval = in.readObject();
//returnval = in.readObject();
Class cls = method.getReturnType();
if(cls == Void.TYPE){
returnval = null;
}else
returnval = ((RMIObjectInputStream)in).readValue(cls);
}
catch (IOException e3) {
throw new RemoteException("call return failed: ", e3);
}
/* if DGCAck is necessary
//According to RMI wire protocol, send a DGCAck
// to indicate receiving return value
dout.writeByte(MESSAGE_DGCACK);
ack.write(dout);
out.flush();
*/
manager.discardConnection(conn);
if (returncode != RETURN_ACK) {
@ -183,13 +202,16 @@ public void writeExternal(ObjectOutput out) throws IOException {
}
manager.write(out);
objid.write(out);
out.writeByte(RETURN_ACK);
// This byte is somewhat confusing when interoperating with JDK
out.writeByte(0); //RETURN_ACK);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
manager = UnicastConnectionManager.read(in);
objid = ObjID.read(in);
if (in.readByte() != RETURN_ACK) {
byte ack = in.readByte();
// This byte is somewhat confusing when interoperating with JDK
if (ack != RETURN_ACK && ack != 0/*jdk ack value*/) {
throw new IOException("no ack found");
}
}

View File

@ -65,6 +65,13 @@ public static void exportObject(UnicastServerRef obj) {
obj.manager.startServer();
}
// FIX ME: I haven't handle force parameter
public static boolean unexportObject(UnicastServerRef obj, boolean force) {
objects.remove(obj.objid);
obj.manager.stopServer();
return true;
}
private static synchronized void startDGC() {
if (dgc == null) {
try {
@ -100,10 +107,14 @@ private static void incomingMessageCall(UnicastConnection conn) throws IOExcepti
UnicastServerRef uref = (UnicastServerRef)objects.get(objid);
Object returnval;
int returncode = RETURN_ACK;
// returnval is from Method.invoke(), so we must check the return class to see
// if it's primitive type
Class returncls = null;
if (uref != null) {
try {
// Dispatch the call to it.
returnval = uref.incomingMessageCall(conn, method, hash);
returncls = uref.getMethodReturnType(method, hash);
}
catch (Exception e) {
returnval = e;
@ -121,7 +132,10 @@ private static void incomingMessageCall(UnicastConnection conn) throws IOExcepti
out.writeByte(returncode);
(new UID()).write(out);
out.writeObject(returnval);
if(returnval != null && returncls != null)
((RMIObjectOutputStream)out).writeValue(returnval, returncls);
else
out.writeObject(returnval);
out.flush();
}

View File

@ -66,14 +66,15 @@ import java.io.ObjectOutputStream;
import java.util.Hashtable;
public class UnicastServerRef
extends UnicastRef {
extends UnicastRef
implements ServerRef{ //SHOULD implement ServerRef
final static private Class[] stubprototype = new Class[] { RemoteRef.class };
Remote myself;
private Skeleton skel;
private RemoteStub stub;
private Hashtable methods;
private Hashtable methods = new Hashtable();
public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf) {
super(id);
@ -95,7 +96,7 @@ public RemoteStub exportObject(Remote obj) throws RemoteException {
skel = (Skeleton)getHelperClass(cls, "_Skel");
// Build hash of methods which may be called.
buildMethodHash(obj.getClass());
buildMethodHash(obj.getClass(), true);
// Export it.
UnicastServer.exportObject(this);
@ -104,10 +105,25 @@ public RemoteStub exportObject(Remote obj) throws RemoteException {
return (stub);
}
public RemoteStub exportObject(Remote remote, Object obj)
throws RemoteException
{
//FIX ME
return exportObject(remote);
}
public boolean unexportObject(Remote obj, boolean force) throws RemoteException {
// Remove all hashes of methods which may be called.
buildMethodHash(obj.getClass(), false);
return UnicastServer.unexportObject(this, force);
}
private Object getHelperClass(Class cls, String type) {
try {
String classname = cls.getName();
Class scls = Class.forName(classname + type);
String classname = cls.getName();
ClassLoader cl = cls.getClassLoader(); //DONT use "Class scls = Class.forName(classname + type);"
Class scls = cl.loadClass(classname + type);
if (type.equals("_Stub")) {
try {
// JDK 1.2 stubs
@ -147,8 +163,7 @@ public String getClientHost() throws ServerNotActiveException {
throw new Error("Not implemented");
}
private void buildMethodHash(Class cls) {
methods = new Hashtable();
private void buildMethodHash(Class cls, boolean build) {
Method[] meths = cls.getMethods();
for (int i = 0; i < meths.length; i++) {
/* Don't need to include any java.xxx related stuff */
@ -156,11 +171,23 @@ private void buildMethodHash(Class cls) {
continue;
}
long hash = RMIHashes.getMethodHash(meths[i]);
methods.put(new Long (hash), meths[i]);
if(build)
methods.put(new Long (hash), meths[i]);
else
methods.remove(new Long (hash));
//System.out.println("meth = " + meths[i] + ", hash = " + hash);
}
}
Class getMethodReturnType(int method, long hash) throws Exception
{
if (method == -1) {
Method meth = (Method)methods.get(new Long (hash));
return meth.getReturnType();
}else
return null;
}
public Object incomingMessageCall(UnicastConnection conn, int method, long hash) throws Exception {
//System.out.println("method = " + method + ", hash = " + hash);
// If method is -1 then this is JDK 1.2 RMI - so use the hash
@ -189,7 +216,15 @@ public Object incomingMessageCall(UnicastConnection conn, int method, long hash)
throw t;
}
}
return (meth.invoke(myself, args));
//We must reinterpret the exception thrown by meth.invoke()
//return (meth.invoke(myself, args));
Object ret = null;
try{
ret = meth.invoke(myself, args);
}catch(InvocationTargetException e){
throw (Exception)(e.getTargetException());
}
return ret;
}
// Otherwise this is JDK 1.1 style RMI - we find the skeleton
// and invoke it using the method number. We wrap up our

View File

@ -1,6 +1,6 @@
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

View File

@ -1,5 +1,5 @@
/* ObjectInputStream.java -- Class used to read serialized objects
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -42,6 +42,7 @@ import gnu.classpath.Configuration;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
@ -527,6 +528,32 @@ public class ObjectInputStream extends InputStream
}
protected Class resolveProxyClass (String[] intfs)
throws IOException, ClassNotFoundException
{
SecurityManager sm = System.getSecurityManager ();
if (sm == null)
sm = new SecurityManager () {};
ClassLoader cl = currentClassLoader (sm);
Class[] clss = new Class[intfs.length];
if(cl == null){
for (int i = 0; i < intfs.length; i++)
clss[i] = Class.forName(intfs[i]);
cl = ClassLoader.getSystemClassLoader();
}
else
for (int i = 0; i < intfs.length; i++)
clss[i] = cl.loadClass(intfs[i]);
try {
return Proxy.getProxyClass(cl, clss);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
/**
If <code>enable</code> is <code>true</code> and this object is
trusted, then <code>resolveObject (Object)</code> will be called

View File

@ -38,24 +38,73 @@ exception statement from your version. */
package java.rmi;
import java.io.Serializable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import gnu.java.rmi.RMIMarshalledObjectInputStream;
import gnu.java.rmi.RMIMarshalledObjectOutputStream;
/**
* FIXME - doc missing
*/
public final class MarshalledObject
extends Object implements Serializable {
extends Object implements Serializable
{
public MarshalledObject(Object obj) {
throw new Error("Not implemented");
//The following fields are from Java API Documentation "Serialized form"
private static final long serialVersionUID = 8988374069173025854L;
byte[] objBytes;
byte[] locBytes;
int hash;
public MarshalledObject(Object obj) throws java.io.IOException
{
ByteArrayOutputStream objStream = new ByteArrayOutputStream();
RMIMarshalledObjectOutputStream stream = new RMIMarshalledObjectOutputStream(objStream);
stream.writeObject(obj);
stream.flush();
objBytes = objStream.toByteArray();
locBytes = stream.getLocBytes();
//The following algorithm of calculating hashCode is similar to String
hash = 0;
for (int i = 0; i < objBytes.length; i++)
hash = hash * 31 + objBytes[i];
if(locBytes != null)
for (int i = 0; i < locBytes.length; i++)
hash = hash * 31 + locBytes[i];
}
public boolean equals(Object obj)
{
if(obj == null || !(obj instanceof MarshalledObject) )
return false;
MarshalledObject aobj = (MarshalledObject)obj;
if (objBytes == null || aobj.objBytes == null)
return objBytes == aobj.objBytes;
if (objBytes.length != aobj.objBytes.length)
return false;
for (int i = 0; i < objBytes.length; i++)
{
if (objBytes[i] != aobj.objBytes[i])
return false;
}
// Ignore comparison of locBytes(annotation)
return true;
}
public Object get()
throws java.io.IOException, java.lang.ClassNotFoundException
{
if(objBytes == null)
return null;
RMIMarshalledObjectInputStream stream =
new RMIMarshalledObjectInputStream(objBytes, locBytes);
return stream.readObject();
}
public boolean equals(Object obj) {
throw new Error("Not implemented");
}
public Object get() {
throw new Error("Not implemented");
}
public int hashCode() {
throw new Error("Not implemented");
}
public int hashCode() {
return hash;
}
}

View File

@ -39,21 +39,25 @@ package java.rmi.server;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLClassLoader;
import java.io.IOException;
import java.io.DataInputStream;
import java.net.MalformedURLException;
import java.util.StringTokenizer;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.ArrayList;
public class RMIClassLoader
{
static private class MyClassLoader extends ClassLoader
static private class MyClassLoader extends URLClassLoader
{
/**
* Non-private constructor to reduce bytecode emitted.
*/
MyClassLoader()
private MyClassLoader(URL[] urls, ClassLoader parent)
{
super (urls, parent);
}
Class defineClass(String name, byte[] data)
@ -62,7 +66,34 @@ public class RMIClassLoader
}
}
static private MyClassLoader loader = new MyClassLoader();
private static Map cacheLoaders; //map annotations to loaders
private static Map cacheClasses; //map loader to classes that the loader loaded+
private static String defaultAnnotation;
private static URL defaultCodebase;
private static MyClassLoader defaultLoader;
static
{
cacheLoaders = Collections.synchronizedMap(new WeakHashMap(5));
cacheClasses = Collections.synchronizedMap(new WeakHashMap(5));
defaultAnnotation = System.getProperty("java.rmi.server.defaultAnnotation");
try
{
if (defaultAnnotation != null)
defaultCodebase = new URL(defaultAnnotation);
}
catch(Exception _)
{
defaultCodebase = null;
}
if (defaultCodebase != null)
{
defaultLoader = new MyClassLoader(new URL[]{ defaultCodebase },
Thread.currentThread().getContextClassLoader());
cacheLoaders.put(defaultAnnotation, defaultLoader);
cacheClasses.put(defaultLoader, Collections.synchronizedMap(new WeakHashMap()));
}
}
/**
* @deprecated
@ -70,7 +101,7 @@ public class RMIClassLoader
public static Class loadClass(String name)
throws MalformedURLException, ClassNotFoundException
{
return loadClass(System.getProperty("java.rmi.server.codebase"), name);
return (loadClass("", name));
}
public static Class loadClass(URL codebase, String name)
@ -79,39 +110,87 @@ public class RMIClassLoader
URL u = new URL(codebase, name + ".class");
try
{
URLConnection conn = u.openConnection();
DataInputStream strm = new DataInputStream(conn.getInputStream());
byte data[] = new byte[conn.getContentLength()];
strm.readFully(data);
return loader.defineClass(name, data);
URLConnection conn = u.openConnection();
DataInputStream strm = new DataInputStream(conn.getInputStream());
byte data[] = new byte[conn.getContentLength()];
strm.readFully(data);
return (defaultLoader.defineClass(name, data));
}
catch (IOException _)
{
throw new ClassNotFoundException(name);
throw new ClassNotFoundException(name);
}
}
public static Class loadClass(String codebase, String name)
public static Class loadClass(String codebases, String name)
throws MalformedURLException, ClassNotFoundException
{
StringTokenizer tok = new StringTokenizer(codebase, ":");
while (tok.hasMoreTokens())
ClassLoader loader = (ClassLoader)cacheLoaders.get(codebases);
if (loader == null)
{
try
{
return loadClass(new URL(tok.nextToken()), name);
}
catch (ClassNotFoundException _)
{
// Ignore - try the next one.
}
if (codebases != "")
{
//codebases are separated by " "
StringTokenizer tok = new StringTokenizer(codebases, " ");
ArrayList urls = new ArrayList();
while (tok.hasMoreTokens())
urls.add(new URL(tok.nextToken()));
loader = new MyClassLoader((URL[])urls.toArray(new URL[urls.size()]),
Thread.currentThread().getContextClassLoader());
cacheLoaders.put(codebases, loader);
cacheClasses.put(loader, Collections.synchronizedMap(new WeakHashMap()));
}
else
{
//if codebases is empty, construct a classloader
// based on current context classloader,
// and we won't cache classloader for empty codebases
loader = new MyClassLoader(new URL[]{ defaultCodebase },
Thread.currentThread().getContextClassLoader());
}
}
throw new ClassNotFoundException(name);
Class c = null;
Map classes = (Map)cacheClasses.get(loader);
if (classes != null)
{
c = (Class)classes.get(name);
if (c == null)
{
c = loader.loadClass(name);
classes.put(name, c);
}
}else
c = loader.loadClass(name);
return c;
}
public static String getClassAnnotation(Class cl)
{
return null; // We don't yet do this.
ClassLoader loader = cl.getClassLoader();
if (loader == null)
{
if (defaultCodebase != null)
return defaultCodebase.toExternalForm();
else
return null;
}
if (loader instanceof URLClassLoader)
{
URL[] urls = ((URLClassLoader)loader).getURLs();
if(urls.length == 0)
return null;
StringBuffer annotation = new StringBuffer(urls[0].toExternalForm());
for(int i = 1; i < urls.length; i++)
{
annotation.append(' ');
annotation.append(urls[i].toExternalForm());
}
return annotation.toString();
}
return null;
}
/**

View File

@ -48,6 +48,7 @@ import java.io.IOException;
import java.lang.ClassNotFoundException;
import java.lang.InstantiationException;
import java.lang.IllegalAccessException;
import java.lang.reflect.Constructor;
public abstract class RemoteObject
implements Remote, Serializable {
@ -68,9 +69,22 @@ public RemoteRef getRef() {
return (ref);
}
public static Remote toStub(Remote obj) throws NoSuchObjectException {
throw new Error("Not implemented");
}
public static Remote toStub(Remote obj) throws NoSuchObjectException
{
Class cls = obj.getClass();
String classname = cls.getName();
ClassLoader cl = cls.getClassLoader();
try
{
Class scls = cl.loadClass(classname + "_Stub");
// JDK 1.2 stubs
Class[] stubprototype = new Class[] { RemoteRef.class };
Constructor con = scls.getConstructor(stubprototype);
return (Remote)(con.newInstance(new Object[]{obj}));
}
catch (Exception e) {}
throw new NoSuchObjectException(obj.getClass().getName());
}
public int hashCode() {
if (ref == null) {
@ -86,30 +100,46 @@ public boolean equals(Object obj) {
return (this == obj);
}
public String toString() {
return (ref.toString());
}
public String toString()
{
if (ref == null)
return getClass ().toString ();
return (ref.toString ());
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
String cname = in.readUTF();
if (!cname.equals("")) {
cname = RemoteRef.packagePrefix + '.' + cname;
try {
Class cls = Class.forName(cname);
ref = (RemoteRef)cls.newInstance();
}
catch (InstantiationException e1) {
throw new UnmarshalException("failed to create ref");
}
catch (IllegalAccessException e2) {
throw new UnmarshalException("failed to create ref");
}
ref.readExternal(in);
}
else {
ref = (RemoteRef)in.readObject();
}
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
String cname = in.readUTF();
if (!cname.equals(""))
{
if (cname.equals ("UnicastRef2"))
{
// hack for interoperating with JDK
cname = "UnicastRef";
in.read (); //some unknown UnicastRef2 field
}
cname = RemoteRef.packagePrefix + '.' + cname;
try
{
Class cls = Class.forName(cname);
ref = (RemoteRef)cls.newInstance();
}
catch (InstantiationException e1)
{
throw new UnmarshalException("failed to create ref");
}
catch (IllegalAccessException e2)
{
throw new UnmarshalException("failed to create ref");
}
ref.readExternal(in);
}
else
{
ref = (RemoteRef)in.readObject();
}
}
private void writeObject(ObjectOutputStream out) throws IOException, ClassNotFoundException {
if (ref == null) {

View File

@ -42,10 +42,17 @@ import java.rmi.Remote;
import java.rmi.server.RemoteRef;
import java.rmi.NoSuchObjectException;
import gnu.java.rmi.server.UnicastServerRef;
import gnu.java.rmi.server.UnicastServer;
public class UnicastRemoteObject
extends RemoteServer {
private static final long serialVersionUID = 4974527148936298033L;
//The following serialized fields are from Java API Documentation "Serialized form"
private int port = 0;
private RMIClientSocketFactory csf = null;
private RMIServerSocketFactory ssf = null;
protected UnicastRemoteObject() throws RemoteException {
this(0);
}
@ -55,11 +62,21 @@ protected UnicastRemoteObject(int port) throws RemoteException {
}
protected UnicastRemoteObject(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
super(new UnicastServerRef(new ObjID(), port, ssf));
this.port = port;
//Is RMIXXXSocketFactory serializable
//this.csf = csf;
//this.ssf = ssf;
this.ref = new UnicastServerRef(new ObjID(), port, ssf);
//Should we export it here?
// if we export, we got infinite recursive call:
// UnicastRemoteObject.<init>->...->UnicastServer.startDGC()->UnicastRemoteObject.<init>->...
//exportObject(this);
}
protected UnicastRemoteObject(RemoteRef ref) throws RemoteException {
super((UnicastServerRef)ref);
//Should we export it here?
//exportObject(this);
}
public Object clone() throws CloneNotSupportedException {
@ -71,16 +88,46 @@ public static RemoteStub exportObject(Remote obj) throws RemoteException {
return (sref.exportObject(obj));
}
public static Remote exportObject(Remote obj, int port) throws RemoteException {
return (exportObject(obj));
}
public static Remote exportObject(Remote obj, int port) throws RemoteException
{
return exportObject(obj, port, null);
}
public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
return (exportObject(obj));
}
protected static Remote exportObject(Remote obj, int port, RMIServerSocketFactory ssf)
throws RemoteException
{
UnicastServerRef sref = null;
if (obj instanceof RemoteObject)
sref = (UnicastServerRef)((RemoteObject)obj).getRef ();
if(sref == null)
{
sref = new UnicastServerRef(new ObjID (), port, ssf);
}
return (sref.exportObject (obj));
}
public static boolean unexportObject(Remote obj, boolean force) throws NoSuchObjectException {
throw new Error("Not implemented");
}
/**
* FIX ME
*/
public static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
throws RemoteException
{
return (exportObject(obj, port, ssf));
}
public static boolean unexportObject(Remote obj, boolean force)
throws RemoteException, NoSuchObjectException
{
if (obj instanceof RemoteObject)
{
UnicastServerRef sref = (UnicastServerRef)((RemoteObject)obj).getRef();
return sref.unexportObject(obj, force);
}
else
//FIX ME
;
return true;
}
}

View File

@ -71,7 +71,7 @@ public class SecureClassLoader extends ClassLoader
@param b the data representing the classfile, in classfile format.
@param off the offset into the data where the classfile starts.
@param len the length of the classfile data in the array.
@param cs the CodeSource for the class
@param cs the CodeSource for the class or null when unknown.
@return the class that was defined and optional CodeSource.
@ -81,16 +81,14 @@ public class SecureClassLoader extends ClassLoader
CodeSource cs)
{
// FIXME: Need to cache ProtectionDomains according to 1.3 docs.
ProtectionDomain protectionDomain =
new ProtectionDomain(cs, getPermissions(cs));
try
if (cs != null)
{
ProtectionDomain protectionDomain
= new ProtectionDomain(cs, getPermissions(cs));
return super.defineClass(name, b, off, len, protectionDomain);
}
catch (ClassFormatError cfe)
{
return null;
}
else
return super.defineClass(name, b, off, len);
}
/**

View File

@ -1,6 +1,6 @@
# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
# Makefile.in generated automatically by automake 1.4 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.