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:52 UTC

[08/10] git commit: This closes #90

This closes #90

Conflicts:
	core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java - createEntity had been changed to pull in all interfaces, while class-loading logic changed here to pull in classloaders of all supertypes; have merged


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

Branch: refs/heads/master
Commit: 658039294e567bbe4a804699faa419ca0a3ad18e
Parents: 65afbdb c0a2fee
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Aug 5 00:55:11 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Aug 5 00:55:11 2014 -0400

----------------------------------------------------------------------
 .../entity/proxying/InternalEntityFactory.java  |  36 ++-
 .../brooklyn/management/ha/OsgiManager.java     |  23 +-
 .../main/java/brooklyn/util/ResourceUtils.java  |  37 ++--
 .../src/main/java/brooklyn/util/osgi/Osgis.java | 221 ++++++++++++++++---
 .../management/osgi/OsgiStandaloneTest.java     |  70 +++++-
 pom.xml                                         |   9 +
 .../util/javalang/AggregateClassLoader.java     |   6 +-
 .../brooklyn/util/maven/MavenRetriever.java     |   2 +-
 .../src/main/java/brooklyn/util/os/Os.java      |   9 +-
 9 files changed, 343 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65803929/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
index 4d53fbb,c4daa02..b5d7c0a
--- a/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalEntityFactory.java
@@@ -19,9 -19,9 +19,10 @@@
  package brooklyn.entity.proxying;
  
  import static com.google.common.base.Preconditions.checkNotNull;
 +import static com.google.common.base.Preconditions.checkState;
  
  import java.lang.reflect.InvocationTargetException;
+ import java.util.Collection;
  import java.util.Map;
  import java.util.Set;
  
@@@ -89,38 -138,51 +90,65 @@@ public class InternalEntityFactory exte
          } else {
              log.warn("EntitySpec declared in terms of concrete type "+spec.getType()+"; should be supplied in terms of interface");
          }
 -        builder.addAll(spec.getAdditionalInterfaces());
 -        Set<Class<?>> interfaces = builder.build();
 +        interfaces.addAll(spec.getAdditionalInterfaces());
 +        
 +        return createEntityProxy(interfaces, entity);
 +    }
 +
 +    @SuppressWarnings("unchecked")
 +    public <T extends Entity> T createEntityProxy(Iterable<Class<?>> interfaces, T entity) {
 +        // TODO Don't want the proxy to have to implement EntityLocal, but required by how 
 +        // AbstractEntity.parent is used (e.g. parent.getAllConfig)
 +        Set<Class<?>> allInterfaces = MutableSet.<Class<?>>builder()
 +                .add(EntityProxy.class, Entity.class, EntityLocal.class, EntityInternal.class)
 +                .addAll(interfaces)
 +                .build();
  
 -        // When using the entity's classloader, we get errors such as:
 +        // TODO OSGi strangeness! The classloader obtained from the type should be enough.
 +        // If an OSGi class loader, it should delegate to find things like Entity.class etc.
 +        // However, we get errors such as:
          //    NoClassDefFoundError: brooklyn.event.AttributeSensor not found by io.brooklyn.brooklyn-test-osgi-entities
          // Building our own aggregating class loader gets around this.
 +        // But we really should not have to do this! What are the consequences?
+         //
+         // The reason for the error is that the proxy tries to load all classes
+         // 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).
+         Collection<ClassLoader> loaders = Sets.newLinkedHashSet();
+         addClassLoaders(entity.getClass(), loaders);
 -        for(Class<?> iface : interfaces) {
++        for (Class<?> iface : allInterfaces) {
+             loaders.add(iface.getClassLoader());
+         }
+ 
          AggregateClassLoader aggregateClassLoader =  AggregateClassLoader.newInstanceWithNoLoaders();
-         aggregateClassLoader.addFirst(entity.getClass().getClassLoader());
-         for(Class<?> iface : allInterfaces) {
-             aggregateClassLoader.addLast(iface.getClassLoader());
+         for (ClassLoader cl : loaders) {
+             aggregateClassLoader.addLast(cl);
          }
  
          return (T) java.lang.reflect.Proxy.newProxyInstance(
                  aggregateClassLoader,
 -                interfaces.toArray(new Class[interfaces.size()]),
 +                allInterfaces.toArray(new Class[allInterfaces.size()]),
                  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.)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65803929/core/src/main/java/brooklyn/util/ResourceUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/65803929/pom.xml
----------------------------------------------------------------------