From d74732f5cd87b68aed10ea3fcfcb24171b9f5d67 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 1 Oct 2002 03:46:43 +0000 Subject: 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 --- libjava/java/rmi/server/RMIClassLoader.java | 149 +++++++++++++++++------ libjava/java/rmi/server/RemoteObject.java | 84 +++++++++---- libjava/java/rmi/server/UnicastRemoteObject.java | 71 +++++++++-- 3 files changed, 230 insertions(+), 74 deletions(-) (limited to 'libjava/java/rmi/server') diff --git a/libjava/java/rmi/server/RMIClassLoader.java b/libjava/java/rmi/server/RMIClassLoader.java index cde97b0..da8f52c 100644 --- a/libjava/java/rmi/server/RMIClassLoader.java +++ b/libjava/java/rmi/server/RMIClassLoader.java @@ -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 */ diff --git a/libjava/java/rmi/server/RemoteObject.java b/libjava/java/rmi/server/RemoteObject.java index e73dfc5..8ae93ff 100644 --- a/libjava/java/rmi/server/RemoteObject.java +++ b/libjava/java/rmi/server/RemoteObject.java @@ -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()); -} - -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(); - } -} + 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 + } + + 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) { diff --git a/libjava/java/rmi/server/UnicastRemoteObject.java b/libjava/java/rmi/server/UnicastRemoteObject.java index 5571b9f..a9c4f35 100644 --- a/libjava/java/rmi/server/UnicastRemoteObject.java +++ b/libjava/java/rmi/server/UnicastRemoteObject.java @@ -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.->...->UnicastServer.startDGC()->UnicastRemoteObject.->... + //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, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException { - return (exportObject(obj)); -} - -public static boolean unexportObject(Remote obj, boolean force) throws NoSuchObjectException { - throw new Error("Not implemented"); -} + 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)); + } + + /** + * 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; + } } -- cgit v1.1