You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ge...@apache.org on 2017/07/19 16:25:33 UTC

[03/39] brooklyn-server git commit: fix bundles set on scanning, and aborted work to scan osgi bundles

fix bundles set on scanning, and aborted work to scan osgi bundles

scanning for OSGi can be made to work in some cases if we have the jar,
but it won't work after rebind, or even in some cases if persisting (race deleting the JAR),
plus there are likely classloading issues;

note OSGi deliberately doesn't give us the JAR.

java scanning is discouraged by OSGi; it wants us to explicitly list things e.g. in the catalog.bom,
which is fine.


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

Branch: refs/heads/master
Commit: 2165778a354fa4221eec0e8ba03a96ef5bef92a3
Parents: d7975d1
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Jun 27 14:23:34 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Jun 27 14:28:49 2017 +0100

----------------------------------------------------------------------
 .../CatalogOsgiVersionMoreEntityRebindTest.java |  10 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |   2 -
 .../brooklyn/catalog/CatalogScanOsgiTest.java   | 119 +++++++++++++++++++
 .../camp/brooklyn/catalog/CatalogScanTest.java  |   2 +-
 .../catalog/SpecParameterParsingOsgiTest.java   |  31 +----
 .../brooklyn/test/lite/CampYamlLiteTest.java    |   6 +-
 .../catalog/internal/BasicBrooklynCatalog.java  | 109 ++++++++++++-----
 .../catalog/internal/CatalogClasspathDo.java    |   4 +-
 .../util/core/javalang/ReflectionScanner.java   |   3 +
 .../src/main/resources/catalog.bom              |   1 -
 .../entities/src/main/resources/catalog.bom     |   1 -
 .../src/main/resources/catalog.bom              |   1 -
 .../src/main/resources/catalog.bom              |   1 -
 .../src/main/resources/catalog.bom              |   1 -
 .../brooklyn-test-osgi-com-example-entities.jar | Bin 22139 -> 22099 bytes
 .../osgi/brooklyn-test-osgi-entities.jar        | Bin 22902 -> 22864 bytes
 .../brooklyn-test-osgi-more-entities_0.1.0.jar  | Bin 16003 -> 15967 bytes
 .../brooklyn-test-osgi-more-entities_0.2.0.jar  | Bin 16922 -> 16884 bytes
 ...-test-osgi-more-entities_evil-twin_0.2.0.jar | Bin 14098 -> 14061 bytes
 19 files changed, 222 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java
index 1d066f5..b881ec7 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java
@@ -386,5 +386,13 @@ public class CatalogOsgiVersionMoreEntityRebindTest extends AbstractYamlRebindTe
             Asserts.expectedFailureContainsIgnoreCase(e, "unable to load", BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
         }
     }
