You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2017/06/08 09:37:42 UTC
[08/11] brooklyn-server git commit: extract OsgiClassLoader as more
general ClassLoaderFromStackOfBrooklynClassLoadingContext
extract OsgiClassLoader as more general ClassLoaderFromStackOfBrooklynClassLoadingContext
so we can use and test it from XmlSerializer (ie memento-free)
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/f9566273
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/f9566273
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/f9566273
Branch: refs/heads/master
Commit: f9566273d3c748e16a1733cd00489bef29d9f53a
Parents: f23f4cb
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Jun 7 13:46:50 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Jun 7 13:47:40 2017 +0100
----------------------------------------------------------------------
.../BrooklynClassLoadingContextSequential.java | 2 -
...rFromStackOfBrooklynClassLoadingContext.java | 132 +++++++++++++++++
.../core/mgmt/persist/XmlMementoSerializer.java | 108 +-------------
...mStackOfBrooklynClassLoadingContextTest.java | 143 +++++++++++++++++++
...entoSerializerDelegatingClassLoaderTest.java | 143 -------------------
5 files changed, 280 insertions(+), 248 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f9566273/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java
index 50a0509..ddd5c5b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/BrooklynClassLoadingContextSequential.java
@@ -32,8 +32,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Objects;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
public final class BrooklynClassLoadingContextSequential extends AbstractBrooklynClassLoadingContext {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f9566273/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContext.java
new file mode 100644
index 0000000..f42ecd2
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContext.java
@@ -0,0 +1,132 @@
+/*
+ * 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.core.mgmt.classloading;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Stack;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential;
+import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.util.core.ClassLoaderUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.javalang.ClassLoadingContext;
+
+/** Provides a stack where {@link ClassLoadingContext} instances can be pushed and popped,
+ * with the most recently pushed one in effect at any given time.
+ * <p>
+ * This is useful when traversing a tree some of whose elements may bring custom search paths,
+ * and the worker wants to have a simple view of the loader to use at any point in time.
+ * For example XStream keeps a class-loader in effect but when deserializing things
+ * some of those things may define bundles to use. */
+public class ClassLoaderFromStackOfBrooklynClassLoadingContext extends ClassLoader {
+
+ private final Stack<BrooklynClassLoadingContext> contexts = new Stack<BrooklynClassLoadingContext>();
+ private final Stack<ClassLoader> cls = new Stack<ClassLoader>();
+ private final AtomicReference<Thread> lockOwner = new AtomicReference<Thread>();
+ private ManagementContext mgmt;
+ private ClassLoader currentClassLoader;
+ private AtomicReference<ClassLoaderUtils> currentLoader = new AtomicReference<>();
+ private int lockCount;
+
+ public ClassLoaderFromStackOfBrooklynClassLoadingContext(ClassLoader classLoader) {
+ setCurrentClassLoader(classLoader);
+ }
+
+ public void setManagementContext(ManagementContext mgmt) {
+ this.mgmt = checkNotNull(mgmt, "mgmt");
+ currentLoader.set(new ClassLoaderUtils(currentClassLoader, mgmt));
+ }
+
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ return currentLoader.get().loadClass(name);
+ }
+
+ /** Must be accompanied by a corresponding {@link #popClassLoadingContext()} when finished. */
+ @SuppressWarnings("deprecation")
+ public void pushClassLoadingContext(BrooklynClassLoadingContext clcNew) {
+ acquireLock();
+ BrooklynClassLoadingContext oldClc;
+ if (!contexts.isEmpty()) {
+ oldClc = contexts.peek();
+ } else {
+ // TODO xml serializers using this should take a BCLC instead of a CL
+ oldClc = JavaBrooklynClassLoadingContext.create(mgmt, getCurrentClassLoader());
+ }
+ BrooklynClassLoadingContextSequential clcMerged = new BrooklynClassLoadingContextSequential(mgmt, oldClc, clcNew);
+ ClassLoader newCL = ClassLoaderFromBrooklynClassLoadingContext.of(clcMerged);
+ contexts.push(clcMerged);
+ cls.push(getCurrentClassLoader());
+ setCurrentClassLoader(newCL);
+ }
+
+ public void popClassLoadingContext() {
+ synchronized (lockOwner) {
+ releaseXstreamLock();
+ setCurrentClassLoader(cls.pop());
+ contexts.pop();
+ }
+ }
+
+ private ClassLoader getCurrentClassLoader() {
+ return currentClassLoader;
+ }
+
+ private void setCurrentClassLoader(ClassLoader classLoader) {
+ currentClassLoader = checkNotNull(classLoader);
+ currentLoader.set(new ClassLoaderUtils(currentClassLoader, mgmt));
+ }
+
+ protected void acquireLock() {
+ synchronized (lockOwner) {
+ while (true) {
+ if (lockOwner.compareAndSet(null, Thread.currentThread()) ||
+ Thread.currentThread().equals( lockOwner.get() )) {
+ break;
+ }
+ try {
+ lockOwner.wait(1000);
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+ lockCount++;
+ }
+ }
+
+ protected void releaseXstreamLock() {
+ synchronized (lockOwner) {
+ if (lockCount<=0) {
+ throw new IllegalStateException("not locked");
+ }
+ if (--lockCount == 0) {
+ if (!lockOwner.compareAndSet(Thread.currentThread(), null)) {
+ Thread oldOwner = lockOwner.getAndSet(null);
+ throw new IllegalStateException("locked by "+oldOwner+" but unlock attempt by "+Thread.currentThread());
+ }
+ lockOwner.notifyAll();
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f9566273/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
index dac3ca7..e83b5ea 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
@@ -24,9 +24,7 @@ import java.io.IOException;
import java.io.Writer;
import java.util.Map;
import java.util.NoSuchElementException;
-import java.util.Stack;
import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.effector.Effector;
@@ -49,9 +47,7 @@ import org.apache.brooklyn.core.effector.BasicParameterType;
import org.apache.brooklyn.core.effector.EffectorAndBody;
import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory;
import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential;
-import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromBrooklynClassLoadingContext;
-import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromStackOfBrooklynClassLoadingContext;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicCatalogItemMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEnricherMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEntityMemento;
@@ -60,14 +56,12 @@ import org.apache.brooklyn.core.mgmt.rebind.dto.BasicLocationMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicManagedBundleMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicPolicyMemento;
import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.util.core.ClassLoaderUtils;
import org.apache.brooklyn.util.core.xstream.XmlSerializer;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.annotations.VisibleForTesting;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.SingleValueConverter;
@@ -88,7 +82,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
private static final Logger LOG = LoggerFactory.getLogger(XmlMementoSerializer.class);
- private final OsgiClassLoader delegatingClassLoader;
+ private final ClassLoaderFromStackOfBrooklynClassLoadingContext delegatingClassLoader;
private LookupContext lookupContext;
public XmlMementoSerializer(ClassLoader classLoader) {
@@ -97,7 +91,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
public XmlMementoSerializer(ClassLoader classLoader, Map<String, String> deserializingClassRenames) {
super(deserializingClassRenames);
- this.delegatingClassLoader = new OsgiClassLoader(classLoader);
+ this.delegatingClassLoader = new ClassLoaderFromStackOfBrooklynClassLoadingContext(classLoader);
xstream.setClassLoader(this.delegatingClassLoader);
xstream.alias("entity", BasicEntityMemento.class);
@@ -449,7 +443,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
RegisteredType cat = lookupContext.lookupManagementContext().getTypeRegistry().get(catalogItemId);
if (cat==null) throw new NoSuchElementException("catalog item: "+catalogItemId);
BrooklynClassLoadingContext clcNew = CatalogUtils.newClassLoadingContext(lookupContext.lookupManagementContext(), cat);
- delegatingClassLoader.pushXstreamCustomClassLoader(clcNew);
+ delegatingClassLoader.pushClassLoadingContext(clcNew);
customLoaderSet = true;
}
@@ -460,7 +454,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
} finally {
context.put("SpecConverter.instance", null);
if (customLoaderSet) {
- delegatingClassLoader.popXstreamCustomClassLoader();
+ delegatingClassLoader.popClassLoadingContext();
}
}
}
@@ -483,96 +477,4 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento
context.put("SpecConverter.instance", instance);
}
}
-
- @VisibleForTesting
- static class OsgiClassLoader extends ClassLoader {
- private final Stack<BrooklynClassLoadingContext> contexts = new Stack<BrooklynClassLoadingContext>();
- private final Stack<ClassLoader> cls = new Stack<ClassLoader>();
- private final AtomicReference<Thread> xstreamLockOwner = new AtomicReference<Thread>();
- private ManagementContext mgmt;
- private ClassLoader currentClassLoader;
- private AtomicReference<ClassLoaderUtils> currentLoader = new AtomicReference<>();
- private int lockCount;
-
- protected OsgiClassLoader(ClassLoader classLoader) {
- setCurrentClassLoader(classLoader);
- }
-
- protected void setManagementContext(ManagementContext mgmt) {
- this.mgmt = checkNotNull(mgmt, "mgmt");
- currentLoader.set(new ClassLoaderUtils(currentClassLoader, mgmt));
- }
-
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- return currentLoader.get().loadClass(name);
- }
-
- /** Must be accompanied by a corresponding {@link #popXstreamCustomClassLoader()} when finished. */
- @SuppressWarnings("deprecation")
- protected void pushXstreamCustomClassLoader(BrooklynClassLoadingContext clcNew) {
- acquireXstreamLock();
- BrooklynClassLoadingContext oldClc;
- if (!contexts.isEmpty()) {
- oldClc = contexts.peek();
- } else {
- // TODO XmlMementoSerializer should take a BCLC instead of a CL
- oldClc = JavaBrooklynClassLoadingContext.create(mgmt, getCurrentClassLoader());
- }
- BrooklynClassLoadingContextSequential clcMerged = new BrooklynClassLoadingContextSequential(mgmt, oldClc, clcNew);
- ClassLoader newCL = ClassLoaderFromBrooklynClassLoadingContext.of(clcMerged);
- contexts.push(clcMerged);
- cls.push(getCurrentClassLoader());
- setCurrentClassLoader(newCL);
- }
-
- protected void popXstreamCustomClassLoader() {
- synchronized (xstreamLockOwner) {
- releaseXstreamLock();
- setCurrentClassLoader(cls.pop());
- contexts.pop();
- }
- }
-
- private ClassLoader getCurrentClassLoader() {
- return currentClassLoader;
- }
-
- private void setCurrentClassLoader(ClassLoader classLoader) {
- currentClassLoader = checkNotNull(classLoader);
- currentLoader.set(new ClassLoaderUtils(currentClassLoader, mgmt));
- }
-
- protected void acquireXstreamLock() {
- synchronized (xstreamLockOwner) {
- while (true) {
- if (xstreamLockOwner.compareAndSet(null, Thread.currentThread()) ||
- Thread.currentThread().equals( xstreamLockOwner.get() )) {
- break;
- }
- try {
- xstreamLockOwner.wait(1000);
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- }
- }
- lockCount++;
- }
- }
-
- protected void releaseXstreamLock() {
- synchronized (xstreamLockOwner) {
- if (lockCount<=0) {
- throw new IllegalStateException("xstream not locked");
- }
- if (--lockCount == 0) {
- if (!xstreamLockOwner.compareAndSet(Thread.currentThread(), null)) {
- Thread oldOwner = xstreamLockOwner.getAndSet(null);
- throw new IllegalStateException("xstream was locked by "+oldOwner+" but unlock attempt by "+Thread.currentThread());
- }
- xstreamLockOwner.notifyAll();
- }
- }
- }
- }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f9566273/core/src/test/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContextTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContextTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContextTest.java
new file mode 100644
index 0000000..a2237af
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/classloading/ClassLoaderFromStackOfBrooklynClassLoadingContextTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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.core.mgmt.classloading;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromStackOfBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
+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.test.support.TestResourceUnavailableException;
+import org.apache.brooklyn.util.core.osgi.Osgis;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.osgi.OsgiTestResources;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+
+public class ClassLoaderFromStackOfBrooklynClassLoadingContextTest {
+
+ private LocalManagementContext mgmt;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ mgmt = LocalManagementContextForTests.builder(true).enableOsgiReusable().build();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (mgmt != null) {
+ Entities.destroyAll(mgmt);
+ }
+ }
+
+ @Test
+ public void testLoadClassFromBundle() throws Exception {
+ TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
+
+ ClassLoader classLoader = getClass().getClassLoader();
+ Bundle apiBundle = getBundle(mgmt, "org.apache.brooklyn.api");
+ Bundle coreBundle = getBundle(mgmt, "org.apache.brooklyn.core");
+
+ String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
+ Bundle otherBundle = installBundle(mgmt, bundleUrl);
+
+ assertLoads(classLoader, Entity.class, Optional.of(apiBundle));
+ assertLoads(classLoader, AbstractEntity.class, Optional.of(coreBundle));
+ assertLoads(classLoader, OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY, Optional.of(otherBundle));
+ }
+
+ @Test
+ public void testLoadClassVanilla() throws Exception {
+ ClassLoader classLoader = getClass().getClassLoader();
+
+ assertLoads(classLoader, Entity.class, Optional.<Bundle>absent());
+ assertLoads(classLoader, AbstractEntity.class, Optional.<Bundle>absent());
+ }
+
+ // Tests we can do funny stuff, like return a differently named class from that expected!
+ @Test
+ public void testLoadClassReturningDifferentlyNamedClass() throws Exception {
+ final String specialClassName = "my.madeup.Clazz";
+
+ ClassLoader classLoader = new ClassLoader() {
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (name != null && name.equals(specialClassName)) {
+ return Entity.class;
+ }
+ return getClass().getClassLoader().loadClass(name);
+ }
+ };
+
+ ClassLoaderFromStackOfBrooklynClassLoadingContext ocl = new ClassLoaderFromStackOfBrooklynClassLoadingContext(classLoader);
+ ocl.setManagementContext(mgmt);
+ assertEquals(ocl.loadClass(specialClassName), Entity.class);
+
+ // TODO The line below fails: java.lang.ClassNotFoundException: my/madeup/Clazz
+ //assertEquals(Class.forName(specialClassName, false, ocl).getName(), Entity.class.getName());
+ }
+
+ private void assertLoads(ClassLoader delegateClassLoader, Class<?> clazz, Optional<Bundle> bundle) throws Exception {
+ ClassLoaderFromStackOfBrooklynClassLoadingContext ocl = new ClassLoaderFromStackOfBrooklynClassLoadingContext(delegateClassLoader);
+ ocl.setManagementContext(mgmt);
+ String classname = (bundle.isPresent() ? bundle.get().getSymbolicName() + ":" : "") + clazz.getName();
+ assertEquals(ocl.loadClass(classname), clazz);
+
+ // TODO The line below fails, e.g.: java.lang.ClassNotFoundException: org/apache/brooklyn/api:org/apache/brooklyn/api/entity/Entity
+ //assertEquals(Class.forName(classname, false, ocl), clazz);
+
+ }
+
+ private void assertLoads(ClassLoader delegateClassLoader, String clazz, Optional<Bundle> bundle) throws Exception {
+ ClassLoaderFromStackOfBrooklynClassLoadingContext ocl = new ClassLoaderFromStackOfBrooklynClassLoadingContext(delegateClassLoader);
+ ocl.setManagementContext(mgmt);
+ String classname = (bundle.isPresent() ? bundle.get().getSymbolicName() + ":" : "") + clazz;
+ assertEquals(ocl.loadClass(classname).getName(), clazz);
+
+ // TODO The line below fails, e.g.: java.lang.ClassNotFoundException: org/apache/brooklyn/test/resources/osgi/brooklyn-test-osgi-entities:org/apache/brooklyn/test/osgi/entities/SimpleEntity
+ //assertEquals(Class.forName(classname, false, ocl).getName(), clazz);
+ }
+
+ private Bundle getBundle(ManagementContext mgmt, final String symbolicName) throws Exception {
+ OsgiManager osgiManager = ((ManagementContextInternal)mgmt).getOsgiManager().get();
+ Framework framework = osgiManager.getFramework();
+ Maybe<Bundle> result = Osgis.bundleFinder(framework)
+ .symbolicName(symbolicName)
+ .find();
+ return result.get();
+ }
+
+ private Bundle installBundle(ManagementContext mgmt, String bundleUrl) throws Exception {
+ OsgiManager osgiManager = ((ManagementContextInternal)mgmt).getOsgiManager().get();
+ Framework framework = osgiManager.getFramework();
+ return Osgis.install(framework, bundleUrl);
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/f9566273/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerDelegatingClassLoaderTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerDelegatingClassLoaderTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerDelegatingClassLoaderTest.java
deleted file mode 100644
index 38c9982..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerDelegatingClassLoaderTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.core.mgmt.persist;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
-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.mgmt.persist.XmlMementoSerializer.OsgiClassLoader;
-import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.support.TestResourceUnavailableException;
-import org.apache.brooklyn.util.core.osgi.Osgis;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.osgi.OsgiTestResources;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.launch.Framework;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Optional;
-
-public class XmlMementoSerializerDelegatingClassLoaderTest {
-
- private LocalManagementContext mgmt;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- mgmt = LocalManagementContextForTests.builder(true).enableOsgiReusable().build();
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (mgmt != null) {
- Entities.destroyAll(mgmt);
- }
- }
-
- @Test
- public void testLoadClassFromBundle() throws Exception {
- TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
-
- ClassLoader classLoader = getClass().getClassLoader();
- Bundle apiBundle = getBundle(mgmt, "org.apache.brooklyn.api");
- Bundle coreBundle = getBundle(mgmt, "org.apache.brooklyn.core");
-
- String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL;
- Bundle otherBundle = installBundle(mgmt, bundleUrl);
-
- assertLoads(classLoader, Entity.class, Optional.of(apiBundle));
- assertLoads(classLoader, AbstractEntity.class, Optional.of(coreBundle));
- assertLoads(classLoader, OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENTITY, Optional.of(otherBundle));
- }
-
- @Test
- public void testLoadClassVanilla() throws Exception {
- ClassLoader classLoader = getClass().getClassLoader();
-
- assertLoads(classLoader, Entity.class, Optional.<Bundle>absent());
- assertLoads(classLoader, AbstractEntity.class, Optional.<Bundle>absent());
- }
-
- // Tests we can do funny stuff, like return a differently named class from that expected!
- @Test
- public void testLoadClassReturningDifferentlyNamedClass() throws Exception {
- final String specialClassName = "my.madeup.Clazz";
-
- ClassLoader classLoader = new ClassLoader() {
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- if (name != null && name.equals(specialClassName)) {
- return Entity.class;
- }
- return getClass().getClassLoader().loadClass(name);
- }
- };
-
- OsgiClassLoader ocl = new XmlMementoSerializer.OsgiClassLoader(classLoader);
- ocl.setManagementContext(mgmt);
- assertEquals(ocl.loadClass(specialClassName), Entity.class);
-
- // TODO The line below fails: java.lang.ClassNotFoundException: my/madeup/Clazz
- //assertEquals(Class.forName(specialClassName, false, ocl).getName(), Entity.class.getName());
- }
-
- private void assertLoads(ClassLoader delegateClassLoader, Class<?> clazz, Optional<Bundle> bundle) throws Exception {
- OsgiClassLoader ocl = new XmlMementoSerializer.OsgiClassLoader(delegateClassLoader);
- ocl.setManagementContext(mgmt);
- String classname = (bundle.isPresent() ? bundle.get().getSymbolicName() + ":" : "") + clazz.getName();
- assertEquals(ocl.loadClass(classname), clazz);
-
- // TODO The line below fails, e.g.: java.lang.ClassNotFoundException: org/apache/brooklyn/api:org/apache/brooklyn/api/entity/Entity
- //assertEquals(Class.forName(classname, false, ocl), clazz);
-
- }
-
- private void assertLoads(ClassLoader delegateClassLoader, String clazz, Optional<Bundle> bundle) throws Exception {
- OsgiClassLoader ocl = new XmlMementoSerializer.OsgiClassLoader(delegateClassLoader);
- ocl.setManagementContext(mgmt);
- String classname = (bundle.isPresent() ? bundle.get().getSymbolicName() + ":" : "") + clazz;
- assertEquals(ocl.loadClass(classname).getName(), clazz);
-
- // TODO The line below fails, e.g.: java.lang.ClassNotFoundException: org/apache/brooklyn/test/resources/osgi/brooklyn-test-osgi-entities:org/apache/brooklyn/test/osgi/entities/SimpleEntity
- //assertEquals(Class.forName(classname, false, ocl).getName(), clazz);
- }
-
- private Bundle getBundle(ManagementContext mgmt, final String symbolicName) throws Exception {
- OsgiManager osgiManager = ((ManagementContextInternal)mgmt).getOsgiManager().get();
- Framework framework = osgiManager.getFramework();
- Maybe<Bundle> result = Osgis.bundleFinder(framework)
- .symbolicName(symbolicName)
- .find();
- return result.get();
- }
-
- private Bundle installBundle(ManagementContext mgmt, String bundleUrl) throws Exception {
- OsgiManager osgiManager = ((ManagementContextInternal)mgmt).getOsgiManager().get();
- Framework framework = osgiManager.getFramework();
- return Osgis.install(framework, bundleUrl);
- }
-}