You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/08/05 07:24:49 UTC

[05/10] git commit: Use all classloaders from the type's hierarchy when creating a proxy.

Use all classloaders from the type's hierarchy when creating a proxy.

The proxy will need access to all extended classes and interfaces but they
might come from a different classloader than the entity's one.
It might be the case that entity's classloader doesn't know about all of the
extended types if there is an intermediate classloader in between.


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/c0a2feea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/c0a2feea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/c0a2feea

Branch: refs/heads/master
Commit: c0a2feea92ec24644d103e5534a104d5f82b892c
Parents: b2da61e
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 29 10:53:29 2014 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 29 11:54:51 2014 +0300

----------------------------------------------------------------------
 .../entity/proxying/InternalEntityFactory.java  | 30 ++++++++++++++++++--
 1 file changed, 27 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c0a2feea/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
index 2081780..c4daa02 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
@@ -21,6 +21,7 @@ package brooklyn.entity.proxying;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
@@ -51,6 +52,7 @@ import brooklyn.util.task.Tasks;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
 
 /**
  * Creates entities (and proxies) of required types, given the 
@@ -147,10 +149,15 @@ public class InternalEntityFactory {
         // referenced from the entity and its interfaces with the single passed loader
         // while a normal class loading would nest the class loaders (loading interfaces'
         // references with their own class loaders which in our case are different).
-        AggregateClassLoader aggregateClassLoader =  AggregateClassLoader.newInstanceWithNoLoaders();
-        aggregateClassLoader.addFirst(entity.getClass().getClassLoader());
+        Collection<ClassLoader> loaders = Sets.newLinkedHashSet();
+        addClassLoaders(entity.getClass(), loaders);
         for(Class<?> iface : interfaces) {
-            aggregateClassLoader.addLast(iface.getClassLoader());
+            loaders.add(iface.getClassLoader());
+        }
+
+        AggregateClassLoader aggregateClassLoader =  AggregateClassLoader.newInstanceWithNoLoaders();
+        for (ClassLoader cl : loaders) {
+            aggregateClassLoader.addLast(cl);
         }
 
         return (T) java.lang.reflect.Proxy.newProxyInstance(
@@ -159,6 +166,23 @@ public class InternalEntityFactory {
                 new EntityProxyImpl(entity));
     }
 
+    private void addClassLoaders(Class<?> type, Collection<ClassLoader> loaders) {
+        ClassLoader cl = type.getClassLoader();
+
+        //java.lang.Object.getClassLoader() = null
+        if (cl != null) {
+            loaders.add(cl);
+        }
+
+        Class<?> superType = type.getSuperclass();
+        if (superType != null) {
+            addClassLoaders(superType, loaders);
+        }
+        for (Class<?> iface : type.getInterfaces()) {
+            addClassLoaders(iface, loaders);
+        }
+    }
+
     public <T extends Entity> T createEntity(EntitySpec<T> spec) {
         /* Order is important here. Changed Jul 2014 when supporting children in spec.
          * (Previously was much simpler, and parent was set right after running initializers; and there were no children.)