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/11/19 18:48:03 UTC

[08/13] incubator-brooklyn git commit: make BrooklynClassLoadingContext instances serializable

make BrooklynClassLoadingContext instances serializable

clean up how we set and manage those; fix bug where serialized state of `/Users/alex/Data/cloudsoft/dev/gits/brooklyn/docs/use/guide/defining-applications/example_yaml/appserver-clustered-w-db.yaml` was 8 MB !  also rename methods and internal fields to make things more standardized, and dampen down some logging


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

Branch: refs/heads/master
Commit: 07048fc55e5e39aae01a707d0e447a8f8e42ba20
Parents: 9c6b602
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Nov 18 17:06:04 2014 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Nov 19 13:53:07 2014 +0000

----------------------------------------------------------------------
 .../java/brooklyn/catalog/BrooklynCatalog.java  |  3 +-
 .../catalog/internal/BasicBrooklynCatalog.java  | 16 ++++----
 .../brooklyn/catalog/internal/CatalogUtils.java | 39 ++++++++++++++++++--
 .../entity/basic/ServiceStateLogic.java         |  8 ++--
 .../JavaBrooklynClassLoadingContext.java        | 20 +++++++---
 .../OsgiBrooklynClassLoadingContext.java        | 36 ++++++++++++------
 .../management/entitlement/Entitlements.java    | 25 +++++++------
 .../internal/AbstractManagementContext.java     |  4 +-
 .../internal/EntityManagementUtils.java         |  5 +--
 .../main/java/brooklyn/util/ResourceUtils.java  | 34 +++++++++--------
 .../entity/webapp/jboss/JBoss7ServerImpl.java   |  2 -
 .../BrooklynComponentTemplateResolver.java      | 32 +++++++++++++---
 .../spi/creation/BrooklynEntityMatcher.java     |  4 +-
 .../BrooklynYamlTypeInstantiatorTest.java       |  2 +-
 14 files changed, 156 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java b/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java
