You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sm...@apache.org on 2006/05/19 08:00:56 UTC

svn commit: r407724 [4/11] - in /incubator/harmony/enhanced/classlib/trunk: make/ modules/rmi/make/ modules/rmi/src/main/java/java/rmi/ modules/rmi/src/main/java/java/rmi/registry/ modules/rmi/src/main/java/java/rmi/server/ modules/rmi/src/main/java/or...

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl_Stub.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl_Stub.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl_Stub.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/registry/RegistryImpl_Stub.java Thu May 18 23:00:52 2006
@@ -1,238 +1,238 @@
-/* 
-*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
-* 
-*  Licensed under the Apache License, Version 2.0 (the "License"); 
-*  you may not use this file except in compliance with the License. 
-*  You may obtain a copy of the License at 
-* 
-*    http://www.apache.org/licenses/LICENSE-2.0 
-* 
-*  Unless required by applicable law or agreed to in writing, software 
-*  distributed under the License is distributed on an "AS IS" BASIS, 
-*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-*  See the License for the specific language governing permissions and 
-*  limitations under the License. 
-*/
-package ar.org.fitc.rmi.registry;
-
-import java.lang.reflect.Method;
-import java.rmi.AccessException;
-import java.rmi.AlreadyBoundException;
-import java.rmi.NotBoundException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.UnexpectedException;
-import java.rmi.registry.Registry;
-import java.rmi.server.RemoteRef;
-import java.rmi.server.RemoteStub;
-
-/**
- * Generic stub used to contact a remote registry.
- * 
- * @author Gonzalo Ortega
- * 
- */
-final class RegistryImpl_Stub extends RemoteStub implements Registry {
-
-    /**
-     * 
-     */
-    private static final long serialVersionUID = 1L;
-    
-    private static final long METHOD_BIND_HASH = 
-        7583982177005850366L;
-
-    private static final long METHOD_LIST_HASH = 
-        2571371476350237748L;
-
-    private static final long METHOD_LOOK_UP_HASH = 
-        -7538657168040752697L;
-    
-    private static final long METHOD_REBIND_HASH = 
-        -8381844669958460146L;
-    
-    private static final long METHOD_UNBIND_HASH = 
-        7305022919901907578L;
-
-    private static Method methodBind;
-
-    private static Method methodList;
-    
-    private static Method methodLookup;
-    
-    private static Method methodRebind;
-
-    private static Method methodUnbind;
-
-
-    static {
-        try {
-            methodBind = Registry.class.getMethod("bind", new Class[] {
-                    String.class, Remote.class });
-            methodList = Registry.class.getMethod("list", new Class[] {});
-            methodLookup = Registry.class.getMethod("lookup",
-                    new Class[] { String.class });
-            methodRebind = Registry.class.getMethod("rebind", new Class[] {
-                    String.class, Remote.class });
-            methodUnbind = Registry.class.getMethod("unbind",
-                    new Class[] { String.class });
-        } catch (NoSuchMethodException e) {
-            throw new NoSuchMethodError("stub class initialization failed");
-        }
-    }
-
-    /**
-     * Creates a new instance of RegistryImpl_Stub starting from the received
-     * <code>RemoteRef</code>
-     * 
-     * @param ref
-     *            The <code>RemoteRef</code> for the remote registry
-     */
-    public RegistryImpl_Stub(RemoteRef ref) {
-        super(ref);
-    }
-
-    /**
-     * Puts the received key <code>name</code> and the stub <code>obj</code>
-     * in this registry, or throws an exception if the received key is already
-     * present in the registry.
-     * 
-     * @param name
-     *            The key that will be used to lookup the remote object
-     * @param obj
-     *            The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AlreadyBoundException
-     *             if <code>name</code> is already present in the table
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void bind(String name, Remote obj) throws RemoteException,
-            AlreadyBoundException, AccessException {
-        try {
-            ref.invoke(this, methodBind, new Object[] { name, obj },
-                    METHOD_BIND_HASH);
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (RemoteException e) {
-            throw e;
-        } catch (AlreadyBoundException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UnexpectedException("undeclared checked exception", e);
-        }
-    }
-
-    /**
-     * Returns all keys present in the registry in a String array.
-     * 
-     * @return The list of keys bound to the registry
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final String[] list() throws RemoteException, AccessException {
-        try {
-            Object result = ref.invoke(this, methodList, null,
-                    METHOD_LIST_HASH);
-            return ((String[]) result);
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (RemoteException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UnexpectedException("undeclared checked exception", e);
-        }
-    }
-
-    /**
-     * Returns the associated stub for the received key, or an exception if no
-     * stub is present for that key
-     * 
-     * @param name
-     *            The key used to bind the remote stub in the registry
-     * @return The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws NotBoundException
-     *             If the key is not found in the registry
-     */
-    public final Remote lookup(String name) throws RemoteException,
-            NotBoundException, AccessException {
-        try {
-            Object result = ref.invoke(this, methodLookup,
-                    new Object[] { name }, METHOD_LOOK_UP_HASH);
-            return ((Remote) result);
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (RemoteException e) {
-            throw e;
-        } catch (NotBoundException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UnexpectedException("undeclared checked exception", e);
-        }
-    }
-
-    /**
-     * Puts the received key <code>name</code> and the stub <code>obj</code>
-     * in this registry.
-     * 
-     * @param name
-     *            The key that will be used to lookup the remote object
-     * @param obj
-     *            The remote object associated with <code>name</code>
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void rebind(String name, Remote obj) throws RemoteException,
-            AccessException {
-        try {
-            ref.invoke(this, methodRebind, new Object[] { name, obj },
-                    METHOD_REBIND_HASH);
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (RemoteException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UnexpectedException("undeclared checked exception", e);
-        }
-    }
-
-    /**
-     * Removes the stub associated to the key received <code>name</code> from
-     * this registry
-     * 
-     * @param name
-     *            the name of the binding to remove
-     * @throws RemoteException
-     *             if remote communication with the registry failed
-     * @throws NotBoundException
-     *             if <code>name</code> is not found in the registry
-     * @throws AccessException
-     *             if registry denies the caller access to perform this
-     *             operation
-     */
-    public final void unbind(String name) throws RemoteException, NotBoundException,
-            AccessException {
-        try {
-            ref.invoke(this, methodUnbind, new Object[] { name },
-                    METHOD_UNBIND_HASH);
-        } catch (RuntimeException e) {
-            throw e;
-        } catch (RemoteException e) {
-            throw e;
-        } catch (NotBoundException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new UnexpectedException("undeclared checked exception", e);
-        }
-    }
-}
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed under the Apache License, Version 2.0 (the "License"); 
+*  you may not use this file except in compliance with the License. 
+*  You may obtain a copy of the License at 
+* 
+*    http://www.apache.org/licenses/LICENSE-2.0 
+* 
+*  Unless required by applicable law or agreed to in writing, software 
+*  distributed under the License is distributed on an "AS IS" BASIS, 
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+*  See the License for the specific language governing permissions and 
+*  limitations under the License. 
+*/
+package org.apache.harmony.rmi.internal.registry;
+
+import java.lang.reflect.Method;
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnexpectedException;
+import java.rmi.registry.Registry;
+import java.rmi.server.RemoteRef;
+import java.rmi.server.RemoteStub;
+
+/**
+ * Generic stub used to contact a remote registry.
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+final class RegistryImpl_Stub extends RemoteStub implements Registry {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    
+    private static final long METHOD_BIND_HASH = 
+        7583982177005850366L;
+
+    private static final long METHOD_LIST_HASH = 
+        2571371476350237748L;
+
+    private static final long METHOD_LOOK_UP_HASH = 
+        -7538657168040752697L;
+    
+    private static final long METHOD_REBIND_HASH = 
+        -8381844669958460146L;
+    
+    private static final long METHOD_UNBIND_HASH = 
+        7305022919901907578L;
+
+    private static Method methodBind;
+
+    private static Method methodList;
+    
+    private static Method methodLookup;
+    
+    private static Method methodRebind;
+
+    private static Method methodUnbind;
+
+
+    static {
+        try {
+            methodBind = Registry.class.getMethod("bind", new Class[] {
+                    String.class, Remote.class });
+            methodList = Registry.class.getMethod("list", new Class[] {});
+            methodLookup = Registry.class.getMethod("lookup",
+                    new Class[] { String.class });
+            methodRebind = Registry.class.getMethod("rebind", new Class[] {
+                    String.class, Remote.class });
+            methodUnbind = Registry.class.getMethod("unbind",
+                    new Class[] { String.class });
+        } catch (NoSuchMethodException e) {
+            throw new NoSuchMethodError("stub class initialization failed");
+        }
+    }
+
+    /**
+     * Creates a new instance of RegistryImpl_Stub starting from the received
+     * <code>RemoteRef</code>
+     * 
+     * @param ref
+     *            The <code>RemoteRef</code> for the remote registry
+     */
+    public RegistryImpl_Stub(RemoteRef ref) {
+        super(ref);
+    }
+
+    /**
+     * Puts the received key <code>name</code> and the stub <code>obj</code>
+     * in this registry, or throws an exception if the received key is already
+     * present in the registry.
+     * 
+     * @param name
+     *            The key that will be used to lookup the remote object
+     * @param obj
+     *            The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AlreadyBoundException
+     *             if <code>name</code> is already present in the table
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void bind(String name, Remote obj) throws RemoteException,
+            AlreadyBoundException, AccessException {
+        try {
+            ref.invoke(this, methodBind, new Object[] { name, obj },
+                    METHOD_BIND_HASH);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (RemoteException e) {
+            throw e;
+        } catch (AlreadyBoundException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new UnexpectedException("undeclared checked exception", e);
+        }
+    }
+
+    /**
+     * Returns all keys present in the registry in a String array.
+     * 
+     * @return The list of keys bound to the registry
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final String[] list() throws RemoteException, AccessException {
+        try {
+            Object result = ref.invoke(this, methodList, null,
+                    METHOD_LIST_HASH);
+            return ((String[]) result);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (RemoteException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new UnexpectedException("undeclared checked exception", e);
+        }
+    }
+
+    /**
+     * Returns the associated stub for the received key, or an exception if no
+     * stub is present for that key
+     * 
+     * @param name
+     *            The key used to bind the remote stub in the registry
+     * @return The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws NotBoundException
+     *             If the key is not found in the registry
+     */
+    public final Remote lookup(String name) throws RemoteException,
+            NotBoundException, AccessException {
+        try {
+            Object result = ref.invoke(this, methodLookup,
+                    new Object[] { name }, METHOD_LOOK_UP_HASH);
+            return ((Remote) result);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (RemoteException e) {
+            throw e;
+        } catch (NotBoundException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new UnexpectedException("undeclared checked exception", e);
+        }
+    }
+
+    /**
+     * Puts the received key <code>name</code> and the stub <code>obj</code>
+     * in this registry.
+     * 
+     * @param name
+     *            The key that will be used to lookup the remote object
+     * @param obj
+     *            The remote object associated with <code>name</code>
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void rebind(String name, Remote obj) throws RemoteException,
+            AccessException {
+        try {
+            ref.invoke(this, methodRebind, new Object[] { name, obj },
+                    METHOD_REBIND_HASH);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (RemoteException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new UnexpectedException("undeclared checked exception", e);
+        }
+    }
+
+    /**
+     * Removes the stub associated to the key received <code>name</code> from
+     * this registry
+     * 
+     * @param name
+     *            the name of the binding to remove
+     * @throws RemoteException
+     *             if remote communication with the registry failed
+     * @throws NotBoundException
+     *             if <code>name</code> is not found in the registry
+     * @throws AccessException
+     *             if registry denies the caller access to perform this
+     *             operation
+     */
+    public final void unbind(String name) throws RemoteException, NotBoundException,
+            AccessException {
+        try {
+            ref.invoke(this, methodUnbind, new Object[] { name },
+                    METHOD_UNBIND_HASH);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (RemoteException e) {
+            throw e;
+        } catch (NotBoundException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new UnexpectedException("undeclared checked exception", e);
+        }
+    }
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RMIDefaultClassLoaderSpi.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RMIDefaultClassLoaderSpi.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RMIDefaultClassLoaderSpi.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RMIDefaultClassLoaderSpi.java Thu May 18 23:00:52 2006
@@ -1,387 +1,387 @@
-/* 
-*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
-* 
-*  Licensed under the Apache License, Version 2.0 (the "License"); 
-*  you may not use this file except in compliance with the License. 
-*  You may obtain a copy of the License at 
-* 
-*    http://www.apache.org/licenses/LICENSE-2.0 
-* 
-*  Unless required by applicable law or agreed to in writing, software 
-*  distributed under the License is distributed on an "AS IS" BASIS, 
-*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-*  See the License for the specific language governing permissions and 
-*  limitations under the License. 
-*/
-package ar.org.fitc.rmi.runtime;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.rmi.server.RMIClassLoader;
-import java.rmi.server.RMIClassLoaderSpi;
-import java.util.Arrays;
-import java.util.HashMap;
-
-import ar.org.fitc.rmi.utils.Pair;
-import ar.org.fitc.rmi.utils.PropertiesReader;
-
-/**
- * This is the default RMI implementation of the
- * {@link java.rmi.server.RMIClassLoaderSpi} interface. The implementation of
- * these method it is specified in the
- * {@link RMIClassLoader}
- * API.
- * 
- * @author Gustavo Petri
- * 
- */
-public class RMIDefaultClassLoaderSpi extends RMIClassLoaderSpi {
-
-    /**
-     * A <code>String</code> that serves as a cache fot the codebaseProp
-     * property.
-     */
-    private String codebaseProp;
-
-    /**
-     * A flag that represents the unexistence of a <code>SecurityManager</code>.
-     */
-    private boolean noSecurityManager;
-
-    /**
-     * The actual <code>SecurityManager</code> instance of the class.
-     */
-    private SecurityManager securityManager;
-
-    /**
-     * This is a mapping between pairs of sorted codebase Strings and
-     * <code>ClassLoader</code> instances to <code>WeakReferences</code> to
-     * the <code>URLClassLoader</code> cached in this table.
-     */
-    private HashMap<Pair<String, ClassLoader>, WeakReference<URLClassLoader>> classLoaderMap;
-
-    /**
-     * Constructs a default {@link java.rmi.server.RMIClassLoaderSpi}
-     * instance and it initializes the private variables.
-     */
-    public RMIDefaultClassLoaderSpi() {
-
-        super();
-        codebaseProp = PropertiesReader.readString("java.rmi.server.codebase");
-        securityManager = System.getSecurityManager();
-        if (securityManager == null) {
-            noSecurityManager = true;
-        } else {
-            noSecurityManager = false;
-        }
-        classLoaderMap = 
-            new HashMap<Pair<String, ClassLoader>, WeakReference<URLClassLoader>>();
-    }
-
-    @Override
-    /**
-     * Should construct a Proxy Class that implements all the interfaces passed
-     * as parameter.
-     * 
-     * @param codebase
-     *            a <code>String</code> that represent the specified directory
-     * @param interfaces
-     *            a array of <code>Strings</code> interfaces
-     * @param defaultLoader
-     *            responsible for loading classes
-     * @return a Proxy Class that implements all the interfaces
-     * @throws MalformedURLException
-     *             no legal protocol could be found in a specification string
-     * @throws ClassNotFoundException
-     *             if there is no Classloader for the specified interfaces
-     */
-    public final Class<?> loadProxyClass(String codebase, String[] interfaces,
-            ClassLoader defaultLoader) throws MalformedURLException,
-            ClassNotFoundException {
-        Class<?>[] interfaceClasses = new Class[interfaces.length];
-        ClassLoader notPublicClassloader = null;
-
-        for (int i = 0; i < interfaces.length; i++) {
-            interfaceClasses[i] = loadClass(codebase, interfaces[i],
-                    defaultLoader);
-            int modifier = interfaceClasses[i].getModifiers();
-            if (!Modifier.isPublic(modifier)) {
-                if (notPublicClassloader == null) {
-                    notPublicClassloader = interfaceClasses[i].getClassLoader();
-                } else if (!notPublicClassloader.equals(interfaceClasses[i]
-                        .getClassLoader())) {
-                    throw new LinkageError(
-                            "There is no Classloader for the specified interfaces");
-                }
-            }
-        }
-        if (notPublicClassloader != null) {
-            try {
-                return Proxy.getProxyClass(notPublicClassloader,
-                        interfaceClasses);
-            } catch (Exception e) {
-                throw new LinkageError(
-                        "There is no Classloader for the specified interfaces");
-            }
-        } 
-        try {
-            ClassLoader cl = getClassLoader(codebase);
-            return Proxy.getProxyClass(cl, interfaceClasses);
-        } catch (IllegalArgumentException e) {
-            try {
-                return Proxy.getProxyClass(defaultLoader, interfaceClasses);
-            } catch (IllegalArgumentException e1) {
-                throw new ClassNotFoundException(
-                        "There is no Classloader for the specified interfaces",
-                        e);
-            }
-        }
-    }
-
-    @Override
-    /**
-     * Specified in the
-     * {@link java.rmi.server.RMIClassLoader#getDefaultProviderInstance} Method.
-     * Returns the
-     * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
-     * which has loaded the Class.
-     * 
-     * @param cl
-     *            the specified Class
-     * @return the
-     *         {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
-     *         which has loaded the Class.
-     */
-    public final String getClassAnnotation(Class cl) {
-
-        java.lang.ClassLoader classLoader = cl.getClassLoader();
-
-        String codebase = 
-            PropertiesReader.readString("java.rmi.server.codebase");
-
-        if (classLoader == null) {
-            return codebase;
-        }
-        java.lang.ClassLoader cLoader = classLoader;
-        while (cLoader != null) {
-            if (ClassLoader.getSystemClassLoader().equals(classLoader)) {
-                return codebase;
-            }
-            if (cl != null) {
-                cLoader = cLoader.getParent();
-            }
-        }
-
-        if (classLoader instanceof URLClassLoader
-                && !ClassLoader.getSystemClassLoader().equals(classLoader)) {
-            try {
-                URL urls[] = ((URLClassLoader) classLoader).getURLs();
-                String ret = null;
-
-                /*
-                 * FIXME HARD: Check Permissions: If the URLClassLoader was
-                 * created by this provider to service an invocation of its
-                 * loadClass or loadProxyClass methods, then no permissions are
-                 * required to get the associated codebase string. If it is an
-                 * arbitrary other URLClassLoader instance, then if there is a
-                 * security manager, its checkPermission method will be invoked
-                 * once for each URL returned by the getURLs method, with the
-                 * permission returned by invoking
-                 * openConnection().getPermission() on each URL
-                 */
-
-                if (urls != null) {
-                    for (URL url : urls) {
-                        if (ret == null) {
-                            ret = new String(url.toExternalForm());
-                        } else {
-                            ret += " " + url.toExternalForm();
-                        }
-                    }
-                }
-
-                return ret;
-            } catch (SecurityException e) {
-                return codebase;
-            }
-        } 
-        return codebase;
-    }
-
-    @Override
-    /**
-     * Specified in the {@link java.rmi.server.RMIClassLoader#loadClass(String)}
-     * Method. It loads the class directly.
-     * 
-     * @param codebase
-     *            a <code>String</code> that represent the specified directory
-     * @param name
-     *            of the class.
-     * @param defaultLoader
-     *            responsible for loading classes
-     * @return a Proxy Class
-     * @throws MalformedURLException
-     *             no legal protocol could be found in a specification string
-     * @throws ClassNotFoundException
-     *             if there is no Classloader for the specified interfaces
-     */
-    public final Class<?> loadClass(String codebase, String name,
-            ClassLoader defaultLoader) throws MalformedURLException,
-            ClassNotFoundException {
-        Class<?> ret;
-
-        if (defaultLoader != null) {
-            try {
-                ret = Class.forName(name, false, defaultLoader);
-            } catch (ClassNotFoundException e) {
-                try {
-                    ret = Class.forName(name, false, getClassLoader(codebase));
-                } catch (SecurityException e1) {
-                    ret = Class.forName(name, false, Thread.currentThread()
-                            .getContextClassLoader());
-                }
-            }
-        } else {
-            try {
-                ret = Class.forName(name, false, getClassLoader(codebase));
-            } catch (SecurityException e1) {
-                ret = Class.forName(name, false, Thread.currentThread()
-                        .getContextClassLoader());
-            }
-        }
-        return ret;
-    }
-
-    @Override
-    /**
-     * Specified in the
-     * {@link java.rmi.server.RMIClassLoader#getClassLoader(String)} Method.
-     * Returns the corresponding
-     * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
-     * to the codebase
-     * 
-     * @param codebase
-     *            a <code>String</code> that represent the specified directory
-     * @return the corresponding
-     *         {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
-     * @throws MalformedURLException
-     *             no legal protocol could be found in a specification string
-     */
-    public final ClassLoader getClassLoader(String codebase)
-            throws MalformedURLException {
-
-        if (!noSecurityManager) {
-            securityManager.checkPermission(
-                    new RuntimePermission("getClassLoader"));
-        } else {
-            return Thread.currentThread().getContextClassLoader();
-        }
-        return getClassLoaderFromCodebase(codebase);
-    }
-
-    /**
-     * Specified in the {@link java.rmi.server.RMIClassLoader}.
-     * 
-     * @param codebase
-     *            a <code>String</code> that represent the specified directory
-     * @return the corresponding
-     *         {@link ClassLoader}
-     * @throws MalformedURLException
-     *             no legal protocol could be found in a specification string
-     */
-    private final ClassLoader getClassLoaderFromCodebase(String codebase)
-            throws MalformedURLException {
-        ClassLoader classLoader = null;
-        
-        String tempCodebase = (codebase == null) ? codebaseProp : codebase;
-        /*
-         * The API Specification always assumes that the property
-         * java.rmi.server.codebase is correctly setted, and it does not specify
-         * what to do when returns null. In this case we always return
-         * Thread.currentThread().getContextClassLoader();
-         */
-
-        if (tempCodebase == null) {
-            return Thread.currentThread().getContextClassLoader();
-        }
-        tempCodebase = sortURLs(tempCodebase);
-        Pair<String, ClassLoader> key = new Pair<String, ClassLoader>(
-                tempCodebase, Thread.currentThread().getContextClassLoader());
-        if (classLoaderMap.containsKey(key)) {
-            classLoader = classLoaderMap.get(key).get();
-        }
-        if (classLoader == null) {
-            URL[] urls = getURLs(codebase);
-            if (urls == null) {
-                return null;
-            }
-            for (URL url : urls) {
-                try {
-                    securityManager.checkPermission(url.openConnection()
-                            .getPermission());
-                } catch (IOException e) {
-                    throw new SecurityException(e);
-                }
-            }
-            classLoader = new URLClassLoader(urls);
-            classLoaderMap.put(key, new WeakReference<URLClassLoader>(
-                    (URLClassLoader) classLoader));
-        }
-        return classLoader;
-    }
-
-    /**
-     * Takes a <EM>space separated</EM> list of URL's as a String, and sorts
-     * it. For that purpose the String must be parsed.
-     * 
-     * @param urls
-     *            a list of URL's
-     * @return an alphabetic order list of URL's
-     */
-    private final static String sortURLs(String urls) {
-        String ret = null;
-
-        if (urls != null) {
-            String[] codebaseSplit = urls.split("( )+");
-            if (codebaseSplit.length > 0) {
-                ret = new String();
-                Arrays.sort(codebaseSplit);
-                for (String url : codebaseSplit) {
-                    ret += url + " ";
-                }
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Takes a <EM>space separated</EM> list of URL's as a <code>String</code>,
-     * and returns an array of URL's.
-     * 
-     * @param urls
-     *            a list of URL's as a <code>String</code>
-     * @return an array of URL's
-     * @throws MalformedURLException
-     *             no legal protocol could be found in a specification string
-     */
-    private final static URL[] getURLs(String urls) throws MalformedURLException {
-        URL[] realURLs = null;
-
-        if (urls == null) {
-            return realURLs;
-        }
-        String[] codebaseSplit = urls.split("( )+");
-        if (codebaseSplit.length > 0) {
-            realURLs = new URL[codebaseSplit.length];
-            for (int i = 0; i < codebaseSplit.length; i++) {
-                realURLs[i] = new URL(codebaseSplit[i]);
-            }
-        }
-        return realURLs;
-    }
-}
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed under the Apache License, Version 2.0 (the "License"); 
+*  you may not use this file except in compliance with the License. 
+*  You may obtain a copy of the License at 
+* 
+*    http://www.apache.org/licenses/LICENSE-2.0 
+* 
+*  Unless required by applicable law or agreed to in writing, software 
+*  distributed under the License is distributed on an "AS IS" BASIS, 
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+*  See the License for the specific language governing permissions and 
+*  limitations under the License. 
+*/
+package org.apache.harmony.rmi.internal.runtime;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.rmi.server.RMIClassLoader;
+import java.rmi.server.RMIClassLoaderSpi;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.apache.harmony.rmi.internal.utils.Pair;
+import org.apache.harmony.rmi.internal.utils.PropertiesReader;
+
+/**
+ * This is the default RMI implementation of the
+ * {@link java.rmi.server.RMIClassLoaderSpi} interface. The implementation of
+ * these method it is specified in the
+ * {@link RMIClassLoader}
+ * API.
+ * 
+ * @author Gustavo Petri
+ * 
+ */
+public class RMIDefaultClassLoaderSpi extends RMIClassLoaderSpi {
+
+    /**
+     * A <code>String</code> that serves as a cache fot the codebaseProp
+     * property.
+     */
+    private String codebaseProp;
+
+    /**
+     * A flag that represents the unexistence of a <code>SecurityManager</code>.
+     */
+    private boolean noSecurityManager;
+
+    /**
+     * The actual <code>SecurityManager</code> instance of the class.
+     */
+    private SecurityManager securityManager;
+
+    /**
+     * This is a mapping between pairs of sorted codebase Strings and
+     * <code>ClassLoader</code> instances to <code>WeakReferences</code> to
+     * the <code>URLClassLoader</code> cached in this table.
+     */
+    private HashMap<Pair<String, ClassLoader>, WeakReference<URLClassLoader>> classLoaderMap;
+
+    /**
+     * Constructs a default {@link java.rmi.server.RMIClassLoaderSpi}
+     * instance and it initializes the private variables.
+     */
+    public RMIDefaultClassLoaderSpi() {
+
+        super();
+        codebaseProp = PropertiesReader.readString("java.rmi.server.codebase");
+        securityManager = System.getSecurityManager();
+        if (securityManager == null) {
+            noSecurityManager = true;
+        } else {
+            noSecurityManager = false;
+        }
+        classLoaderMap = 
+            new HashMap<Pair<String, ClassLoader>, WeakReference<URLClassLoader>>();
+    }
+
+    @Override
+    /**
+     * Should construct a Proxy Class that implements all the interfaces passed
+     * as parameter.
+     * 
+     * @param codebase
+     *            a <code>String</code> that represent the specified directory
+     * @param interfaces
+     *            a array of <code>Strings</code> interfaces
+     * @param defaultLoader
+     *            responsible for loading classes
+     * @return a Proxy Class that implements all the interfaces
+     * @throws MalformedURLException
+     *             no legal protocol could be found in a specification string
+     * @throws ClassNotFoundException
+     *             if there is no Classloader for the specified interfaces
+     */
+    public final Class<?> loadProxyClass(String codebase, String[] interfaces,
+            ClassLoader defaultLoader) throws MalformedURLException,
+            ClassNotFoundException {
+        Class<?>[] interfaceClasses = new Class[interfaces.length];
+        ClassLoader notPublicClassloader = null;
+
+        for (int i = 0; i < interfaces.length; i++) {
+            interfaceClasses[i] = loadClass(codebase, interfaces[i],
+                    defaultLoader);
+            int modifier = interfaceClasses[i].getModifiers();
+            if (!Modifier.isPublic(modifier)) {
+                if (notPublicClassloader == null) {
+                    notPublicClassloader = interfaceClasses[i].getClassLoader();
+                } else if (!notPublicClassloader.equals(interfaceClasses[i]
+                        .getClassLoader())) {
+                    throw new LinkageError(
+                            "There is no Classloader for the specified interfaces");
+                }
+            }
+        }
+        if (notPublicClassloader != null) {
+            try {
+                return Proxy.getProxyClass(notPublicClassloader,
+                        interfaceClasses);
+            } catch (Exception e) {
+                throw new LinkageError(
+                        "There is no Classloader for the specified interfaces");
+            }
+        } 
+        try {
+            ClassLoader cl = getClassLoader(codebase);
+            return Proxy.getProxyClass(cl, interfaceClasses);
+        } catch (IllegalArgumentException e) {
+            try {
+                return Proxy.getProxyClass(defaultLoader, interfaceClasses);
+            } catch (IllegalArgumentException e1) {
+                throw new ClassNotFoundException(
+                        "There is no Classloader for the specified interfaces",
+                        e);
+            }
+        }
+    }
+
+    @Override
+    /**
+     * Specified in the
+     * {@link java.rmi.server.RMIClassLoader#getDefaultProviderInstance} Method.
+     * Returns the
+     * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
+     * which has loaded the Class.
+     * 
+     * @param cl
+     *            the specified Class
+     * @return the
+     *         {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
+     *         which has loaded the Class.
+     */
+    public final String getClassAnnotation(Class cl) {
+
+        java.lang.ClassLoader classLoader = cl.getClassLoader();
+
+        String codebase = 
+            PropertiesReader.readString("java.rmi.server.codebase");
+
+        if (classLoader == null) {
+            return codebase;
+        }
+        java.lang.ClassLoader cLoader = classLoader;
+        while (cLoader != null) {
+            if (ClassLoader.getSystemClassLoader().equals(classLoader)) {
+                return codebase;
+            }
+            if (cl != null) {
+                cLoader = cLoader.getParent();
+            }
+        }
+
+        if (classLoader instanceof URLClassLoader
+                && !ClassLoader.getSystemClassLoader().equals(classLoader)) {
+            try {
+                URL urls[] = ((URLClassLoader) classLoader).getURLs();
+                String ret = null;
+
+                /*
+                 * FIXME HARD: Check Permissions: If the URLClassLoader was
+                 * created by this provider to service an invocation of its
+                 * loadClass or loadProxyClass methods, then no permissions are
+                 * required to get the associated codebase string. If it is an
+                 * arbitrary other URLClassLoader instance, then if there is a
+                 * security manager, its checkPermission method will be invoked
+                 * once for each URL returned by the getURLs method, with the
+                 * permission returned by invoking
+                 * openConnection().getPermission() on each URL
+                 */
+
+                if (urls != null) {
+                    for (URL url : urls) {
+                        if (ret == null) {
+                            ret = new String(url.toExternalForm());
+                        } else {
+                            ret += " " + url.toExternalForm();
+                        }
+                    }
+                }
+
+                return ret;
+            } catch (SecurityException e) {
+                return codebase;
+            }
+        } 
+        return codebase;
+    }
+
+    @Override
+    /**
+     * Specified in the {@link java.rmi.server.RMIClassLoader#loadClass(String)}
+     * Method. It loads the class directly.
+     * 
+     * @param codebase
+     *            a <code>String</code> that represent the specified directory
+     * @param name
+     *            of the class.
+     * @param defaultLoader
+     *            responsible for loading classes
+     * @return a Proxy Class
+     * @throws MalformedURLException
+     *             no legal protocol could be found in a specification string
+     * @throws ClassNotFoundException
+     *             if there is no Classloader for the specified interfaces
+     */
+    public final Class<?> loadClass(String codebase, String name,
+            ClassLoader defaultLoader) throws MalformedURLException,
+            ClassNotFoundException {
+        Class<?> ret;
+
+        if (defaultLoader != null) {
+            try {
+                ret = Class.forName(name, false, defaultLoader);
+            } catch (ClassNotFoundException e) {
+                try {
+                    ret = Class.forName(name, false, getClassLoader(codebase));
+                } catch (SecurityException e1) {
+                    ret = Class.forName(name, false, Thread.currentThread()
+                            .getContextClassLoader());
+                }
+            }
+        } else {
+            try {
+                ret = Class.forName(name, false, getClassLoader(codebase));
+            } catch (SecurityException e1) {
+                ret = Class.forName(name, false, Thread.currentThread()
+                        .getContextClassLoader());
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    /**
+     * Specified in the
+     * {@link java.rmi.server.RMIClassLoader#getClassLoader(String)} Method.
+     * Returns the corresponding
+     * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
+     * to the codebase
+     * 
+     * @param codebase
+     *            a <code>String</code> that represent the specified directory
+     * @return the corresponding
+     *         {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ClassLoader.html"><code>ClassLoader</code></a>}
+     * @throws MalformedURLException
+     *             no legal protocol could be found in a specification string
+     */
+    public final ClassLoader getClassLoader(String codebase)
+            throws MalformedURLException {
+
+        if (!noSecurityManager) {
+            securityManager.checkPermission(
+                    new RuntimePermission("getClassLoader"));
+        } else {
+            return Thread.currentThread().getContextClassLoader();
+        }
+        return getClassLoaderFromCodebase(codebase);
+    }
+
+    /**
+     * Specified in the {@link java.rmi.server.RMIClassLoader}.
+     * 
+     * @param codebase
+     *            a <code>String</code> that represent the specified directory
+     * @return the corresponding
+     *         {@link ClassLoader}
+     * @throws MalformedURLException
+     *             no legal protocol could be found in a specification string
+     */
+    private final ClassLoader getClassLoaderFromCodebase(String codebase)
+            throws MalformedURLException {
+        ClassLoader classLoader = null;
+        
+        String tempCodebase = (codebase == null) ? codebaseProp : codebase;
+        /*
+         * The API Specification always assumes that the property
+         * java.rmi.server.codebase is correctly setted, and it does not specify
+         * what to do when returns null. In this case we always return
+         * Thread.currentThread().getContextClassLoader();
+         */
+
+        if (tempCodebase == null) {
+            return Thread.currentThread().getContextClassLoader();
+        }
+        tempCodebase = sortURLs(tempCodebase);
+        Pair<String, ClassLoader> key = new Pair<String, ClassLoader>(
+                tempCodebase, Thread.currentThread().getContextClassLoader());
+        if (classLoaderMap.containsKey(key)) {
+            classLoader = classLoaderMap.get(key).get();
+        }
+        if (classLoader == null) {
+            URL[] urls = getURLs(codebase);
+            if (urls == null) {
+                return null;
+            }
+            for (URL url : urls) {
+                try {
+                    securityManager.checkPermission(url.openConnection()
+                            .getPermission());
+                } catch (IOException e) {
+                    throw new SecurityException(e);
+                }
+            }
+            classLoader = new URLClassLoader(urls);
+            classLoaderMap.put(key, new WeakReference<URLClassLoader>(
+                    (URLClassLoader) classLoader));
+        }
+        return classLoader;
+    }
+
+    /**
+     * Takes a <EM>space separated</EM> list of URL's as a String, and sorts
+     * it. For that purpose the String must be parsed.
+     * 
+     * @param urls
+     *            a list of URL's
+     * @return an alphabetic order list of URL's
+     */
+    private final static String sortURLs(String urls) {
+        String ret = null;
+
+        if (urls != null) {
+            String[] codebaseSplit = urls.split("( )+");
+            if (codebaseSplit.length > 0) {
+                ret = new String();
+                Arrays.sort(codebaseSplit);
+                for (String url : codebaseSplit) {
+                    ret += url + " ";
+                }
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Takes a <EM>space separated</EM> list of URL's as a <code>String</code>,
+     * and returns an array of URL's.
+     * 
+     * @param urls
+     *            a list of URL's as a <code>String</code>
+     * @return an array of URL's
+     * @throws MalformedURLException
+     *             no legal protocol could be found in a specification string
+     */
+    private final static URL[] getURLs(String urls) throws MalformedURLException {
+        URL[] realURLs = null;
+
+        if (urls == null) {
+            return realURLs;
+        }
+        String[] codebaseSplit = urls.split("( )+");
+        if (codebaseSplit.length > 0) {
+            realURLs = new URL[codebaseSplit.length];
+            for (int i = 0; i < codebaseSplit.length; i++) {
+                realURLs[i] = new URL(codebaseSplit[i]);
+            }
+        }
+        return realURLs;
+    }
+}

Modified: incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RemoteReferenceManager.java
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RemoteReferenceManager.java?rev=407724&r1=407183&r2=407724&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RemoteReferenceManager.java (original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/rmi/src/main/java/org/apache/harmony/rmi/internal/runtime/RemoteReferenceManager.java Thu May 18 23:00:52 2006
@@ -1,477 +1,477 @@
-/* 
-*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
-* 
-*  Licensed under the Apache License, Version 2.0 (the "License"); 
-*  you may not use this file except in compliance with the License. 
-*  You may obtain a copy of the License at 
-* 
-*    http://www.apache.org/licenses/LICENSE-2.0 
-* 
-*  Unless required by applicable law or agreed to in writing, software 
-*  distributed under the License is distributed on an "AS IS" BASIS, 
-*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-*  See the License for the specific language governing permissions and 
-*  limitations under the License. 
-*/
-package ar.org.fitc.rmi.runtime;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Proxy;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.StubNotFoundException;
-import java.rmi.server.ObjID;
-import java.rmi.server.RemoteObjectInvocationHandler;
-import java.rmi.server.RemoteRef;
-import java.rmi.server.RemoteStub;
-import java.rmi.server.ServerRef;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import ar.org.fitc.rmi.dgc.server.DGCImpl;
-import ar.org.fitc.rmi.server.UnicastServerRefImpl;
-import ar.org.fitc.rmi.transport.TransportManager;
-import ar.org.fitc.rmi.utils.Pair;
-import ar.org.fitc.rmi.utils.PropertiesReader;
-import ar.org.fitc.rmi.utils.RemoteUtils;
-
-/*
- * NOTE: 
- * This class has been modified in order to support 
- * Java VM 1.4.2 using the javac's target jsr14 
- */
-
-/**
- * Implements a singleton which provides neccessary funtionality for
- * remote object exportation, remote object management, stub generation,
- * call execution, etc. 
- * 
- * @author Gonzalo Ortega
- * 
- */
-public final class RemoteReferenceManager {
-
-    private static RemoteReferenceManager rrm;
-
-    private Map<ObjID, ServerRef> serverRefsMap;
-
-    private Map<Remote, Pair<Remote, ObjID>> exportedRemotes;
-
-    private DGCImpl dgc;
-
-    /**
-     * Implements the singleton behavior. If there is an instance of
-     * <code>RemoteReferenceManager</code> is returned, else a new instance is
-     * created and returned.
-     * 
-     * @return the only <code>RemoteReferenceManager</code> instance
-     */
-    public final static synchronized RemoteReferenceManager getRemoteReferenceManager() {
-        if (rrm == null) {
-            rrm = new RemoteReferenceManager();
-        }
-        return rrm;
-    }
-    
-    /**
-     * Creates a new instance of <code>RemoteReferenceManager</code>. This
-     * created instance should be the one and only. (<code>RemoteReferenceManager</code>
-     * is a Singleton object)
-     */
-    private RemoteReferenceManager() {
-        // Initialize internal tables
-        serverRefsMap = new Hashtable<ObjID, ServerRef>();
-        exportedRemotes = Collections
-                .synchronizedMap(new WeakHashMap<Remote, Pair<Remote, ObjID>>());
-
-        // Export the Distributed Garbage Collector
-        dgc = new DGCImpl();
-        ObjID objID = new ObjID(ObjID.DGC_ID);
-        UnicastServerRefImpl sref = new UnicastServerRefImpl(dgc, objID, null);
-        storeExportData(null, objID, sref, null);
-    }
-
-    /**
-     * Stores the data generated during object exportation into the
-     * <code>RemoteReferenceManager</code> internal tables
-     * 
-     * @param obj
-     *            The remote object being exported
-     * @param objID
-     *            The <code>ObjID</code> generated for <code>obj</code>
-     * @param sref
-     *            The <code>ServerRef</code> generated for <code>obj</code>
-     * @param stub
-     *            The stub generated for <code>obj</code>
-     */
-    public final void storeExportData(Remote obj, ObjID objID, ServerRef sref,
-            Remote stub) {
-        serverRefsMap.put(objID, sref);
-        exportedRemotes.put(obj, new Pair<Remote, ObjID>(stub, objID));
-        dgc.register(objID, obj);
-    }
-
-    /**
-     * Returns <code>true</code> if <code>obj</code> has been exported to
-     * the RMI Runtime.
-     * 
-     * @param obj
-     *            The remote object that could be exported
-     * @return <code>true</code> if <code>obj</code> has been exported to
-     *         the RMI Runtime
-     */
-    public final boolean isExported(Remote obj) {
-        if ((exportedRemotes.containsKey(obj))
-                && !(obj instanceof RemoteObjectInvocationHandler)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Receives a dispatch request from the Transport Layer and forwards it to
-     * the appropriate dispatcher object.
-     * 
-     * @param objID
-     *            The <code>ObjID</code> received in the request
-     * @param hash
-     *            The method identificator received in the request
-     * @param args
-     *            The arguments received in the request
-     * @return The result of the invocation in the remote object
-     * @throws Exception
-     *             If the invocation of the method throws an exception
-     */
-    public final Object executeCall(ObjID objID, long hash, Object[] args)
-            throws Exception {
-        if (objID == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID == null).");
-        }
-        ServerRef sref = serverRefsMap.get(objID);
-        if (sref == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID not found in lookup).");
-        }
-
-        /*
-         * REVIEW: For call execution the instance of ServerRef needed is of
-         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
-         * specify the dispach method) Review the casting or the type stored in
-         * the container when the implementation of the Activation framework
-         * takes place.
-         */
-        if (sref instanceof UnicastServerRefImpl) {
-            return ((UnicastServerRefImpl) sref).executeCall(args, hash);
-        }
-        throw new NoSuchObjectException(
-                "Remote server not available (No UnicastServerImpl reference).");
-    }
-
-    /**
-     * Returns a stub for the exported object <code>obj</code>
-     * 
-     * @param obj
-     *            the remote object that the stub is requested for
-     * @return the stub corresponding to <code>obj</code>
-     * @throws NoSuchObjectException
-     *             if there is no stub correspondig to <code>obj</code>
-     */
-    public final Remote getStub(Remote obj) throws NoSuchObjectException {
-        if (obj == null) {
-            throw new NoSuchObjectException(
-                    "Invalid (null) Remote server object.");
-        }
-        Pair<Remote, ObjID> data;
-        if ((data = exportedRemotes.get(obj)) != null) {
-            return data.getFirst();
-        }
-        throw new NoSuchObjectException("Stub not found for this object.");
-    }
-
-    /**
-     * Removes the remote object <code>obj</code> from internal tables, and
-     * delegates the unexportation to the Transport Layer, in order to perform
-     * the neccessary cleanup.
-     * 
-     * @param obj
-     *            The remote object that will be unexported
-     * @param force
-     *            if true, unexports the object even if there are pending calls;
-     *            if false, only unexports the object if there are no pending
-     *            calls
-     * @return true if the remote object was unexported, false otherwise
-     * @throws NoSuchObjectException
-     *             if the remote object was not exported
-     */
-    public final boolean unexportObject(Remote obj, boolean force)
-            throws NoSuchObjectException {
-        if (obj == null) {
-            throw new NoSuchObjectException(
-                    "Invalid (null) Remote server object.");
-        }
-        Pair<Remote, ObjID> data;
-        if ((data = exportedRemotes.get(obj)) == null) {
-            throw new NoSuchObjectException("Object not exported.");
-        }
-        ObjID objID = data.getSecond();
-
-        TransportManager tm = TransportManager.getTransportManager();
-        if (tm.unexport(objID, force)) {
-            // Remove data for this object from the internal tables
-            serverRefsMap.remove(objID);
-            exportedRemotes.remove(obj);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Removes the received <code>objID</code> from internal tables, and
-     * delegates the unexportation to the Transport Layer, in order to perform
-     * the neccessary cleanup.
-     * 
-     * @param objID
-     *            The <code>objID</code> that will be removed
-     * @return true if the remote object was unexported, false otherwise
-     * @throws NoSuchObjectException
-     *             if the <code>objID</code> was not found
-     */
-    public final boolean unexportObjectDGC(ObjID objID)
-            throws NoSuchObjectException {
-        if (objID == null) {
-            throw new NoSuchObjectException(
-                    "Invalid (null) Remote server object.");
-        }
-        if (!(serverRefsMap.containsKey(objID))) {
-            return true;
-        }
-        TransportManager tm = TransportManager.getTransportManager();
-        if (tm.unexport(objID, true)) {
-            // Remove data for this object from the internal tables
-            serverRefsMap.remove(objID);
-            // Removing data from exportedRemotes is not needed, because it will
-            // be
-            // automatically removed when GC collects the remote object
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Returns the number of arguments received by the method represented by
-     * <code>methodHash</code> in the remote object referenced by
-     * <code>objID</code>
-     * 
-     * @param objID
-     *            The <code>ObjID</code> received in the request
-     * @param methodHash
-     *            The method identificator received in the request
-     * @return the number of arguments of the method
-     * @throws NoSuchObjectException
-     *             if there isn't any exported object with the received
-     *             <code>ObjID</code>
-     */
-    public final int getArgsCount(ObjID objID, long methodHash)
-            throws NoSuchObjectException {
-        if (objID == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID == null).");
-        }
-        ServerRef sref = serverRefsMap.get(objID);
-        if (sref == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID not found in lookup).");
-        }
-
-        /*
-         * REVIEW: For call execution the instance of ServerRef needed is of
-         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
-         * specify the getArgsCount method) Review the casting or the type
-         * stored in the container when the implementation of the Activation
-         * framework takes place.
-         */
-        if (sref instanceof UnicastServerRefImpl) {
-            return ((UnicastServerRefImpl) sref).getArgsCount(methodHash);
-        } 
-        throw new NoSuchObjectException(
-                    "Remote server not available (No UnicastServerImpl reference).");
-    }
-
-    /**
-     * Returns true if the method represented by <code>methodHash</code> in
-     * the remote object referenced by <code>objID</code> returns any value.
-     * (the return type of the method is different than <code>void</code>)
-     * 
-     * @param objID
-     *            The <code>ObjID</code> received in the request
-     * @param methodHash
-     *            The method identificator received in the request
-     * @return true if the return type of the method is different than
-     *         <code>void</code>, otherwise returns false
-     * @throws NoSuchObjectException
-     *             if there isn't any exported object with the received
-     *             <code>ObjID</code>
-     */
-    public final boolean sendReturnValue(ObjID objID, long methodHash)
-            throws NoSuchObjectException {
-        if (objID == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID == null).");
-        }
-        ServerRef sref = serverRefsMap.get(objID);
-        if (sref == null) {
-            throw new NoSuchObjectException(
-                    "Remote server not available (ObjID not found in lookup).");
-        }
-
-        /*
-         * REVIEW: For call execution the instance of ServerRef needed is of
-         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
-         * specify the sendReturnValue method) Review the casting or the type
-         * stored in the container when the implementation of the Activation
-         * framework takes place.
-         */
-        if (sref instanceof UnicastServerRefImpl) {
-            return ((UnicastServerRefImpl) sref).sendReturnValue(methodHash);
-        } 
-        throw new NoSuchObjectException(
-                    "Remote server not available (No UnicastServerImpl reference).");
-    }
-
-    /**
-     * Instantiates and returns a stub for a remote object starting from the
-     * class generated by <code>rmic</code>. If the class is no found, an
-     * exception is thrown.
-     * 
-     * @param ref
-     *            The remote reference for the stub
-     * @param obj
-     *            The object, that the stub will represent
-     * @return a stub for <code>obj</code>
-     * @throws StubNotFoundException
-     *             if the stub class is not found, or any other problem arises
-     *             during stub instantiation.
-     */
-    public final RemoteStub createRegularStub(RemoteRef ref, Remote obj)
-            throws StubNotFoundException {
-
-        Class stubBaseClass = findStubBaseClass(obj.getClass());
-        String stubClassName = stubBaseClass.getName() + "_Stub";
-        Class[] argsClass = new Class[] { java.rmi.server.RemoteRef.class };
-        Object[] args = new Object[] { ref };
-        Constructor constructor;
-        
-        Object stub;
-        try {
-            Class stubClass = Class.forName(stubClassName, true, stubBaseClass
-                    .getClassLoader());
-            constructor = stubClass.getConstructor(argsClass);
-        } catch (Exception e) {
-            throw new StubNotFoundException(stubClassName
-                    + ": Stub class not found", e);
-        }
-
-        try {
-            stub = constructor.newInstance(args);
-        } catch (Exception e) {
-            throw new StubNotFoundException(
-                    "Error during stub instantiation - " + stubClassName, e);
-        }
-
-        if (stub instanceof RemoteStub) {
-            return (RemoteStub) stub;
-        }
-        throw new StubNotFoundException(stubClassName
-                    + " doesn't inherits from RemoteStub.");
-    }
-
-    /**
-     * Instantiates and returns a stub either starting from a class generated by
-     * <code>rmic</code>, or creating a dynamic proxy class for the remote
-     * object.
-     * 
-     * @param ref
-     *            The remote reference for the stub
-     * @param obj
-     *            The object, that the stub will represent
-     * @return a stub for <code>obj</code>
-     * @throws StubNotFoundException
-     *             If a dynamic proxy can not be instantiated for that object.
-     */
-    public final Remote createStub(RemoteRef ref, Remote obj)
-            throws StubNotFoundException {
-        Remote stub = null;
-        boolean ignoreStubClasses = false;
-        String propertyValue;
-
-        // Verify if the old non-dynamic stubs should be ignored
-        propertyValue = PropertiesReader
-                .readString("java.rmi.server.ignoreStubClasses");
-        if (propertyValue != null) {
-            ignoreStubClasses = propertyValue.equalsIgnoreCase("true");
-        }
-
-        if (!ignoreStubClasses) {
-            try {
-                stub = createRegularStub(ref, obj);
-                return stub;
-            } catch (StubNotFoundException e) {
-                // An error has been produced during regular stub instantiation.
-                // ignore it and try now a dynamic proxy.
-            }
-        }
-
-        Set<Class> remoteSet = (RemoteUtils.getRemoteInterfaces(obj.getClass()));
-        Class[] remoteInterfaces = new Class[remoteSet.size()];
-        remoteSet.toArray(remoteInterfaces);
-
-        try {
-            stub = (Remote) Proxy.newProxyInstance(obj.getClass()
-                    .getClassLoader(), remoteInterfaces,
-                    new RemoteObjectInvocationHandler(ref));
-        } catch (IllegalArgumentException ex) {
-            throw new StubNotFoundException(
-                    "Couldn't create dynamic proxy for " + obj, ex);
-        }
-        return stub;
-    }
-
-    /**
-     * Finds the "root class" according to RMI Specification, wich name will be
-     * used for constructing the name of the stub class that corresponds to the
-     * <code>inspect</code> class.
-     * 
-     * @param inspect
-     *            the class of the object
-     * @return the root class of the object
-     * @throws StubNotFoundException
-     *             If the class does not implement any remote interfaces
-     */
-    // Returns the apropriate root class for a stub of the class received as
-    // parameter.
-    private final Class findStubBaseClass(Class inspect)
-            throws StubNotFoundException {
-        Set<Class> remoteInterfacesList = RemoteUtils
-                .getRemoteInterfaces(inspect);
-
-        do {
-            // Check if the class implements any Remote Interface directly
-            Class[] directInterfacesList = inspect.getInterfaces();
-            for (Class directInterface : directInterfacesList) {
-                if (remoteInterfacesList.contains(directInterface)) {
-                    return inspect;
-                }
-            }
-            // The interfaces implemented directly aren't remote interfaces...
-            // check now the interfaces implemented directly by the superclass.
-            inspect = inspect.getSuperclass();
-        } while (inspect != null);
-
-        throw new StubNotFoundException(
-                "The remote object doesn't implement any Remote interfaces.");
-    }
-}
+/* 
+*  Copyright 2005 The Apache Software Foundation or its licensors, as applicable. 
+* 
+*  Licensed under the Apache License, Version 2.0 (the "License"); 
+*  you may not use this file except in compliance with the License. 
+*  You may obtain a copy of the License at 
+* 
+*    http://www.apache.org/licenses/LICENSE-2.0 
+* 
+*  Unless required by applicable law or agreed to in writing, software 
+*  distributed under the License is distributed on an "AS IS" BASIS, 
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+*  See the License for the specific language governing permissions and 
+*  limitations under the License. 
+*/
+package org.apache.harmony.rmi.internal.runtime;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Proxy;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.StubNotFoundException;
+import java.rmi.server.ObjID;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteRef;
+import java.rmi.server.RemoteStub;
+import java.rmi.server.ServerRef;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.apache.harmony.rmi.internal.dgc.server.DGCImpl;
+import org.apache.harmony.rmi.internal.server.UnicastServerRefImpl;
+import org.apache.harmony.rmi.internal.transport.TransportManager;
+import org.apache.harmony.rmi.internal.utils.Pair;
+import org.apache.harmony.rmi.internal.utils.PropertiesReader;
+import org.apache.harmony.rmi.internal.utils.RemoteUtils;
+
+/*
+ * NOTE: 
+ * This class has been modified in order to support 
+ * Java VM 1.4.2 using the javac's target jsr14 
+ */
+
+/**
+ * Implements a singleton which provides neccessary funtionality for
+ * remote object exportation, remote object management, stub generation,
+ * call execution, etc. 
+ * 
+ * @author Gonzalo Ortega
+ * 
+ */
+public final class RemoteReferenceManager {
+
+    private static RemoteReferenceManager rrm;
+
+    private Map<ObjID, ServerRef> serverRefsMap;
+
+    private Map<Remote, Pair<Remote, ObjID>> exportedRemotes;
+
+    private DGCImpl dgc;
+
+    /**
+     * Implements the singleton behavior. If there is an instance of
+     * <code>RemoteReferenceManager</code> is returned, else a new instance is
+     * created and returned.
+     * 
+     * @return the only <code>RemoteReferenceManager</code> instance
+     */
+    public final static synchronized RemoteReferenceManager getRemoteReferenceManager() {
+        if (rrm == null) {
+            rrm = new RemoteReferenceManager();
+        }
+        return rrm;
+    }
+    
+    /**
+     * Creates a new instance of <code>RemoteReferenceManager</code>. This
+     * created instance should be the one and only. (<code>RemoteReferenceManager</code>
+     * is a Singleton object)
+     */
+    private RemoteReferenceManager() {
+        // Initialize internal tables
+        serverRefsMap = new Hashtable<ObjID, ServerRef>();
+        exportedRemotes = Collections
+                .synchronizedMap(new WeakHashMap<Remote, Pair<Remote, ObjID>>());
+
+        // Export the Distributed Garbage Collector
+        dgc = new DGCImpl();
+        ObjID objID = new ObjID(ObjID.DGC_ID);
+        UnicastServerRefImpl sref = new UnicastServerRefImpl(dgc, objID, null);
+        storeExportData(null, objID, sref, null);
+    }
+
+    /**
+     * Stores the data generated during object exportation into the
+     * <code>RemoteReferenceManager</code> internal tables
+     * 
+     * @param obj
+     *            The remote object being exported
+     * @param objID
+     *            The <code>ObjID</code> generated for <code>obj</code>
+     * @param sref
+     *            The <code>ServerRef</code> generated for <code>obj</code>
+     * @param stub
+     *            The stub generated for <code>obj</code>
+     */
+    public final void storeExportData(Remote obj, ObjID objID, ServerRef sref,
+            Remote stub) {
+        serverRefsMap.put(objID, sref);
+        exportedRemotes.put(obj, new Pair<Remote, ObjID>(stub, objID));
+        dgc.register(objID, obj);
+    }
+
+    /**
+     * Returns <code>true</code> if <code>obj</code> has been exported to
+     * the RMI Runtime.
+     * 
+     * @param obj
+     *            The remote object that could be exported
+     * @return <code>true</code> if <code>obj</code> has been exported to
+     *         the RMI Runtime
+     */
+    public final boolean isExported(Remote obj) {
+        if ((exportedRemotes.containsKey(obj))
+                && !(obj instanceof RemoteObjectInvocationHandler)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Receives a dispatch request from the Transport Layer and forwards it to
+     * the appropriate dispatcher object.
+     * 
+     * @param objID
+     *            The <code>ObjID</code> received in the request
+     * @param hash
+     *            The method identificator received in the request
+     * @param args
+     *            The arguments received in the request
+     * @return The result of the invocation in the remote object
+     * @throws Exception
+     *             If the invocation of the method throws an exception
+     */
+    public final Object executeCall(ObjID objID, long hash, Object[] args)
+            throws Exception {
+        if (objID == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID == null).");
+        }
+        ServerRef sref = serverRefsMap.get(objID);
+        if (sref == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID not found in lookup).");
+        }
+
+        /*
+         * REVIEW: For call execution the instance of ServerRef needed is of
+         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
+         * specify the dispach method) Review the casting or the type stored in
+         * the container when the implementation of the Activation framework
+         * takes place.
+         */
+        if (sref instanceof UnicastServerRefImpl) {
+            return ((UnicastServerRefImpl) sref).executeCall(args, hash);
+        }
+        throw new NoSuchObjectException(
+                "Remote server not available (No UnicastServerImpl reference).");
+    }
+
+    /**
+     * Returns a stub for the exported object <code>obj</code>
+     * 
+     * @param obj
+     *            the remote object that the stub is requested for
+     * @return the stub corresponding to <code>obj</code>
+     * @throws NoSuchObjectException
+     *             if there is no stub correspondig to <code>obj</code>
+     */
+    public final Remote getStub(Remote obj) throws NoSuchObjectException {
+        if (obj == null) {
+            throw new NoSuchObjectException(
+                    "Invalid (null) Remote server object.");
+        }
+        Pair<Remote, ObjID> data;
+        if ((data = exportedRemotes.get(obj)) != null) {
+            return data.getFirst();
+        }
+        throw new NoSuchObjectException("Stub not found for this object.");
+    }
+
+    /**
+     * Removes the remote object <code>obj</code> from internal tables, and
+     * delegates the unexportation to the Transport Layer, in order to perform
+     * the neccessary cleanup.
+     * 
+     * @param obj
+     *            The remote object that will be unexported
+     * @param force
+     *            if true, unexports the object even if there are pending calls;
+     *            if false, only unexports the object if there are no pending
+     *            calls
+     * @return true if the remote object was unexported, false otherwise
+     * @throws NoSuchObjectException
+     *             if the remote object was not exported
+     */
+    public final boolean unexportObject(Remote obj, boolean force)
+            throws NoSuchObjectException {
+        if (obj == null) {
+            throw new NoSuchObjectException(
+                    "Invalid (null) Remote server object.");
+        }
+        Pair<Remote, ObjID> data;
+        if ((data = exportedRemotes.get(obj)) == null) {
+            throw new NoSuchObjectException("Object not exported.");
+        }
+        ObjID objID = data.getSecond();
+
+        TransportManager tm = TransportManager.getTransportManager();
+        if (tm.unexport(objID, force)) {
+            // Remove data for this object from the internal tables
+            serverRefsMap.remove(objID);
+            exportedRemotes.remove(obj);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Removes the received <code>objID</code> from internal tables, and
+     * delegates the unexportation to the Transport Layer, in order to perform
+     * the neccessary cleanup.
+     * 
+     * @param objID
+     *            The <code>objID</code> that will be removed
+     * @return true if the remote object was unexported, false otherwise
+     * @throws NoSuchObjectException
+     *             if the <code>objID</code> was not found
+     */
+    public final boolean unexportObjectDGC(ObjID objID)
+            throws NoSuchObjectException {
+        if (objID == null) {
+            throw new NoSuchObjectException(
+                    "Invalid (null) Remote server object.");
+        }
+        if (!(serverRefsMap.containsKey(objID))) {
+            return true;
+        }
+        TransportManager tm = TransportManager.getTransportManager();
+        if (tm.unexport(objID, true)) {
+            // Remove data for this object from the internal tables
+            serverRefsMap.remove(objID);
+            // Removing data from exportedRemotes is not needed, because it will
+            // be
+            // automatically removed when GC collects the remote object
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the number of arguments received by the method represented by
+     * <code>methodHash</code> in the remote object referenced by
+     * <code>objID</code>
+     * 
+     * @param objID
+     *            The <code>ObjID</code> received in the request
+     * @param methodHash
+     *            The method identificator received in the request
+     * @return the number of arguments of the method
+     * @throws NoSuchObjectException
+     *             if there isn't any exported object with the received
+     *             <code>ObjID</code>
+     */
+    public final int getArgsCount(ObjID objID, long methodHash)
+            throws NoSuchObjectException {
+        if (objID == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID == null).");
+        }
+        ServerRef sref = serverRefsMap.get(objID);
+        if (sref == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID not found in lookup).");
+        }
+
+        /*
+         * REVIEW: For call execution the instance of ServerRef needed is of
+         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
+         * specify the getArgsCount method) Review the casting or the type
+         * stored in the container when the implementation of the Activation
+         * framework takes place.
+         */
+        if (sref instanceof UnicastServerRefImpl) {
+            return ((UnicastServerRefImpl) sref).getArgsCount(methodHash);
+        } 
+        throw new NoSuchObjectException(
+                    "Remote server not available (No UnicastServerImpl reference).");
+    }
+
+    /**
+     * Returns true if the method represented by <code>methodHash</code> in
+     * the remote object referenced by <code>objID</code> returns any value.
+     * (the return type of the method is different than <code>void</code>)
+     * 
+     * @param objID
+     *            The <code>ObjID</code> received in the request
+     * @param methodHash
+     *            The method identificator received in the request
+     * @return true if the return type of the method is different than
+     *         <code>void</code>, otherwise returns false
+     * @throws NoSuchObjectException
+     *             if there isn't any exported object with the received
+     *             <code>ObjID</code>
+     */
+    public final boolean sendReturnValue(ObjID objID, long methodHash)
+            throws NoSuchObjectException {
+        if (objID == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID == null).");
+        }
+        ServerRef sref = serverRefsMap.get(objID);
+        if (sref == null) {
+            throw new NoSuchObjectException(
+                    "Remote server not available (ObjID not found in lookup).");
+        }
+
+        /*
+         * REVIEW: For call execution the instance of ServerRef needed is of
+         * type UnicastServerRefImpl, instead of ServerRef... (ServerRef doesn't
+         * specify the sendReturnValue method) Review the casting or the type
+         * stored in the container when the implementation of the Activation
+         * framework takes place.
+         */
+        if (sref instanceof UnicastServerRefImpl) {
+            return ((UnicastServerRefImpl) sref).sendReturnValue(methodHash);
+        } 
+        throw new NoSuchObjectException(
+                    "Remote server not available (No UnicastServerImpl reference).");
+    }
+
+    /**
+     * Instantiates and returns a stub for a remote object starting from the
+     * class generated by <code>rmic</code>. If the class is no found, an
+     * exception is thrown.
+     * 
+     * @param ref
+     *            The remote reference for the stub
+     * @param obj
+     *            The object, that the stub will represent
+     * @return a stub for <code>obj</code>
+     * @throws StubNotFoundException
+     *             if the stub class is not found, or any other problem arises
+     *             during stub instantiation.
+     */
+    public final RemoteStub createRegularStub(RemoteRef ref, Remote obj)
+            throws StubNotFoundException {
+
+        Class stubBaseClass = findStubBaseClass(obj.getClass());
+        String stubClassName = stubBaseClass.getName() + "_Stub";
+        Class[] argsClass = new Class[] { java.rmi.server.RemoteRef.class };
+        Object[] args = new Object[] { ref };
+        Constructor constructor;
+        
+        Object stub;
+        try {
+            Class stubClass = Class.forName(stubClassName, true, stubBaseClass
+                    .getClassLoader());
+            constructor = stubClass.getConstructor(argsClass);
+        } catch (Exception e) {
+            throw new StubNotFoundException(stubClassName
+                    + ": Stub class not found", e);
+        }
+
+        try {
+            stub = constructor.newInstance(args);
+        } catch (Exception e) {
+            throw new StubNotFoundException(
+                    "Error during stub instantiation - " + stubClassName, e);
+        }
+
+        if (stub instanceof RemoteStub) {
+            return (RemoteStub) stub;
+        }
+        throw new StubNotFoundException(stubClassName
+                    + " doesn't inherits from RemoteStub.");
+    }
+
+    /**
+     * Instantiates and returns a stub either starting from a class generated by
+     * <code>rmic</code>, or creating a dynamic proxy class for the remote
+     * object.
+     * 
+     * @param ref
+     *            The remote reference for the stub
+     * @param obj
+     *            The object, that the stub will represent
+     * @return a stub for <code>obj</code>
+     * @throws StubNotFoundException
+     *             If a dynamic proxy can not be instantiated for that object.
+     */
+    public final Remote createStub(RemoteRef ref, Remote obj)
+            throws StubNotFoundException {
+        Remote stub = null;
+        boolean ignoreStubClasses = false;
+        String propertyValue;
+
+        // Verify if the old non-dynamic stubs should be ignored
+        propertyValue = PropertiesReader
+                .readString("java.rmi.server.ignoreStubClasses");
+        if (propertyValue != null) {
+            ignoreStubClasses = propertyValue.equalsIgnoreCase("true");
+        }
+
+        if (!ignoreStubClasses) {
+            try {
+                stub = createRegularStub(ref, obj);
+                return stub;
+            } catch (StubNotFoundException e) {
+                // An error has been produced during regular stub instantiation.
+                // ignore it and try now a dynamic proxy.
+            }
+        }
+
+        Set<Class> remoteSet = (RemoteUtils.getRemoteInterfaces(obj.getClass()));
+        Class[] remoteInterfaces = new Class[remoteSet.size()];
+        remoteSet.toArray(remoteInterfaces);
+
+        try {
+            stub = (Remote) Proxy.newProxyInstance(obj.getClass()
+                    .getClassLoader(), remoteInterfaces,
+                    new RemoteObjectInvocationHandler(ref));
+        } catch (IllegalArgumentException ex) {
+            throw new StubNotFoundException(
+                    "Couldn't create dynamic proxy for " + obj, ex);
+        }
+        return stub;
+    }
+
+    /**
+     * Finds the "root class" according to RMI Specification, wich name will be
+     * used for constructing the name of the stub class that corresponds to the
+     * <code>inspect</code> class.
+     * 
+     * @param inspect
+     *            the class of the object
+     * @return the root class of the object
+     * @throws StubNotFoundException
+     *             If the class does not implement any remote interfaces
+     */
+    // Returns the apropriate root class for a stub of the class received as
+    // parameter.
+    private final Class findStubBaseClass(Class inspect)
+            throws StubNotFoundException {
+        Set<Class> remoteInterfacesList = RemoteUtils
+                .getRemoteInterfaces(inspect);
+
+        do {
+            // Check if the class implements any Remote Interface directly
+            Class[] directInterfacesList = inspect.getInterfaces();
+            for (Class directInterface : directInterfacesList) {
+                if (remoteInterfacesList.contains(directInterface)) {
+                    return inspect;
+                }
+            }
+            // The interfaces implemented directly aren't remote interfaces...
+            // check now the interfaces implemented directly by the superclass.
+            inspect = inspect.getSuperclass();
+        } while (inspect != null);
+
+        throw new StubNotFoundException(
+                "The remote object doesn't implement any Remote interfaces.");
+    }
+}