-    
+
+    @Test(groups="Broken")  // AH think not going to support this; see notes in BasicBrooklynCatalog.scanAnnotationsInBundle
+    // it's hard to get the JAR for scanning, and doesn't fit with the OSGi way
+    public void testRebindJavaScanningBundleInCatalog() throws Exception {
+        CatalogScanOsgiTest.installJavaScanningMoreEntitiesV2(mgmt(), this);
+        rebind();
+        RegisteredType item = mgmt().getTypeRegistry().get(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
+        Assert.assertNotNull(item, "Scanned item should have been available after rebind");
+    }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
index 0813d80..6fee53e 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
@@ -28,8 +28,6 @@ import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
 import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.api.typereg.ManagedBundle;
 import org.apache.brooklyn.api.typereg.RegisteredType;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
new file mode 100644
index 0000000..c8d5399
--- /dev/null
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.brooklyn.camp.brooklyn.catalog;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.zip.ZipEntry;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
+import org.apache.brooklyn.camp.brooklyn.test.lite.CampYamlLiteTest;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.test.support.TestResourceUnavailableException;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.ResourceUtils;
+import org.apache.brooklyn.util.core.osgi.BundleMaker;
+import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.osgi.OsgiTestResources;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.Strings;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Iterables;
+
+public class CatalogScanOsgiTest extends AbstractYamlTest {
+
+    @Override protected boolean disableOsgi() { return false; }
+    
+    @Test(groups="Broken")  // AH think not going to support this; see notes in BasicBrooklynCatalog.scanAnnotationsInBundle
+    public void testScanContainingBundle() throws Exception {
+        installJavaScanningMoreEntitiesV2(mgmt(), this);
+        
+        RegisteredType item = mgmt().getTypeRegistry().get(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
+        Assert.assertNotNull(item, "Scanned item should have been loaded but wasn't");
+        assertEquals(item.getVersion(), "0.2.0");
+        assertEquals(item.getDisplayName(), "More Entity v2");
+        assertEquals(item.getContainingBundle(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL+":"+"0.2.0");
+        assertEquals(Iterables.getOnlyElement(item.getLibraries()).getVersionedName().toString(), 
+            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL+":"+"0.2.0");
+    }
+
+    static void installJavaScanningMoreEntitiesV2(ManagementContext mgmt, Object context) throws FileNotFoundException {
+        // scanning bundle functionality added in 0.12.0, relatively new compared to non-osgi scanning
+        
+        TestResourceUnavailableException.throwIfResourceUnavailable(context.getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        TestResourceUnavailableException.throwIfResourceUnavailable(context.getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+        
+        CampYamlLiteTest.installWithoutCatalogBom(mgmt, OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        
+        BundleMaker bm = new BundleMaker(mgmt);
+        File f = Os.newTempFile(context.getClass(), "jar");
+        Streams.copy(ResourceUtils.create(context).getResourceFromUrl(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH), new FileOutputStream(f));
+        f = bm.copyRemoving(f, MutableSet.of("catalog.bom"));
+        f = bm.copyAdding(f, MutableMap.of(new ZipEntry("catalog.bom"),
+            new ByteArrayInputStream( Strings.lines(
+                "brooklyn.catalog:",
+                "  scanJavaAnnotations: true").getBytes() ) ));
+        
+        ((ManagementContextInternal)mgmt).getOsgiManager().get().install(new FileInputStream(f)).checkNoError();
+    }
+    
+    @Test
+    public void testScanLegacyListedLibraries() {
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+        TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+        addCatalogItems(bomForLegacySiblingLibraries());
+
+        RegisteredType hereItem = mgmt().getTypeRegistry().get("here-item");
+        assertEquals(hereItem.getVersion(), "2.0-test_java");
+        assertEquals(hereItem.getLibraries().size(), 3);
+        assertEquals(hereItem.getContainingBundle(), "test-items:2.0-test_java");
+        
+        RegisteredType item = mgmt().getTypeRegistry().get(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
+        // versions and libraries _are_ inherited in this legacy mode
+        assertEquals(item.getVersion(), "2.0-test_java");
+        assertEquals(item.getLibraries().size(), 3);
+        // and the containing bundle is recorded as the 
+        assertEquals(item.getContainingBundle(), "test-items"+":"+"2.0-test_java");
+    }
+
+    static String bomForLegacySiblingLibraries() {
+        return Strings.lines("brooklyn.catalog:",
+            "    bundle: test-items",
+            "    version: 2.0-test_java",
+            "    items:",
+            "    - scanJavaAnnotations: true",
+            "      item:",
+            "        id: here-item",
+            "        type: "+OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
+            "      libraries:",
+            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH,
+            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanTest.java
index ff7a027..9e11b10 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanTest.java
@@ -84,7 +84,7 @@ public class CatalogScanTest {
 
     private LocalManagementContext newManagementContext(BrooklynProperties props) {
         final LocalManagementContext localMgmt = LocalManagementContextForTests.builder(true)
-                .disableOsgi(disableOsgi())
+                .setOsgiEnablementAndReuse(disableOsgi(), true)
                 .useProperties(props)
                 .build();
         mgmts.add(localMgmt);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterParsingOsgiTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterParsingOsgiTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterParsingOsgiTest.java
index 557ebc5..06048c3 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterParsingOsgiTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/SpecParameterParsingOsgiTest.java
@@ -29,7 +29,6 @@ import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.objs.SpecParameter;
 import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
-import org.apache.brooklyn.core.BrooklynVersion;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.objs.BasicSpecParameter;
@@ -40,7 +39,6 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 
 public class SpecParameterParsingOsgiTest extends AbstractYamlTest {
 
@@ -82,36 +80,9 @@ public class SpecParameterParsingOsgiTest extends AbstractYamlTest {
     public void testOsgiClassScanned() {
         TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
         TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        addCatalogItems("brooklyn.catalog:",
-            "    bundle: test-items",
-            "    version: 2.0-test_java",
-            "    items:",
-            "    - scanJavaAnnotations: true",
-            "      item:",
-            "        id: here-item",
-            "        type: "+OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY,
-            "      libraries:",
-            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH,
-            "      - classpath://" + OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_V2_PATH);
-
-        RegisteredType hereItem = mgmt().getTypeRegistry().get("here-item");
-        assertEquals(hereItem.getVersion(), "2.0-test_java");
-        assertEquals(hereItem.getLibraries().size(), 3);
-        assertEquals(hereItem.getContainingBundle(), "test-items:2.0-test_java");
+        addCatalogItems(CatalogScanOsgiTest.bomForLegacySiblingLibraries());
         
         RegisteredType item = mgmt().getTypeRegistry().get(OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY);
-        // since 0.12.0 items now installed with version from bundle, not inherited from the version here
-        assertEquals(item.getVersion(), BrooklynVersion.get());
-        // since 0.12.0 library bundles (correctly) don't inherit libraries from caller
-        assertEquals(item.getLibraries().size(), 1);
-        assertEquals(Iterables.getOnlyElement(item.getLibraries()).getVersionedName().toString(), 
-            OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL+":"+"0.2.0");
-        
-        assertEquals(item.getContainingBundle(), OsgiTestResources.BROOKLYN_TEST_MORE_ENTITIES_SYMBOLIC_NAME_FULL+":"+"0.2.0");
-        
-        // TODO assertions above should be in separate test
-        
         AbstractBrooklynObjectSpec<?,?> spec = createSpec(item);
         List<SpecParameter<?>> inputs = spec.getParameters();
         if (inputs.isEmpty()) Assert.fail("no inputs (if you're in the IDE, mvn clean install may need to be run to rebuild osgi test JARs)");

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
index 12abc50..7e6f176 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -32,6 +32,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -46,6 +47,7 @@ import org.apache.brooklyn.core.effector.AddChildrenEffector;
 import org.apache.brooklyn.core.effector.Effectors;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
 import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.core.test.entity.TestApplication;
@@ -208,11 +210,11 @@ public class CampYamlLiteTest {
                 "    type: " + MockWebPlatform.APPSERVER.getName());
     }
 
-    protected void installWithoutCatalogBom(LocalManagementContext mgmt, String bundleUrl) {
+    public static void installWithoutCatalogBom(ManagementContext mgmt, String bundleUrl) {
         // install bundle for class access but without loading its catalog.bom, 
         // since we only have mock matchers here
         // (if we don't do this, the default routines install it and try to process the catalog.bom, failing)
-        mgmt.getOsgiManager().get().installDeferredStart(new BasicManagedBundle(null, null, bundleUrl), null).get();
+        ((ManagementContextInternal)mgmt).getOsgiManager().get().installDeferredStart(new BasicManagedBundle(null, null, bundleUrl), null).get();
     }
 
     private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index d003ce9..c0e2e07 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -25,6 +25,7 @@ import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.util.Collection;
 import java.util.Collections;
@@ -57,6 +58,7 @@ import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult.ResultCode;
 import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
 import org.apache.brooklyn.core.mgmt.internal.CampYamlParser;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.typereg.BasicManagedBundle;
 import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer;
 import org.apache.brooklyn.core.typereg.RegisteredTypeNaming;
 import org.apache.brooklyn.util.collections.MutableList;
@@ -72,7 +74,9 @@ import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.javalang.AggregateClassLoader;
 import org.apache.brooklyn.util.javalang.JavaClassNames;
 import org.apache.brooklyn.util.javalang.LoadedClassLoader;
+import org.apache.brooklyn.util.os.Os;
 import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.stream.Streams;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
@@ -560,7 +564,7 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                 if (isLibrariesMoreThanJustContainingBundle(libraryBundlesNew, containingBundle)) {
                     // legacy mode, since 0.12.0, scan libraries referenced in a legacy non-bundle BOM
                     log.warn("Deprecated use of scanJavaAnnotations to scan other libraries ("+libraryBundlesNew+"); libraries should declare they scan themselves");
-                    result.addAll(scanAnnotationsFromBundles(mgmt, libraryBundlesNew, catalogMetadata));
+                    result.addAll(scanAnnotationsLegacyInListOfLibraries(mgmt, libraryBundlesNew, catalogMetadata, containingBundle));
                 } else if (!isLibrariesMoreThanJustContainingBundle(libraryBundles, containingBundle)) {
                     // for default catalog, no libraries declared, we want to scan local classpath
                     // bundle should be named "brooklyn-default-catalog"
@@ -571,19 +575,21 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                         // since 0.12.0, require this to be right next to where libraries are defined, or at root
                         log.warn("Deprecated use of scanJavaAnnotations declared in item; should be declared at the top level of the BOM");
                     }
-                    result.addAll(scanAnnotationsFromLocal(mgmt, catalogMetadata));
+                    result.addAll(scanAnnotationsFromLocalNonBundleClasspath(mgmt, catalogMetadata, containingBundle));
                 } else {
                     throw new IllegalStateException("Cannot scan for Java catalog items when libraries declared on an ancestor; scanJavaAnnotations should be specified alongside brooklyn.libraries (or ideally those libraries should specify to scan)");
                 }
             } else {
-                if (depth>0) {
-                    // since 0.12.0, require this to be right next to where libraries are defined, or at root
-                    log.warn("Deprecated use of scanJavaAnnotations declared in item; should be declared at the top level of the BOM");
-                }
-                // normal JAR install, only scan that bundle (the one containing the catalog.bom)
-                result.addAll(scanAnnotationsFromBundles(mgmt, MutableList.of(containingBundle), catalogMetadata));
-                // TODO above (scanning a ZIP uploaded) won't work yet because scan routines need a URL
-                // TODO are libraries installed properly, such that they are now managed and their catalog.bom's are scanned ?
+                throw new IllegalArgumentException("Scanning for Java annotations is not supported in BOMs in bundles; "
+                    + "entries should be listed explicitly in the catalog.bom");
+                // see comments on scanAnnotationsInBundle
+//                if (depth>0) {
+//                    // since 0.12.0, require this to be right next to where libraries are defined, or at root
+//                    log.warn("Deprecated use of scanJavaAnnotations declared in item; should be declared at the top level of the BOM");
+//                }
+//                // normal JAR install, only scan that bundle (the one containing the catalog.bom)
+//                // note metadata not relevant here
+//                result.addAll(scanAnnotationsInBundle(mgmt, containingBundle));
             }
         }
         
@@ -832,12 +838,12 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         return oldValue;
     }
 
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromLocal(ManagementContext mgmt, Map<?, ?> catalogMetadata) {
+    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromLocalNonBundleClasspath(ManagementContext mgmt, Map<?, ?> catalogMetadata, ManagedBundle containingBundle) {
         CatalogDto dto = CatalogDto.newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the classpath", "scanning-local-classpath");
-        return scanAnnotationsInternal(mgmt, new CatalogDo(dto), catalogMetadata);
+        return scanAnnotationsInternal(mgmt, new CatalogDo(dto), catalogMetadata, containingBundle);
     }
     
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromBundles(ManagementContext mgmt, Collection<? extends OsgiBundleWithUrl> libraries, Map<?, ?> catalogMetadata) {
+    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsLegacyInListOfLibraries(ManagementContext mgmt, Collection<? extends OsgiBundleWithUrl> libraries, Map<?, ?> catalogMetadata, ManagedBundle containingBundle) {
         CatalogDto dto = CatalogDto.newNamedInstance("Bundles Scanned Catalog", "All annotated Brooklyn entities detected in bundles", "scanning-bundles-classpath-"+libraries.hashCode());
         List<String> urls = MutableList.of();
         for (OsgiBundleWithUrl b: libraries) {
@@ -857,22 +863,52 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         
         CatalogDo subCatalog = new CatalogDo(dto);
         subCatalog.addToClasspath(urls.toArray(new String[0]));
-        return scanAnnotationsInternal(mgmt, subCatalog, catalogMetadata);
+        return scanAnnotationsInternal(mgmt, subCatalog, catalogMetadata, containingBundle);
     }
     
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInternal(ManagementContext mgmt, CatalogDo subCatalog, Map<?, ?> catalogMetadata) {
-        // TODO this does java-scanning only;
-        // the call when scanning bundles should use the CatalogItem instead and use OSGi when loading for scanning
-        // (or another scanning mechanism).  see comments on CatalogClasspathDo.load
+    @SuppressWarnings("unused")  // keep during 0.12.0 until we are decided we won't support this; search for this method name
+    // note that it breaks after rebind since we don't have the JAR -- see notes below
+    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInBundle(ManagementContext mgmt, ManagedBundle containingBundle) {
+        CatalogDto dto = CatalogDto.newNamedInstance("Bundle "+containingBundle.getVersionedName().toOsgiString()+" Scanned Catalog", "All annotated Brooklyn entities detected in bundles", "scanning-bundle-"+containingBundle.getVersionedName().toOsgiString());
+        CatalogDo subCatalog = new CatalogDo(dto);
+        // need access to a JAR to scan this
+        String url = null;
+        if (containingBundle instanceof BasicManagedBundle) {
+            File f = ((BasicManagedBundle)containingBundle).getTempLocalFileWhenJustUploaded();
+            if (f!=null) {
+                url = "file:"+f.getAbsolutePath();
+            }
+        }
+        // type.getSubPathName(), type, id+".jar", com.google.common.io.Files.asByteSource(f), exceptionHandler);
+        if (url==null) {
+            url = containingBundle.getUrl();
+        }
+        if (url==null) {
+            // NOT available after persistence/rebind 
+            // as shown by test in CatalogOsgiVersionMoreEntityRebindTest
+            throw new IllegalArgumentException("Error prepaing to scan "+containingBundle.getVersionedName()+": no URL available");
+        }
+        // org.reflections requires the URL to be "file:" containg ".jar"
+        File fJar = Os.newTempFile(containingBundle.getVersionedName().toOsgiString(), ".jar");
+        try {
+            Streams.copy(ResourceUtils.create().getResourceFromUrl(url), new FileOutputStream(fJar));
+        } catch (FileNotFoundException e) {
+            throw Exceptions.propagate("Error extracting "+url+" to scan "+containingBundle.getVersionedName(), e);
+        }
+        subCatalog.addToClasspath(new String[] { "file:"+fJar.getAbsolutePath() });
+        Collection<CatalogItemDtoAbstract<?, ?>> result = scanAnnotationsInternal(mgmt, subCatalog, MutableMap.of("version", containingBundle.getSuppliedVersionString()), containingBundle);
+        fJar.delete();
+        return result;
+    }
+
+    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInternal(ManagementContext mgmt, CatalogDo subCatalog, Map<?, ?> catalogMetadata, ManagedBundle containingBundle) {
         subCatalog.mgmt = mgmt;
         subCatalog.setClasspathScanForEntities(CatalogScanningModes.ANNOTATIONS);
         subCatalog.load();
-        // TODO apply metadata?  (extract YAML from the items returned)
-        // also see doc .../catalog/index.md which says we might not apply metadata
         @SuppressWarnings({ "unchecked", "rawtypes" })
         Collection<CatalogItemDtoAbstract<?, ?>> result = (Collection)Collections2.transform(
                 (Collection<CatalogItemDo<Object,Object>>)(Collection)subCatalog.getIdCache().values(), 
-                itemDoToDtoAddingSelectedMetadataDuringScan(catalogMetadata));
+                itemDoToDtoAddingSelectedMetadataDuringScan(catalogMetadata, containingBundle));
         return result;
     }
 
@@ -1353,24 +1389,43 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         };
     }
     
-    private static <T,SpecT> Function<CatalogItemDo<T, SpecT>, CatalogItem<T,SpecT>> itemDoToDtoAddingSelectedMetadataDuringScan(final Map<?, ?> catalogMetadata) {
+    private static <T,SpecT> Function<CatalogItemDo<T, SpecT>, CatalogItem<T,SpecT>> itemDoToDtoAddingSelectedMetadataDuringScan(final Map<?, ?> catalogMetadata, ManagedBundle containingBundle) {
         return new Function<CatalogItemDo<T,SpecT>, CatalogItem<T,SpecT>>() {
             @Override
             public CatalogItem<T,SpecT> apply(@Nullable CatalogItemDo<T,SpecT> item) {
                 if (item==null) return null;
                 CatalogItemDtoAbstract<T, SpecT> dto = (CatalogItemDtoAbstract<T, SpecT>) item.getDto();
 
-                // when scanning we only allow version and libraries to be overwritten
+                // allow metadata to overwrite version and library bundles;
+                // however this should only be used for local classpath scanning and legacy external libraries;
+                // bundle scans should _not_ use this
                 
                 String version = getFirstAs(catalogMetadata, String.class, "version").orNull();
                 if (Strings.isNonBlank(version)) dto.setVersion(version);
                 
-                Object librariesCombined = catalogMetadata.get("brooklyn.libraries");
-                if (librariesCombined instanceof Collection) {
+                Collection<CatalogBundle> libraryBundles = MutableSet.of(); 
+                if (containingBundle!=null) {
+                    libraryBundles.add(new CatalogBundleDto(containingBundle.getSymbolicName(), containingBundle.getSuppliedVersionString(), null));
+                }
+                libraryBundles.addAll(dto.getLibraries());
+                Object librariesInherited;
+                librariesInherited = catalogMetadata.get("brooklyn.libraries");
+                if (librariesInherited instanceof Collection) {
+                    // will be set by scan -- slightly longwinded way to retrieve, but scanning for osgi needs an overhaul in any case
+                    libraryBundles.addAll(CatalogItemDtoAbstract.parseLibraries((Collection<?>) librariesInherited));
+                }
+                librariesInherited = catalogMetadata.get("libraries");
+                if (librariesInherited instanceof Collection) {
+                    log.warn("Legacy 'libraries' encountered; use 'brooklyn.libraries'");
                     // will be set by scan -- slightly longwinded way to retrieve, but scanning for osgi needs an overhaul in any case
-                    Collection<CatalogBundle> libraryBundles = CatalogItemDtoAbstract.parseLibraries((Collection<?>) librariesCombined);
-                    dto.setLibraries(libraryBundles);
+                    libraryBundles.addAll(CatalogItemDtoAbstract.parseLibraries((Collection<?>) librariesInherited));
+                }
+                dto.setLibraries(libraryBundles);
+                
+                if (containingBundle!=null && dto.getContainingBundle()==null) {
+                    dto.setContainingBundle(containingBundle.getVersionedName());
                 }
+                
                 // replace java type with plan yaml -- needed for libraries / catalog item to be picked up,
                 // but probably useful to transition away from javaType altogether
                 dto.setSymbolicName(dto.getJavaType());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
index bd0c3c7..70a8374 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
@@ -111,7 +111,9 @@ public class CatalogClasspathDo {
     
     /** causes all scanning-based classpaths to scan the classpaths
     * (but does _not_ load all JARs) */
-    // TODO this does a Java scan; we also need an OSGi scan which uses the OSGi classloaders when loading for scanning and resolving dependencies 
+    // NOTE this does a Java scan; we also need an OSGi scan which uses the OSGi classloaders when loading for scanning and resolving dependencies
+    // TODO AH thinks we should delete ALL this old catalog stuff and scanning and annotations; it's redundant now that we use bundles,
+    // and scanning doesn't fit with the OSGi way of doing things
     synchronized void load() {
         if (classpath == null || isLoaded) return;
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/core/src/main/java/org/apache/brooklyn/util/core/javalang/ReflectionScanner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/javalang/ReflectionScanner.java b/core/src/main/java/org/apache/brooklyn/util/core/javalang/ReflectionScanner.java
index bb46376..b5ca2c9 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/javalang/ReflectionScanner.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/javalang/ReflectionScanner.java
@@ -72,6 +72,9 @@ public class ReflectionScanner {
             final String optionalPrefix,
             final Predicate<String> filter,
             final ClassLoader ...classLoaders) {
+        if (Reflections.log==null) {
+            Reflections.log = log;
+        }
         reflections = new Reflections(new ConfigurationBuilder() {
             {
                 if (urlsToScan!=null)

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/dependencies/osgi/com-example-entities/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/com-example-entities/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/com-example-entities/src/main/resources/catalog.bom
index a5fe6bd..9cc84c3 100644
--- a/utils/common/dependencies/osgi/com-example-entities/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/com-example-entities/src/main/resources/catalog.bom
@@ -17,7 +17,6 @@
 
 
 brooklyn.catalog:
-    version: "0.12.0-SNAPSHOT" # BROOKLYN_VERSION
     itemType: entity
     description: For testing loading catalog.bom with catalog scan
     displayName: I Haz Catalog

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
index e491a23..8a768f1 100644
--- a/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/entities/src/main/resources/catalog.bom
@@ -17,7 +17,6 @@
 
 
 brooklyn.catalog:
-    version: "0.12.0-SNAPSHOT" # BROOKLYN_VERSION
     itemType: entity
     description: For testing loading catalog.bom with catalog scan
     displayName: I Haz Catalog

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
index c3e97dc..2426d45 100644
--- a/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v1/src/main/resources/catalog.bom
@@ -16,7 +16,6 @@
 # under the License.
 
 brooklyn.catalog:
-    version: "0.12.0-SNAPSHOT" # BROOKLYN_VERSION
     itemType: entity
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MoreEntity

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
index c3e97dc..2426d45 100644
--- a/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v2-evil-twin/src/main/resources/catalog.bom
@@ -16,7 +16,6 @@
 # under the License.
 
 brooklyn.catalog:
-    version: "0.12.0-SNAPSHOT" # BROOKLYN_VERSION
     itemType: entity
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MoreEntity

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
----------------------------------------------------------------------
diff --git a/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom b/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
index 6307508..0da6334 100644
--- a/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
+++ b/utils/common/dependencies/osgi/more-entities-v2/src/main/resources/catalog.bom
@@ -16,7 +16,6 @@
 # under the License.
 
 brooklyn.catalog:
-    version: "0.12.0-SNAPSHOT" # BROOKLYN_VERSION
     items:
     - id: org.apache.brooklyn.test.osgi.entities.more.MorePolicy
       itemType: policy

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-com-example-entities.jar
----------------------------------------------------------------------
diff --git a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-com-example-entities.jar b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-com-example-entities.jar
index 51cf119..44f5273 100644
Binary files a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-com-example-entities.jar and b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-com-example-entities.jar differ

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar
----------------------------------------------------------------------
diff --git a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar
index 6d0cf2d..f879df7 100644
Binary files a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar and b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-entities.jar differ

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar
----------------------------------------------------------------------
diff --git a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar
index 84fc378..6763cc2 100644
Binary files a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar and b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.1.0.jar differ

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
----------------------------------------------------------------------
diff --git a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar
index 24113f6..d457554 100644
Binary files a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar and b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_0.2.0.jar differ

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2165778a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_evil-twin_0.2.0.jar
----------------------------------------------------------------------
diff --git a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_evil-twin_0.2.0.jar b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_evil-twin_0.2.0.jar
index 21a114a..1f58c67 100644
Binary files a/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_evil-twin_0.2.0.jar and b/utils/common/src/test/resources/brooklyn/osgi/brooklyn-test-osgi-more-entities_evil-twin_0.2.0.jar differ