index cac3038..cd50910 100644
--- a/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java
+++ b/api/src/main/java/brooklyn/catalog/BrooklynCatalog.java
@@ -28,7 +28,8 @@ public interface BrooklynCatalog {
 
     /** @return The item with the given {@link brooklyn.catalog.CatalogItem#getSymbolicName()
      * symbolicName}, or null if not found.
-     * @deprecated since 0.7.0 use {@link #getCatalogItem(String, String)} */
+     * @deprecated since 0.7.0 use {@link #getCatalogItem(String, String)};
+     * or see also CatalogUtils getCatalogItemOptionalVersion */
     @Deprecated
     CatalogItem<?,?> getCatalogItem(String symbolicName);
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index 9db1940..3a46f8b 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -203,8 +203,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
 
     @Override
     @Deprecated
-    public CatalogItem<?,?> getCatalogItem(String id) {
-        return getCatalogItem(id, DEFAULT_VERSION);
+    public CatalogItem<?,?> getCatalogItem(String symbolicName) {
+        return getCatalogItem(symbolicName, DEFAULT_VERSION);
     }
     
     @Override
@@ -225,17 +225,17 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
     }
 
     @Override
-    public void deleteCatalogItem(String id, String version) {
-        log.debug("Deleting manual catalog item from "+mgmt+": "+id + ":" + version);
-        checkNotNull(id, "id");
+    public void deleteCatalogItem(String symbolicName, String version) {
+        log.debug("Deleting manual catalog item from "+mgmt+": "+symbolicName + ":" + version);
+        checkNotNull(symbolicName, "id");
         checkNotNull(version, "version");
         if (DEFAULT_VERSION.equals(version)) {
             throw new IllegalStateException("Deleting items with unspecified version (argument DEFAULT_VERSION) not supported.");
         }
-        CatalogItem<?, ?> item = getCatalogItem(id, version);
+        CatalogItem<?, ?> item = getCatalogItem(symbolicName, version);
         CatalogItemDtoAbstract<?,?> itemDto = getAbstractCatalogItem(item);
         if (itemDto == null) {
-            throw new NoSuchElementException("No catalog item found with id "+id);
+            throw new NoSuchElementException("No catalog item found with id "+symbolicName);
         }
         if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
         manualAdditionsCatalog.deleteEntry(itemDto);
@@ -533,7 +533,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         CatalogUtils.installLibraries(mgmt, libraries);
 
         String versionedId = CatalogUtils.getVersionedId(catalogSymbolicName, catalogVersion);
-        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, versionedId, libraries, getRootClassLoader());
+        BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(mgmt, versionedId, libraries);
         AbstractBrooklynObjectSpec<?, ?> spec = createSpec(plan, loader);
 
         CatalogItemDtoAbstract<?, ?> dto = createItemBuilder(spec, catalogSymbolicName, catalogVersion)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogUtils.java b/core/src/main/java/brooklyn/catalog/internal/CatalogUtils.java
index cb98dfe..ed4d06d 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogUtils.java
@@ -33,6 +33,7 @@ import brooklyn.catalog.CatalogItem.CatalogBundle;
 import brooklyn.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
 import brooklyn.config.BrooklynLogging;
 import brooklyn.entity.Entity;
+import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.classloading.BrooklynClassLoadingContext;
@@ -42,6 +43,7 @@ import brooklyn.management.classloading.OsgiBrooklynClassLoadingContext;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.guava.Maybe;
+import brooklyn.util.text.Strings;
 import brooklyn.util.time.Time;
 
 import com.google.common.annotations.Beta;
@@ -59,10 +61,41 @@ public class CatalogUtils {
         if (item.getLibraries() == null) {
             log.debug("CatalogItemDtoAbstract.getLibraries() is null.", new Exception("Trace for null CatalogItemDtoAbstract.getLibraries()"));
         }
-        return newClassLoadingContext(mgmt, item.getId(), item.getLibraries(), mgmt.getCatalog().getRootClassLoader());
+        return newClassLoadingContext(mgmt, item.getId(), item.getLibraries());
+    }
+    
+    public static BrooklynClassLoadingContext getClassLoadingContext(Entity entity) {
+        ManagementContext mgmt = ((EntityInternal)entity).getManagementContext();
+        String catId = entity.getCatalogItemId();
+        if (Strings.isBlank(catId)) return JavaBrooklynClassLoadingContext.create(mgmt);
+        CatalogItem<?, ?> cat = getCatalogItemOptionalVersion(mgmt, catId);
+        if (cat==null) {
+            log.warn("Cannot load "+catId+" to get classloader for "+entity+"; will try with standard loader, but might fail subsequently");
+            return JavaBrooklynClassLoadingContext.create(mgmt);
+        }
+        return newClassLoadingContext(mgmt, cat);
     }
 
-    public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable ManagementContext mgmt, String catalogItemId, Collection<CatalogBundle> libraries, ClassLoader classLoader) {
+    public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable ManagementContext mgmt, String catalogItemId, Collection<CatalogBundle> libraries) {
+        BrooklynClassLoadingContextSequential result = new BrooklynClassLoadingContextSequential(mgmt);
+
+        if (libraries!=null && !libraries.isEmpty()) {
+            result.add(new OsgiBrooklynClassLoadingContext(mgmt, catalogItemId, libraries));
+        }
+
+        BrooklynClassLoadingContext loader = BrooklynLoaderTracker.getLoader();
+        if (loader != null) {
+            result.add(loader);
+        }
+
+        result.addSecondary(JavaBrooklynClassLoadingContext.create(mgmt));
+        return result;
+    }
+
+    /**
+     * @deprecated since 0.7.0 only for legacy catalog items which provide a non-osgi loader; see {@link #newDefault(ManagementContext)}
+     */ @Deprecated
+    public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable ManagementContext mgmt, String catalogItemId, Collection<CatalogBundle> libraries, ClassLoader customClassLoader) {
         BrooklynClassLoadingContextSequential result = new BrooklynClassLoadingContextSequential(mgmt);
 
         if (libraries!=null && !libraries.isEmpty()) {
@@ -74,7 +107,7 @@ public class CatalogUtils {
             result.add(loader);
         }
 
-        result.addSecondary(JavaBrooklynClassLoadingContext.create(mgmt, classLoader));
+        result.addSecondary(JavaBrooklynClassLoadingContext.create(mgmt, customClassLoader));
         return result;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
index 898de8f..3534101 100644
--- a/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
+++ b/core/src/main/java/brooklyn/entity/basic/ServiceStateLogic.java
@@ -279,8 +279,9 @@ public class ServiceStateLogic {
                 return Lifecycle.RUNNING;
             } else {
                 if (!Lifecycle.ON_FIRE.equals(entity.getAttribute(SERVICE_STATE_ACTUAL))) {
-                    log.warn("Setting "+entity+" "+Lifecycle.ON_FIRE+" due to problems when expected running, up="+serviceUp+", "+
-                        (problems==null || problems.isEmpty() ? "not-up-indicators: "+entity.getAttribute(SERVICE_NOT_UP_INDICATORS) : "problems: "+problems));
+                    BrooklynLogging.log(log, BrooklynLogging.levelDependingIfReadOnly(entity, LoggingLevel.WARN, LoggingLevel.TRACE, LoggingLevel.DEBUG),
+                        "Setting "+entity+" "+Lifecycle.ON_FIRE+" due to problems when expected running, up="+serviceUp+", "+
+                            (problems==null || problems.isEmpty() ? "not-up-indicators: "+entity.getAttribute(SERVICE_NOT_UP_INDICATORS) : "problems: "+problems));
                 }
                 return Lifecycle.ON_FIRE;
             }
@@ -296,7 +297,8 @@ public class ServiceStateLogic {
                 if (Boolean.FALSE.equals(up)) {
                     return Lifecycle.STOPPED;
                 } else {
-                    log.warn("Setting "+entity+" "+Lifecycle.ON_FIRE+" due to problems when expected "+stateTransition+" / up="+up+": "+problems);
+                    BrooklynLogging.log(log, BrooklynLogging.levelDependingIfReadOnly(entity, LoggingLevel.WARN, LoggingLevel.TRACE, LoggingLevel.DEBUG),
+                        "Setting "+entity+" "+Lifecycle.ON_FIRE+" due to problems when expected "+stateTransition+" / up="+up+": "+problems);
                     return Lifecycle.ON_FIRE;
                 }
             } else {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/management/classloading/JavaBrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/classloading/JavaBrooklynClassLoadingContext.java b/core/src/main/java/brooklyn/management/classloading/JavaBrooklynClassLoadingContext.java
index f4e8a8a..29e07af 100644
--- a/core/src/main/java/brooklyn/management/classloading/JavaBrooklynClassLoadingContext.java
+++ b/core/src/main/java/brooklyn/management/classloading/JavaBrooklynClassLoadingContext.java
@@ -31,20 +31,32 @@ import com.google.common.base.Objects;
 
 public class JavaBrooklynClassLoadingContext extends AbstractBrooklynClassLoadingContext {
 
-    private final ClassLoader loader;
+    // on deserialization this loader is replaced with the catalog's root loader;
+    // may cause problems for non-osgi catalog items, but that's a reasonable trade-off,
+    // should this be serialized (e.g. in SpecialFlagsTransformer) in such a case!
+    private final transient ClassLoader loader;
 
+    /**
+     * @deprecated since 0.7.0 only for legacy catalog items which provide a non-osgi loader; see {@link #newDefault(ManagementContext)}
+     */ @Deprecated
     public static JavaBrooklynClassLoadingContext create(ClassLoader loader) {
         return new JavaBrooklynClassLoadingContext(null, checkNotNull(loader, "loader"));
     }
     
     /**
      * At least one of mgmt or loader must not be null.
-     */
+     * @deprecated since 0.7.0 only for legacy catalog items which provide a non-osgi loader; see {@link #newDefault(ManagementContext)}
+     */ @Deprecated
     public static JavaBrooklynClassLoadingContext create(ManagementContext mgmt, ClassLoader loader) {
         checkState(mgmt != null || loader != null, "mgmt and loader must not both be null");
         return new JavaBrooklynClassLoadingContext(mgmt, loader);
     }
     
+    public static JavaBrooklynClassLoadingContext create(ManagementContext mgmt) {
+        return new JavaBrooklynClassLoadingContext(checkNotNull(mgmt, "mgmt"), null);
+    }
+
+    @Deprecated /** @deprecated since 0.7.0 use {@link #create(ManagementContext)} */
     public static JavaBrooklynClassLoadingContext newDefault(ManagementContext mgmt) {
         return new JavaBrooklynClassLoadingContext(checkNotNull(mgmt, "mgmt"), null);
     }
@@ -55,10 +67,6 @@ public class JavaBrooklynClassLoadingContext extends AbstractBrooklynClassLoadin
         this.loader = loader;
     }
     
-    // TODO Ugly workaround for rebind, where the classLoader cannot be serialized/deserialized.
-    // If we're supplying just mgmt (i.e. via {@link #newDefault(ManagementContext)} then can retrieve
-    // class loader from that.
-    // Will not work if trying to serialize/deserialize an instance created with a specific ClassLoader.
     private ClassLoader getClassLoader() {
         if (loader != null) return loader;
         if (mgmt!=null) return mgmt.getCatalog().getRootClassLoader();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/management/classloading/OsgiBrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/classloading/OsgiBrooklynClassLoadingContext.java b/core/src/main/java/brooklyn/management/classloading/OsgiBrooklynClassLoadingContext.java
index bb763d5..3283fb3 100644
--- a/core/src/main/java/brooklyn/management/classloading/OsgiBrooklynClassLoadingContext.java
+++ b/core/src/main/java/brooklyn/management/classloading/OsgiBrooklynClassLoadingContext.java
@@ -21,7 +21,9 @@ package brooklyn.management.classloading;
 import java.net.URL;
 import java.util.Collection;
 
+import brooklyn.catalog.CatalogItem;
 import brooklyn.catalog.CatalogItem.CatalogBundle;
+import brooklyn.catalog.internal.CatalogUtils;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.management.internal.ManagementContextInternal;
@@ -31,23 +33,35 @@ import com.google.common.base.Objects;
 
 public class OsgiBrooklynClassLoadingContext extends AbstractBrooklynClassLoadingContext {
 
-    private final Collection<CatalogBundle> bundles;
     private final String catalogItemId;
+    private boolean hasBundles = false;
+    private transient Collection<CatalogBundle> _bundles;
 
     public OsgiBrooklynClassLoadingContext(ManagementContext mgmt, String catalogItemId, Collection<CatalogBundle> bundles) {
         super(mgmt);
-        this.bundles = bundles;
+        this._bundles = bundles;
+        this.hasBundles = bundles!=null && !bundles.isEmpty();
         this.catalogItemId = catalogItemId;
     }
 
+    public Collection<CatalogBundle> getBundles() {
+        if (_bundles!=null || !hasBundles) return _bundles;
+        CatalogItem<?, ?> cat = CatalogUtils.getCatalogItemOptionalVersion(mgmt, catalogItemId);
+        if (cat==null) {
+            throw new IllegalStateException("Catalog item not found for "+catalogItemId+"; cannot create loading context");
+        }
+        _bundles = cat.getLibraries();
+        return _bundles;
+    }
+    
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Maybe<Class<?>> tryLoadClass(String className) {
         Maybe<Class<Object>> clazz = null;
         Maybe<OsgiManager> osgi = null;
         if (mgmt!=null) {
             osgi = ((ManagementContextInternal)mgmt).getOsgiManager();
-            if (osgi.isPresent() && bundles!=null && !bundles.isEmpty()) {
-                clazz = osgi.get().tryResolveClass(className, bundles);
+            if (osgi.isPresent() && getBundles()!=null && !getBundles().isEmpty()) {
+                clazz = osgi.get().tryResolveClass(className, getBundles());
                 if (clazz.isPresent())
                     return (Maybe)clazz;
             }
@@ -60,19 +74,19 @@ public class OsgiBrooklynClassLoadingContext extends AbstractBrooklynClassLoadin
         // else determine best message
         if (mgmt==null) return Maybe.absent("No mgmt context available for loading "+className);
         if (osgi!=null && osgi.isAbsent()) return Maybe.absent("OSGi not available on mgmt for loading "+className);
-        if (bundles==null || bundles.isEmpty())
+        if (!hasBundles)
             return Maybe.absent("No bundles available for loading "+className);
-        return Maybe.absent("Inconsistent state ("+mgmt+"/"+osgi+"/"+bundles+" loading "+className);
+        return Maybe.absent("Inconsistent state ("+mgmt+"/"+osgi+"/"+getBundles()+" loading "+className);
     }
 
     @Override
     public String toString() {
-        return "OSGi:"+bundles;
+        return "OSGi:"+catalogItemId+"["+getBundles()+"]";
     }
     
     @Override
     public int hashCode() {
-        return Objects.hashCode(super.hashCode(), bundles, catalogItemId);
+        return Objects.hashCode(super.hashCode(), getBundles(), catalogItemId);
     }
     
     @Override
@@ -82,7 +96,7 @@ public class OsgiBrooklynClassLoadingContext extends AbstractBrooklynClassLoadin
 
         OsgiBrooklynClassLoadingContext other = (OsgiBrooklynClassLoadingContext)obj;
         if (!catalogItemId.equals(other.catalogItemId)) return false;
-        if (!Objects.equal(bundles, other.bundles)) return false;
+        if (!Objects.equal(getBundles(), other.getBundles())) return false;
         return true;
     }
 
@@ -90,8 +104,8 @@ public class OsgiBrooklynClassLoadingContext extends AbstractBrooklynClassLoadin
     public URL getResource(String name) {
         if (mgmt!=null) {
             Maybe<OsgiManager> osgi = ((ManagementContextInternal)mgmt).getOsgiManager();
-            if (osgi.isPresent() && bundles!=null && !bundles.isEmpty()) {
-                return osgi.get().getResource(name, bundles);
+            if (osgi.isPresent() && hasBundles) {
+                return osgi.get().getResource(name, getBundles());
             }
         }
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
index 85dc6fb..e8652a4 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -21,26 +21,27 @@ package brooklyn.management.entitlement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.reflect.TypeToken;
-
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
+import brooklyn.management.ManagementContext;
 import brooklyn.management.Task;
-import brooklyn.util.ResourceUtils;
+import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.javalang.Reflections;
 import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.reflect.TypeToken;
+
 /** @since 0.7.0 */
 @Beta
 public class Entitlements {
@@ -288,19 +289,19 @@ public class Entitlements {
         + "or supply the name of an "+EntitlementManager.class+" class to instantiate, taking a 1-arg BrooklynProperties constructor or a 0-arg constructor",
         "root");
     
-    public static EntitlementManager newManager(ResourceUtils loader, BrooklynProperties brooklynProperties) {
-        EntitlementManager result = newGlobalManager(loader, brooklynProperties);
+    public static EntitlementManager newManager(ManagementContext mgmt, BrooklynProperties brooklynProperties) {
+        EntitlementManager result = newGlobalManager(mgmt, brooklynProperties);
         // TODO read per user settings from brooklyn.properties, if set there ?
         return result;
     }
-    private static EntitlementManager newGlobalManager(ResourceUtils loader, BrooklynProperties brooklynProperties) {
+    private static EntitlementManager newGlobalManager(ManagementContext mgmt, BrooklynProperties brooklynProperties) {
         String type = brooklynProperties.getConfig(GLOBAL_ENTITLEMENT_MANAGER);
         if ("root".equalsIgnoreCase(type)) return new PerUserEntitlementManagerWithDefault(root());
         if ("readonly".equalsIgnoreCase(type)) return new PerUserEntitlementManagerWithDefault(readOnly());
         if ("minimal".equalsIgnoreCase(type)) return new PerUserEntitlementManagerWithDefault(minimal());
         if (Strings.isNonBlank(type)) {
             try {
-                Class<?> clazz = loader.getLoader().loadClass(type);
+                Class<?> clazz = ((ManagementContextInternal)mgmt).getBaseClassLoader().loadClass(type);
                 Optional<?> result = Reflections.invokeConstructorWithArgs(clazz, brooklynProperties);
                 if (result.isPresent()) return (EntitlementManager) result.get();
                 return (EntitlementManager) clazz.newInstance();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index e35b708..52714eb 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -125,7 +125,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
                 if (input instanceof EntityManagementSupport)
                     return apply(((EntityManagementSupport)input).getManagementContext());
                 if (input instanceof ManagementContext)
-                    return JavaBrooklynClassLoadingContext.newDefault((ManagementContext) input);
+                    return JavaBrooklynClassLoadingContext.create((ManagementContext) input);
                 return null;
             }
         });
@@ -172,7 +172,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
         this.rebindManager = new RebindManagerImpl(this); // TODO leaking "this" reference; yuck
         this.highAvailabilityManager = new HighAvailabilityManagerImpl(this); // TODO leaking "this" reference; yuck
         
-        this.entitlementManager = Entitlements.newManager(ResourceUtils.create(getBaseClassLoader()), brooklynProperties);
+        this.entitlementManager = Entitlements.newManager(this, brooklynProperties);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
index 089fd33..6734654 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementUtils.java
@@ -25,7 +25,6 @@ import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 
 import java.io.StringReader;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Callable;
 
@@ -106,7 +105,7 @@ public class EntityManagementUtils {
         }
         Assembly assembly;
         if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
+            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
             
             EntitySpec<?> spec = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, true);
             Entity app = mgmt.getEntityManager().createEntity(spec);
@@ -183,7 +182,7 @@ public class EntityManagementUtils {
             throw Exceptions.propagate(e);
         }
         if (instantiator instanceof AssemblyTemplateSpecInstantiator) {
-            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
+            BrooklynClassLoadingContext loader = JavaBrooklynClassLoadingContext.create(mgmt);
             EntitySpec<?> specA = ((AssemblyTemplateSpecInstantiator) instantiator).createSpec(at, camp, loader, false);
 
             // see whether we can promote children

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/core/src/main/java/brooklyn/util/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/ResourceUtils.java b/core/src/main/java/brooklyn/util/ResourceUtils.java
index b40df0d..1112401 100644
--- a/core/src/main/java/brooklyn/util/ResourceUtils.java
+++ b/core/src/main/java/brooklyn/util/ResourceUtils.java
@@ -49,6 +49,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import brooklyn.catalog.internal.CatalogUtils;
 import brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.classloading.BrooklynClassLoadingContext;
@@ -146,7 +147,7 @@ public class ResourceUtils {
     }
 
     public ResourceUtils(ClassLoader loader, Object contextObject, String contextMessage) {
-        this(JavaBrooklynClassLoadingContext.create(loader), contextObject, contextMessage);
+        this(getClassLoadingContextInternal(loader, contextObject), contextObject, contextMessage);
     }
     
     public ResourceUtils(BrooklynClassLoadingContext loader, Object contextObject, String contextMessage) {
@@ -156,7 +157,7 @@ public class ResourceUtils {
     }
 
     public ResourceUtils(Object contextObject, String contextMessage) {
-        this(contextObject==null ? null : getClassLoadingContextForObject(contextObject), contextObject, contextMessage);
+        this(contextObject==null ? null : getClassLoadingContextInternal(null, contextObject), contextObject, contextMessage);
     }
 
     public ResourceUtils(Object contextObject) {
@@ -168,7 +169,9 @@ public class ResourceUtils {
         classLoaderProviders.add(provider);
     }
     
-    public static BrooklynClassLoadingContext getClassLoadingContextForObject(Object contextObject) {
+    // TODO rework this class so it accepts but does not require a BCLC ?
+    @SuppressWarnings("deprecation")
+    protected static BrooklynClassLoadingContext getClassLoadingContextInternal(ClassLoader loader, Object contextObject) {
         if (contextObject instanceof BrooklynClassLoadingContext)
             return (BrooklynClassLoadingContext) contextObject;
         
@@ -176,22 +179,23 @@ public class ResourceUtils {
             BrooklynClassLoadingContext result = provider.apply(contextObject);
             if (result!=null) return result;
         }
-        
-        ClassLoader cl = contextObject instanceof Class ? ((Class<?>)contextObject).getClassLoader() : 
+
+        BrooklynClassLoadingContext bl = BrooklynLoaderTracker.getLoader();
+        ManagementContext mgmt = (bl!=null ? bl.getManagementContext() : null);
+
+        ClassLoader cl = loader;
+        if (cl==null) cl = contextObject instanceof Class ? ((Class<?>)contextObject).getClassLoader() : 
             contextObject instanceof ClassLoader ? ((ClassLoader)contextObject) : 
                 contextObject.getClass().getClassLoader();
-        return getClassLoadingContextForClassLoader(cl);
+            
+        return JavaBrooklynClassLoadingContext.create(mgmt, cl);
     }
     
-    protected static BrooklynClassLoadingContext getClassLoadingContextForClassLoader(ClassLoader loader) {
-        ManagementContext mgmt = null;
-        BrooklynClassLoadingContext bl = BrooklynLoaderTracker.getLoader();
-        if (bl!=null) mgmt = bl.getManagementContext();
-        return JavaBrooklynClassLoadingContext.create(mgmt, loader);
-    }
-    
-    public BrooklynClassLoadingContext getLoader() {
-        return (loader!=null ? loader : getClassLoadingContextForClassLoader(getClass().getClassLoader()));
+    /** This should not be exposed as it risks it leaking into places where it would be serialized.
+     * Better for callers use {@link CatalogUtils#getClassLoadingContext(brooklyn.entity.Entity)} or similar. }.
+     */
+    private BrooklynClassLoadingContext getLoader() {
+        return (loader!=null ? loader : getClassLoadingContextInternal(null, contextObject!=null ? contextObject : this));
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index e246db3..67fe955 100644
--- a/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -27,9 +27,7 @@ import brooklyn.config.render.RendererHints;
 import brooklyn.enricher.Enrichers;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.webapp.HttpsSslConfig;
 import brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
-import brooklyn.entity.webapp.WebAppServiceMethods;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index e641b50..c1a8e4f 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -36,7 +36,6 @@ import javax.annotation.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.catalog.BrooklynCatalog;
 import brooklyn.catalog.CatalogItem;
 import brooklyn.catalog.internal.CatalogUtils;
 import brooklyn.config.ConfigKey;
@@ -44,6 +43,7 @@ import brooklyn.entity.Application;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.BrooklynTags;
+import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.VanillaSoftwareProcess;
@@ -56,6 +56,7 @@ import brooklyn.management.ManagementContext;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.classloading.BrooklynClassLoadingContext;
 import brooklyn.management.classloading.BrooklynClassLoadingContextSequential;
+import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableSet;
@@ -65,6 +66,7 @@ import brooklyn.util.flags.FlagUtils;
 import brooklyn.util.flags.FlagUtils.FlagConfigKeyAndValueRecord;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.javalang.Reflections;
+import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 
 import com.google.common.base.Function;
@@ -191,7 +193,7 @@ public class BrooklynComponentTemplateResolver {
     public CatalogItem<Entity,EntitySpec<?>> getCatalogItem() {
         String type = getBrooklynType();
         if (type != null) {
-            return CatalogUtils.getCatalogItemOptionalVersion(loader.getManagementContext(), Entity.class,  type);
+            return CatalogUtils.getCatalogItemOptionalVersion(mgmt, Entity.class,  type);
         } else {
             return null;
         }
@@ -385,10 +387,20 @@ public class BrooklynComponentTemplateResolver {
     }
 
     protected static class SpecialFlagsTransformer implements Function<Object, Object> {
-        // TODO this may be large when serialized as it includes the context search bundles
-        final BrooklynClassLoadingContext loader;
+        protected final ManagementContext mgmt;
+        /* TODO find a way to make do without loader here?
+         * it is not very nice having to serialize it; but serialization of BLCL is now relatively clean.
+         * 
+         * it is only used to instantiate classes, and now most things should be registered with catalog;
+         * the notable exception is when one entity in a bundle is creating another in the same bundle,
+         * it wants to use his bundle CLC to do that.  but we can set up some unique reference to the entity 
+         * which can be used to find it from mgmt, rather than pass the loader.
+         */
+        private BrooklynClassLoadingContext loader = null;
+        
         public SpecialFlagsTransformer(BrooklynClassLoadingContext loader) {
             this.loader = loader;
+            mgmt = loader.getManagementContext();
         }
         public Object apply(Object input) {
             if (input instanceof Map)
@@ -411,6 +423,16 @@ public class BrooklynComponentTemplateResolver {
             return Iterables.transform(flag, this);
         }
         
+        protected BrooklynClassLoadingContext getLoader() {
+            if (loader!=null) return loader;
+            // TODO currently loader will non-null unless someone has messed with the rebind files,
+            // but we'd like to get rid of it; ideally we'd have a reference to the entity.
+            // for now, this is a slightly naff way to do it, if we have to set loader=null as a workaround
+            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+            if (entity!=null) return CatalogUtils.getClassLoadingContext(entity);
+            return JavaBrooklynClassLoadingContext.create(mgmt);
+        }
+        
         /**
          * Makes additional transformations to the given flag with the extra knowledge of the flag's management context.
          * @return The modified flag, or the flag unchanged.
@@ -423,7 +445,7 @@ public class BrooklynComponentTemplateResolver {
                 @SuppressWarnings("unchecked")
                 Map<String, Object> resolvedConfig = (Map<String, Object>)transformSpecialFlags(specConfig.getSpecConfiguration());
                 specConfig.setSpecConfiguration(resolvedConfig);
-                return Factory.newInstance(loader, specConfig.getSpecConfiguration()).resolveSpec();
+                return Factory.newInstance(getLoader(), specConfig.getSpecConfiguration()).resolveSpec();
             }
             if (flag instanceof ManagementContextInjectable) {
                 if (log.isDebugEnabled()) { log.debug("Injecting Brooklyn management context info object: {}", flag); }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
index db64c0c..aae2b19 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynEntityMatcher.java
@@ -71,7 +71,7 @@ public class BrooklynEntityMatcher implements PdpMatcher {
 
             String serviceType = service.getServiceType();
             BrooklynClassLoadingContext loader = BasicBrooklynCatalog.BrooklynLoaderTracker.getLoader();
-            if (loader == null) loader = JavaBrooklynClassLoadingContext.newDefault(mgmt);
+            if (loader == null) loader = JavaBrooklynClassLoadingContext.create(mgmt);
             if (BrooklynComponentTemplateResolver.Factory.supportsType(loader, serviceType))
                 return serviceType;
 
@@ -212,7 +212,7 @@ public class BrooklynEntityMatcher implements PdpMatcher {
         try {
             // TODO don't use the mgmt loader, but instead use something like catalog.createSpec
             // currently we get warnings and are unable to retrieve flags for items which come from catalog 
-            Class<? extends Entity> type = BrooklynComponentTemplateResolver.Factory.newInstance(JavaBrooklynClassLoadingContext.newDefault(mgmt), typeName).loadEntityClass();
+            Class<? extends Entity> type = BrooklynComponentTemplateResolver.Factory.newInstance(JavaBrooklynClassLoadingContext.create(mgmt), typeName).loadEntityClass();
             ConfigBag bag = ConfigBag.newInstance(attrs);
             List<FlagConfigKeyAndValueRecord> values = FlagUtils.findAllFlagsAndConfigKeys(null, type, bag);
             

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/07048fc5/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
index 3796c00..61fe084 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/BrooklynYamlTypeInstantiatorTest.java
@@ -36,7 +36,7 @@ import brooklyn.util.time.Duration;
 public class BrooklynYamlTypeInstantiatorTest extends AbstractYamlTest {
 
     protected BrooklynClassLoadingContext loader() {
-        return JavaBrooklynClassLoadingContext.newDefault(mgmt());
+        return JavaBrooklynClassLoadingContext.create(mgmt());
     }
     
     @Test