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,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 {
public MarshalledObject(Object obj) {
throw new Error("Not implemented");
extends Object implements Serializable
{
//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,58 +66,133 @@ 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
*/
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)
throws MalformedURLException, ClassNotFoundException
public static Class loadClass(URL codebase, String name)
throws MalformedURLException, ClassNotFoundException
{
URL u = new URL(codebase, name + ".class");
try
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 _)
catch (IOException _)
{
throw new ClassNotFoundException(name);
throw new ClassNotFoundException(name);
}
}
public static Class loadClass(String codebase, String name)
throws MalformedURLException, ClassNotFoundException
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;
}
/**
* @deprecated
*/

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(""))
{
if (cname.equals ("UnicastRef2"))
{
// hack for interoperating with JDK
cname = "UnicastRef";
in.read (); //some unknown UnicastRef2 field
}
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();
}
}
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);
}
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 Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
return (exportObject(obj));
}
/**
* 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 NoSuchObjectException {
throw new Error("Not implemented");
}
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);
}
/**