aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHristo Iliev2010-08-18 12:28:04 (EDT)
committerSteve Powell2010-09-17 11:09:56 (EDT)
commit61738ad048b124afc067295227b292ccd9c7de9d (patch)
tree11525af9f115734bdd61634ea3f5c87c7480c025
parentf2a8d33f4b3af6c7f4f836fb3cc48a414ef9e9aa (diff)
downloadorg.eclipse.virgo.kernel-61738ad048b124afc067295227b292ccd9c7de9d.zip
org.eclipse.virgo.kernel-61738ad048b124afc067295227b292ccd9c7de9d.tar.gz
org.eclipse.virgo.kernel-61738ad048b124afc067295227b292ccd9c7de9d.tar.bz2
Bug 322774 Add ClassLoading commands to equinox shell.
-rw-r--r--org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/ServiceReferenceTracker.java2
-rw-r--r--org.eclipse.virgo.kernel.deployer.test/src/main/java/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/.classpath1
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/ivy.xml8
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/Activator.java24
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelper.java157
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/internal/commands/classloading/ClassLoadingCommandProvider.java191
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelperTests.java196
-rw-r--r--org.eclipse.virgo.kernel.osgicommand/template.mf5
-rw-r--r--org.eclipse.virgo.kernel.test/.classpath1
-rw-r--r--org.eclipse.virgo.kernel.test/ivy.xml26
-rw-r--r--org.eclipse.virgo.kernel.test/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/test/ClassLoadingHelperIntegrationTests.java151
-rw-r--r--org.eclipse.virgo.kernel.test/src/test/resources/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.test/src/test/resources/META-INF/test.config.properties3
14 files changed, 755 insertions, 17 deletions
diff --git a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/ServiceReferenceTracker.java b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/ServiceReferenceTracker.java
index 4740d50..4c3cd78 100644
--- a/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/ServiceReferenceTracker.java
+++ b/org.eclipse.virgo.kernel.core/src/main/java/org/eclipse/virgo/kernel/core/internal/ServiceReferenceTracker.java
@@ -44,7 +44,7 @@ class ServiceReferenceTracker {
/**
* Tracks the supplied {@link ServiceReference}. This <code>ServiceReference</code> will be
- * {@link ServiceReference#unget ungotten} during {@link #ungetAll()}.
+ * {@link BundleContext#ungetService ungotten} during {@link #ungetAll()}.
*
* @param reference the <code>ServiceReference</code> to track.
* @return the reference itself
diff --git a/org.eclipse.virgo.kernel.deployer.test/src/main/java/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.deployer.test/src/main/java/META-INF/MANIFEST.MF
index 12d4672..f6779a1 100644
--- a/org.eclipse.virgo.kernel.deployer.test/src/main/java/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.kernel.deployer.test/src/main/java/META-INF/MANIFEST.MF
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
Bundle-Version: 2.1.0
-Tool: Bundlor 1.0.0.M6
+Tool: Bundlor 1.0.0.RELEASE
Bundle-Name: (incubation) Virgo Kernel Deployer Test
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.eclipse.virgo.kernel.deployer.test.loadable
diff --git a/org.eclipse.virgo.kernel.osgicommand/.classpath b/org.eclipse.virgo.kernel.osgicommand/.classpath
index 04d1ba4..2af0781 100644
--- a/org.eclipse.virgo.kernel.osgicommand/.classpath
+++ b/org.eclipse.virgo.kernel.osgicommand/.classpath
@@ -11,5 +11,6 @@
<classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.shell"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.6.0.v20100517/org.eclipse.osgi-3.6.0.v20100517.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.6.0.v20100517/org.eclipse.osgi-sources-3.6.0.v20100517.jar"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100907105749/org.eclipse.virgo.util.osgi-2.1.0.D-20100907105749.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100907105749/org.eclipse.virgo.util.osgi-sources-2.1.0.D-20100907105749.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
diff --git a/org.eclipse.virgo.kernel.osgicommand/ivy.xml b/org.eclipse.virgo.kernel.osgicommand/ivy.xml
index fbe5674..335bebc 100644
--- a/org.eclipse.virgo.kernel.osgicommand/ivy.xml
+++ b/org.eclipse.virgo.kernel.osgicommand/ivy.xml
@@ -18,6 +18,14 @@
<dependency org="org.eclipse.osgi" name='org.eclipse.osgi' rev='${org.eclipse.osgi}' conf='compile->compile' />
<dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.osgi" rev="latest.integration" conf="compile->compile"/>
<dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.shell" rev="latest.integration" conf="compile->compile"/>
+<!-- TEST -->
+ <dependency org="org.slf4j" name="com.springsource.slf4j.nop" rev="${org.slf4j}" conf="test->runtime"/>
+ <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
+ <dependency org="org.easymock" name="com.springsource.org.easymock" rev="${org.easymock}" conf="test->runtime"/>
+ <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.test" rev="${org.eclipse.virgo.medic}" conf="test->runtime"/>
+
+ <override org="org.springframework" rev="${org.springframework}"/>
+ <override org="org.slf4j" rev="${org.slf4j}"/>
</dependencies>
</ivy-module>
diff --git a/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/Activator.java b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/Activator.java
index dd64b2d..176926c 100644
--- a/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/Activator.java
+++ b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/Activator.java
@@ -18,9 +18,11 @@ import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkUtils;
import org.eclipse.virgo.kernel.osgi.framework.OsgiServiceHolder;
import org.eclipse.virgo.kernel.osgicommand.internal.OsgiKernelShellCommand;
import org.eclipse.virgo.kernel.shell.CommandExecutor;
+import org.eclipse.virgo.kernel.osgicommand.internal.commands.classloading.ClassLoadingCommandProvider;
import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
/**
* {@link BundleActivator} for the osgi.console command extension bundle
@@ -28,16 +30,29 @@ import org.osgi.framework.BundleContext;
*
* <strong>Concurrent Semantics</strong><br />
* thread-safe
- *
- * @author Steve Powell
*/
public class Activator implements BundleActivator {
private static final int COMMAND_EXECUTOR_SERVICE_WAIT = 20*1000; // 20 seconds
+ private static final int SERVICE_WAIT_PAUSE = 100; // 100 milliseconds
+ private static final String PROVIDER_NAME = "org.eclipse.osgi.framework.console.CommandProvider"; //$NON-NLS-1$
+ private ServiceRegistration providerRegistration = null;
private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
public void start(BundleContext context) throws Exception {
+ boolean registerCommands = true;
+ try {
+ Class.forName(PROVIDER_NAME);
+ } catch (ClassNotFoundException e) {
+ registerCommands = false;
+ }
+
+ if (registerCommands) {
+ ClassLoadingCommandProvider provider = new ClassLoadingCommandProvider(context);
+ providerRegistration = context.registerService(PROVIDER_NAME, provider, null);
+ }
+
Runnable runnable = new PostStartInitialisationRunnable(context, this.registrationTracker);
Thread thread = new Thread(runnable);
thread.setDaemon(true);
@@ -45,10 +60,13 @@ public class Activator implements BundleActivator {
}
public void stop(BundleContext context) throws Exception {
+ if (providerRegistration != null)
+ providerRegistration.unregister();
+ providerRegistration = null;
+
this.registrationTracker.unregisterAll();
}
- private static final int SERVICE_WAIT_PAUSE = 100;
/**
* Get a service which might not be immediately available
* @param <T> type of service to get
diff --git a/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelper.java b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelper.java
new file mode 100644
index 0000000..4cf5f74
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelper.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ *******************************************************************************/
+package org.eclipse.virgo.kernel.osgicommand.helper;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import java.util.HashMap;
+
+/**
+ * Helper for class loading supporting commands
+ */
+public class ClassLoadingHelper {
+
+ /**
+ * Determines if a class package is exported by a bundle
+ *
+ * @param bundleContext Bundle context for interaction with the OSGi framework
+ * @param classPackage Class package to check for
+ * @param testBundle The bundle that has to be tested
+ * @return TRUE if the bundle is exported by the package, FALSE if the class is not exported or it does not have a package
+ */
+ public static boolean isPackageExported(BundleContext bundleContext, String classPackage, Bundle testBundle) {
+ ServiceReference reference = bundleContext.getServiceReference(PlatformAdmin.class.getName());
+ PlatformAdmin platformAdmin = (PlatformAdmin) bundleContext.getService(reference);
+ BundleDescription bundleDescription = platformAdmin.getState(false).getBundle(testBundle.getBundleId());
+
+ ExportPackageDescription[] exportDescriptions = bundleDescription.getSelectedExports();
+ for (ExportPackageDescription exportDescription : exportDescriptions) {
+ if (exportDescription.getName().equals(classPackage))
+ return true;
+ }
+
+ // not found
+ return false;
+ }
+
+ /**
+ * Returns the bundles that can load a class and the originating bundle in a map
+ *
+ * @param bundleContext Bundle context for interaction with the OSGi framework
+ * @param className Fully qualified class name (in the form &lt;package&gt;.&lt;class name&gt;)
+ * @return Map between the bundles that can load the class and the bundle that provides it in each case
+ */
+ public static HashMap<Bundle, Bundle> getBundlesLoadingClass(BundleContext bundleContext, String className) {
+ Bundle[] bundles = bundleContext.getBundles();
+ HashMap<Bundle, Bundle> foundBundles = new HashMap<Bundle, Bundle>();
+ for (Bundle bundle : bundles) {
+ Bundle originBundle = originBundleOfClass(className, bundleContext, bundle);
+ if (originBundle != null) {
+ foundBundles.put(bundle, originBundle);
+ }
+ }
+
+ return foundBundles;
+ }
+
+ /**
+ * Find the originating bundle of a class loaded by a bundle
+ *
+ * @param className Fully qualified class name (in the form &lt;package&gt;.&lt;class name&gt; name)
+ * @param bundleContext Bundle context for interaction with the OSGi framework
+ * @param loadingBundle Bundle instance to load class from
+ * @return originating {@link Bundle} or null if it cannot be loaded by <code>testBundle</code>
+ */
+ private static Bundle originBundleOfClass(String className, BundleContext bundleContext, Bundle loadingBundle) {
+ Class<?> clasz = tryToLoadClass(className, loadingBundle);
+ Bundle originBundle = null;
+ if (clasz != null) {
+ originBundle = FrameworkUtil.getBundle(clasz);
+ if (originBundle == null) {
+ // this is the system bundle
+ originBundle = bundleContext.getBundle(0);
+ }
+ }
+ return originBundle;
+ }
+
+ /**
+ * Tries to load a class
+ *
+ * @param className Fully qualified class name (in the form &lt;package&gt;.&lt;class name&gt;)
+ * @param bundle Bundle instance that has to be checked
+ * @return The loaded class or null if it cannot be loaded from this bundle
+ */
+ public static Class<?> tryToLoadClass(String className, Bundle bundle) {
+ if (bundle == null)
+ return null;
+
+ try {
+ return bundle.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ // do nothing - if the class is not found we don't care
+ }
+ return null;
+ }
+
+ /**
+ * Returns all bundles that can load a class
+ *
+ * @param bundleContext Bundle context for interaction with the OSGi framework
+ * @param className Fully qualified class name (in the form &lt;package&gt;.&lt;class name&gt;)
+ * @param bundle Bundle name or ID that has to be checked
+ * @return Map between the bundle that can load the class (key) and the one that provides it (value)
+ * @throws IllegalArgumentException if there is no bundle with such name/id
+ */
+ public static HashMap<Bundle, Bundle> getBundlesLoadingClass(BundleContext bundleContext, String className, String bundle) throws IllegalArgumentException {
+ HashMap<Bundle, Bundle> result = new HashMap<Bundle, Bundle>();
+ long id = Long.MIN_VALUE;
+ try {
+ id = Long.parseLong(bundle);
+ } catch (NumberFormatException e) {
+ // not a number - then it is bundle name
+ }
+
+ if (id >= 0) {
+ Bundle testBundle = bundleContext.getBundle(id);
+ if (testBundle == null)
+ throw new IllegalArgumentException("Bundle with ID [" + id + "] not found");
+
+ Bundle originBundle = originBundleOfClass(className, bundleContext, testBundle);
+ if (originBundle !=null) {
+ result.put(testBundle, originBundle);
+ }
+ } else {
+ ServiceReference reference = bundleContext.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(reference);
+ Bundle[] bundles = packageAdmin.getBundles(bundle, null);
+ if (bundles == null)
+ throw new IllegalArgumentException("Bundle with symbolic name [" + bundle + "] not found");
+
+ for (Bundle testBundle : bundles) {
+ Bundle originBundle = originBundleOfClass(className, bundleContext, testBundle);
+ if (originBundle !=null) {
+ result.put(testBundle, originBundle);
+ }
+ }
+ }
+
+ return result;
+ }
+
+} \ No newline at end of file
diff --git a/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/internal/commands/classloading/ClassLoadingCommandProvider.java b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/internal/commands/classloading/ClassLoadingCommandProvider.java
new file mode 100644
index 0000000..2d5b456
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgicommand/src/main/java/org/eclipse/virgo/kernel/osgicommand/internal/commands/classloading/ClassLoadingCommandProvider.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ *******************************************************************************/
+package org.eclipse.virgo.kernel.osgicommand.internal.commands.classloading;
+
+import org.eclipse.osgi.framework.console.CommandInterpreter;
+import org.eclipse.osgi.framework.console.CommandProvider;
+import org.eclipse.virgo.kernel.osgicommand.helper.ClassLoadingHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+/**
+ * Class loading commands for supportability and diagnostics
+ *
+ * @author Hristo Spaschev Iliev
+ * @version 1.0
+ */
+public class ClassLoadingCommandProvider implements CommandProvider {
+ public static final String NEW_LINE = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ private BundleContext bundleContext;
+
+ public ClassLoadingCommandProvider(BundleContext context) {
+ this.bundleContext = context;
+ }
+
+ /**
+ * Lists all bundles that contain a class
+ *
+ * @param interpreter CommandInterpreter instance
+ */
+ public void _clhas(CommandInterpreter interpreter) {
+ String className = interpreter.nextArgument();
+ if (className == null) {
+ interpreter.println("No class name specified");
+ return;
+ }
+
+ HashMap<Bundle, Bundle> foundBundles = ClassLoadingHelper.getBundlesLoadingClass(bundleContext, className);
+ if (foundBundles.size() == 0) {
+ interpreter.println("No bundle contains class [" + className + "]");
+ return;
+ }
+
+ // build a set with all bundles that contain the class, eliminating repeating ones
+ HashSet<Bundle> uniqueBundles = new HashSet<Bundle>(foundBundles.values());
+
+ // build output map
+ HashMap<Long, String> outputBundles = new HashMap<Long, String>();
+ for (Bundle bundle : uniqueBundles) {
+ outputBundles.put(bundle.getBundleId(), bundle.getSymbolicName());
+ }
+
+ outputFoundBundles(interpreter, "Bundles containing [" + className + "]:", outputBundles);
+ }
+
+ /**
+ * Lists all bundles that can load a class
+ *
+ * @param interpreter CommandInterpreter instance
+ */
+ public void _clload(CommandInterpreter interpreter) {
+ String className = interpreter.nextArgument();
+ if (className == null) {
+ interpreter.println("No class name specified");
+ return;
+ }
+ String bundle = interpreter.nextArgument();
+
+ HashMap<Bundle, Bundle> foundBundles;
+ if (bundle == null) {
+ foundBundles = ClassLoadingHelper.getBundlesLoadingClass(bundleContext, className);
+ } else {
+ foundBundles = ClassLoadingHelper.getBundlesLoadingClass(bundleContext, className, bundle);
+ }
+
+ if (foundBundles.size() == 0) {
+ if (bundle == null) {
+ interpreter.println("No bundle can load class [" + className + "]");
+ } else {
+ interpreter.println("Bundle [" + bundle + "] cannot load class [" + className + "]");
+ }
+ return;
+ }
+
+ outputFoundBundlesAndRelations(interpreter, "Successfully loaded [" + className + "] " + ((bundle != null) ? "using class loader from:" : "from:"), foundBundles, "exported by");
+ }
+
+ /**
+ * Lists all bundles that export a class
+ *
+ * @param interpreter CommandInterpreter instance
+ */
+ public void _clexport(CommandInterpreter interpreter) {
+ String className = interpreter.nextArgument();
+ if (className == null) {
+ interpreter.println("No class name specified");
+ return;
+ }
+
+ // Check if the class has a package
+ int index = className.lastIndexOf(".");
+ if (index == -1) {
+ interpreter.println("The class name [" + className + "] contains no package");
+ return;
+ }
+ String classPackage = className.substring(0, index);
+
+ Bundle[] bundles = bundleContext.getBundles();
+ HashMap<Long, String> foundBundles = new HashMap<Long, String>();
+ for (Bundle bundle : bundles) {
+ if (ClassLoadingHelper.isPackageExported(bundleContext, classPackage, bundle)) {
+ if (ClassLoadingHelper.tryToLoadClass(className, bundle) != null) {
+ foundBundles.put(bundle.getBundleId(), bundle.getSymbolicName());
+ } else {
+ foundBundles.put(bundle.getBundleId(), bundle.getSymbolicName() + " [class not found, package only]");
+ }
+ }
+ }
+
+ if (foundBundles.size() == 0) {
+ interpreter.println("No bundle exports class [" + className + "]");
+ return;
+ }
+
+ outputFoundBundles(interpreter, "Bundles exporting [" + className + "]:", foundBundles);
+ }
+
+ /**
+ * Outputs a list with all found bundles
+ *
+ * @param interpreter CommandInterpreter instance for output to the console
+ * @param message Message to print before the list
+ * @param foundBundles A map with ID and bundle details
+ */
+ private void outputFoundBundles(CommandInterpreter interpreter, String message, HashMap<Long, String> foundBundles) {
+ interpreter.println();
+ interpreter.println(message);
+ for (Map.Entry<Long, String> entry : foundBundles.entrySet()) {
+ interpreter.println(" " + entry.getKey() + "\t" + entry.getValue());
+ }
+ }
+
+ /**
+ * Outputs a list with all found bundles
+ *
+ * @param interpreter CommandInterpreter instance for output to the console
+ * @param message Message to print before the list
+ * @param foundBundles A map with ID and bundle details
+ * @param relation Relation between the bundles
+ */
+ private void outputFoundBundlesAndRelations(CommandInterpreter interpreter, String message, HashMap<Bundle, Bundle> foundBundles, String relation) {
+ interpreter.println();
+ interpreter.println(message);
+ for (Map.Entry<Bundle, Bundle> entry : foundBundles.entrySet()) {
+ Bundle testBundle = entry.getKey();
+ Bundle originalBundle = entry.getValue();
+ if (testBundle.equals(originalBundle)) {
+ interpreter.println(" " + testBundle.getBundleId() + "\t" + testBundle.getSymbolicName());
+ } else {
+ interpreter.println(" " + testBundle.getBundleId() + "\t" + testBundle.getSymbolicName());
+ if (relation != null)
+ interpreter.println(" " + "\t\t[" + relation + " " + originalBundle.getBundleId() + " " + originalBundle.getSymbolicName() + "]");
+ }
+ }
+ }
+
+ public String getHelp() {
+ StringBuffer help = new StringBuffer();
+ help.append("---");
+ help.append("Classloading Commands");
+ help.append("---");
+ help.append(NEW_LINE);
+ help.append("\tclhas <class name> - lists all bundles that contain a class with the specified name.").append(NEW_LINE);
+ help.append("\tclload <class name> [<bundle id> | <bundle name>]- lists all bundles that can load a class or tries to load the class with specified bundle.").append(NEW_LINE);
+ help.append("\tclexport <class name> - lists all bundles that export a class with the specified name.").append(NEW_LINE);
+ return help.toString();
+ }
+
+}
+
diff --git a/org.eclipse.virgo.kernel.osgicommand/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelperTests.java b/org.eclipse.virgo.kernel.osgicommand/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelperTests.java
new file mode 100644
index 0000000..7780a8e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgicommand/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/ClassLoadingHelperTests.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ ******************************************************************************/
+package org.eclipse.virgo.kernel.osgicommand.helper;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+import org.eclipse.osgi.service.resolver.State;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Class for unit testing {@link ClassLoadingHelper}
+ */
+public class ClassLoadingHelperTests {
+
+ private static final long BUNDLE_ID = 1234;
+ private static final String BUNDLE_SYMBOLIC_NAME = "test";
+ private static final String CLASS_NAME = ClassLoadingHelperTests.class.getName();
+ private static final String CLASS_PACKAGE = ClassLoadingHelperTests.class.getPackage().getName();
+
+ @Test
+ public void testIsMissingPackageExported() throws Exception {
+ PlatformAdmin platformAdmin = createMock(PlatformAdmin.class);
+ ServiceReference platformAdminServiceReference = createMock(ServiceReference.class);
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+ State bundleState = createMock(State.class);
+ BundleDescription bundleDescription = createMock(BundleDescription.class);
+
+ expect(bundle.getBundleId()).andReturn(BUNDLE_ID);
+ expect(bundleContext.getServiceReference(PlatformAdmin.class.getName())).andReturn(platformAdminServiceReference);
+ expect(bundleContext.getService(platformAdminServiceReference)).andReturn(platformAdmin);
+ expect(bundleDescription.getSelectedExports()).andReturn(new ExportPackageDescription[0]);
+ expect(platformAdmin.getState(false)).andReturn(bundleState);
+ expect(bundleState.getBundle(BUNDLE_ID)).andReturn(bundleDescription);
+
+ replay(platformAdmin, platformAdminServiceReference, bundle, bundleContext, bundleState, bundleDescription);
+
+ assertFalse("Class [" + CLASS_NAME + "] is reported as exported, while it is NOT",
+ ClassLoadingHelper.isPackageExported(bundleContext, CLASS_NAME, bundle));
+
+ verify(platformAdmin, platformAdminServiceReference, bundle, bundleContext, bundleState, bundleDescription);
+ }
+
+ @Test
+ public void testIsExistingPackageExported() throws Exception {
+ PlatformAdmin platformAdmin = createMock(PlatformAdmin.class);
+ ServiceReference platformAdminServiceReference = createMock(ServiceReference.class);
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+ State bundleState = createMock(State.class);
+ BundleDescription bundleDescription = createMock(BundleDescription.class);
+ ExportPackageDescription exportPackageDescription = createMock(ExportPackageDescription.class);
+
+ expect(bundle.getBundleId()).andReturn(BUNDLE_ID);
+ expect(bundleContext.getServiceReference(PlatformAdmin.class.getName())).andReturn(platformAdminServiceReference);
+ expect(bundleContext.getService(platformAdminServiceReference)).andReturn(platformAdmin);
+ expect(exportPackageDescription.getName()).andReturn(CLASS_PACKAGE);
+ expect(bundleDescription.getSelectedExports()).andReturn(new ExportPackageDescription[]{exportPackageDescription});
+ expect(platformAdmin.getState(false)).andReturn(bundleState);
+ expect(bundleState.getBundle(BUNDLE_ID)).andReturn(bundleDescription);
+
+ replay(platformAdmin, platformAdminServiceReference,
+ bundle, bundleContext, bundleState, bundleDescription,
+ exportPackageDescription);
+
+ assertTrue("Class [" + CLASS_NAME + "] is reported as NOT exported, while it is",
+ ClassLoadingHelper.isPackageExported(bundleContext, CLASS_PACKAGE, bundle));
+
+ verify(platformAdmin, platformAdminServiceReference, bundle, bundleContext, bundleState, bundleDescription);
+ }
+
+ @Test
+ public void testTryToLoadMissingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(null); // missing class
+
+ replay(bundle);
+
+ assertNull("Class [" + CLASS_NAME + "] found, while it is not existing",
+ ClassLoadingHelper.tryToLoadClass(CLASS_NAME, bundle));
+
+ verify(bundle);
+ }
+
+ @Test
+ public void testTryToLoadExistingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(ClassLoadingHelperTests.class);
+
+ replay(bundle);
+
+ assertNotNull("Class [" + CLASS_NAME + "] not found",
+ ClassLoadingHelper.tryToLoadClass(CLASS_NAME, bundle));
+
+ verify(bundle);
+ }
+
+ @Test
+ public void testGetBundlesLoadingMissingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(null); // missing class
+ expect(bundleContext.getBundles()).andReturn(new Bundle[]{bundle});
+
+ replay(bundle, bundleContext);
+
+ assertTrue("The bundle [" + BUNDLE_SYMBOLIC_NAME + "] should NOT be able to load class [" + CLASS_NAME + "]",
+ ClassLoadingHelper.getBundlesLoadingClass(bundleContext, CLASS_NAME).size() == 0);
+
+ verify(bundle, bundleContext);
+ }
+
+ @Test
+ public void testGetBundlesLoadingExistingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(ClassLoadingHelperTests.class);
+ expect(bundleContext.getBundles()).andReturn(new Bundle[]{bundle});
+ expect(bundleContext.getBundle(0)).andReturn(bundle);
+
+ replay(bundle, bundleContext);
+
+ assertFalse("The bundle [" + BUNDLE_SYMBOLIC_NAME + "] should be able to load class [" + CLASS_NAME + "]",
+ ClassLoadingHelper.getBundlesLoadingClass(bundleContext, CLASS_NAME).size() == 0);
+
+ verify(bundle, bundleContext);
+ }
+
+ @Test
+ public void testGetBundleLoadingMissingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+ PackageAdmin packageAdmin = createMock(PackageAdmin.class);
+ ServiceReference packageAdminServiceReference = createMock(ServiceReference.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(null); // missing class
+ expect(bundleContext.getServiceReference(PackageAdmin.class.getName())).andReturn(packageAdminServiceReference);
+ expect(bundleContext.getService(packageAdminServiceReference)).andReturn(packageAdmin);
+ expect(packageAdmin.getBundles(BUNDLE_SYMBOLIC_NAME, null)).andReturn(new Bundle[]{bundle});
+
+ replay(bundle, bundleContext, packageAdmin, packageAdminServiceReference);
+
+ assertTrue("No bundle should be able to load class [" + CLASS_NAME + "]",
+ ClassLoadingHelper.getBundlesLoadingClass(bundleContext, CLASS_NAME, BUNDLE_SYMBOLIC_NAME).size() == 0);
+
+ verify(bundle, bundleContext, packageAdmin, packageAdminServiceReference);
+ }
+
+ @Test
+ public void testGetBundleLoadingExistingClass() throws Exception {
+ Bundle bundle = createMock(Bundle.class);
+ BundleContext bundleContext = createMock(BundleContext.class);
+ PackageAdmin packageAdmin = createMock(PackageAdmin.class);
+ ServiceReference packageAdminServiceReference = createMock(ServiceReference.class);
+
+ expect(bundle.loadClass(CLASS_NAME)).andReturn(ClassLoadingHelperTests.class);
+ expect(bundleContext.getBundle(0)).andReturn(bundle);
+ expect(bundleContext.getServiceReference(PackageAdmin.class.getName())).andReturn(packageAdminServiceReference);
+ expect(bundleContext.getService(packageAdminServiceReference)).andReturn(packageAdmin);
+ expect(packageAdmin.getBundles(BUNDLE_SYMBOLIC_NAME, null)).andReturn(new Bundle[]{bundle});
+
+ replay(bundle, bundleContext, packageAdmin, packageAdminServiceReference);
+
+ assertTrue("The class [" + CLASS_NAME + "] should be successfully loaded",
+ ClassLoadingHelper.getBundlesLoadingClass(bundleContext, CLASS_NAME, BUNDLE_SYMBOLIC_NAME).size() != 0);
+
+ verify(bundle, bundleContext, packageAdmin, packageAdminServiceReference);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgicommand/template.mf b/org.eclipse.virgo.kernel.osgicommand/template.mf
index 41fbde5..78d0b28 100644
--- a/org.eclipse.virgo.kernel.osgicommand/template.mf
+++ b/org.eclipse.virgo.kernel.osgicommand/template.mf
@@ -3,13 +3,14 @@ Bundle-ManifestVersion: 2
Bundle-Name: (incubation) Virgo Kernel osgi console command extension
Bundle-SymbolicName: org.eclipse.virgo.kernel.osgicommand
Bundle-Version: 2.1.0
-Excluded-Exports:
- *
Import-Template:
org.eclipse.virgo.kernel.*;version="${version:[=.=.=, =.+1)}",
org.eclipse.virgo.util.*;version="${org.eclipse.virgo.util:[=.=.=, =.+1)}",
org.eclipse.osgi.framework.*;version="0",
+ org.eclipse.osgi.service.resolver.*;version="0",
org.osgi.framework.*;version="0",
org.osgi.service.*;version="0"
+Export-Template:
+ org.eclipse.virgo.kernel.osgicommand.helper.*;version="${version}"
Bundle-Activator: org.eclipse.virgo.kernel.osgicommand.Activator
diff --git a/org.eclipse.virgo.kernel.test/.classpath b/org.eclipse.virgo.kernel.test/.classpath
index a28c7c0..42c6af8 100644
--- a/org.eclipse.virgo.kernel.test/.classpath
+++ b/org.eclipse.virgo.kernel.test/.classpath
@@ -21,5 +21,6 @@
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.osgi/org.osgi.compendium/4.1.0/org.osgi.compendium-4.1.0.jar"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.parser.manifest/2.1.0.D-20100907105749/org.eclipse.virgo.util.parser.manifest-2.1.0.D-20100907105749.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.parser.manifest/2.1.0.D-20100907105749/org.eclipse.virgo.util.parser.manifest-sources-2.1.0.D-20100907105749.jar"/>
<classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/2.1.0.D-20100907110508/org.eclipse.virgo.medic-2.1.0.D-20100907110508.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/1.0.0.CI-B20/org.eclipse.virgo.medic-sources-1.0.0.CI-B20.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.osgicommand"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
diff --git a/org.eclipse.virgo.kernel.test/ivy.xml b/org.eclipse.virgo.kernel.test/ivy.xml
index e52d58e..34cf7cf 100644
--- a/org.eclipse.virgo.kernel.test/ivy.xml
+++ b/org.eclipse.virgo.kernel.test/ivy.xml
@@ -17,29 +17,39 @@
</publications>
<dependencies>
+ <!-- build -->
+ <dependency org="org.apache.felix" name="org.apache.felix.configadmin" rev="${org.apache.felix}" conf="compile->runtime"/>
+ <dependency org="org.springframework.osgi" name="org.springframework.osgi.core" rev="${org.springframework.osgi}" conf="compile->runtime"/>
+
+ <!-- testing -->
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="${org.easymock}" conf="test->runtime"/>
<dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.dm" rev="latest.integration" conf="test->compile"/>
<dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.core" rev="latest.integration" conf="test->compile"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.shell" rev="latest.integration" conf="test->runtime"/>
+<!-- <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.osgicommand" rev="latest.integration" conf="test->compile"/>-->
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.osgicommand" rev="latest.integration" conf="test->runtime"/>
+
+ <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.core" rev="${org.eclipse.virgo.medic}" conf="test->runtime"/>
+
+ <dependency org="org.eclipse.virgo.repository" name="org.eclipse.virgo.repository" rev="${org.eclipse.virgo.repository}" conf="test->runtime"/>
- <dependency org="org.apache.felix" name="org.apache.felix.configadmin" rev="${org.apache.felix}" conf="compile->runtime"/>
<dependency org="org.eclipse.virgo.test" name="org.eclipse.virgo.test.framework" rev="${org.eclipse.virgo.test}" conf="test->runtime"/>
- <dependency org="org.springframework.osgi" name="org.springframework.osgi.core" rev="${org.springframework.osgi}" conf="compile->runtime"/>
+
<dependency org="org.eclipse.virgo.osgi" name="org.eclipse.virgo.osgi.launcher" rev="${org.eclipse.virgo.osgi}" conf="test->runtime"/>
<dependency org="org.eclipse.virgo.osgi" name="org.eclipse.virgo.osgi.extensions.equinox" rev="${org.eclipse.virgo.osgi}" conf="test->runtime"/>
+
<dependency org="org.slf4j" name="com.springsource.slf4j.nop" rev="${org.slf4j}" conf="test->runtime"/>
<dependency org="org.slf4j" name="com.springsource.slf4j.org.apache.commons.logging" rev="${org.slf4j}" conf="test->runtime"/>
- <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic.core" rev="${org.eclipse.virgo.medic}" conf="test->runtime"/>
- <dependency org="org.eclipse.virgo.repository" name="org.eclipse.virgo.repository" rev="${org.eclipse.virgo.repository}" conf="test->runtime"/>
<!-- Prevent Xerces from being on the classpath to work around Java bug 6723276 during integration testing -->
<exclude org="org.apache.xerces"/>
- <override org="org.springframework" rev="${org.springframework}"/>
- <override org="org.eclipse.virgo.osgi" rev="${org.eclipse.virgo.osgi}"/>
- <override org="org.eclipse.virgo.util" rev="${org.eclipse.virgo.util}"/>
- <override org="org.eclipse.osgi" module="org.eclipse.osgi" rev="${org.eclipse.osgi}"/>
+<!-- <override org="org.springframework" rev="${org.springframework}"/>-->
+<!-- <override org="org.eclipse.virgo.osgi" rev="${org.eclipse.virgo.osgi}"/>-->
+<!-- <override org="org.eclipse.virgo.util" rev="${org.eclipse.virgo.util}"/>-->
+<!-- <override org="org.eclipse.osgi" module="org.eclipse.osgi" rev="${org.eclipse.osgi}"/>-->
</dependencies>
diff --git a/org.eclipse.virgo.kernel.test/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/test/ClassLoadingHelperIntegrationTests.java b/org.eclipse.virgo.kernel.test/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/test/ClassLoadingHelperIntegrationTests.java
new file mode 100644
index 0000000..4b5f6d4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.test/src/test/java/org/eclipse/virgo/kernel/osgicommand/helper/test/ClassLoadingHelperIntegrationTests.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ *******************************************************************************/
+package org.eclipse.virgo.kernel.osgicommand.helper.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.eclipse.virgo.kernel.osgicommand.helper.ClassLoadingHelper;
+import org.eclipse.virgo.kernel.test.AbstractKernelIntegrationTest;
+import org.eclipse.virgo.test.framework.dmkernel.DmKernelTestRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Class for integration testing {@link org.eclipse.virgo.kernel.osgicommand.helper.ClassLoadingHelper}
+ */
+@RunWith(DmKernelTestRunner.class)
+public class ClassLoadingHelperIntegrationTests extends AbstractKernelIntegrationTest {
+ private static final String SHELL_COMMANDS_BUNDLE_NAME = "org.eclipse.virgo.kernel.osgicommand";
+ private static final String CLASSLOADING_PACKAGE = "org.eclipse.virgo.kernel.osgicommand.helper";
+ private static final String TEST_CLASS_NAME = ClassLoadingHelperIntegrationTests.class.getName();
+ private static final String TEST_CLASS_PACKAGE = ClassLoadingHelperIntegrationTests.class.getPackage().getName();
+ private final String FRAMEWORK_CLASS_PACKAGE = BundleContext.class.getPackage().getName();
+ private final String FRAMEWORK_CLASS_NAME = BundleContext.class.getName();
+
+ private Bundle currentBundle = null;
+ private Bundle shellCommandsBundle = null;
+ private Bundle systemBundle = null;
+
+ private final String UNEXPORTED_ERROR_MESSAGE = "Package [%s] is reported as exported by [%s] with id [%s], but it is not";
+ private final String EXPORTED_ERROR_MESSAGE = "Package [%s] is reported as not exported by [%s] with id [%s], but it is";
+ private final String LOADED = "Class [%s] was loaded by by bundle [%s] with id [%s], but it should be available only in [%s]";
+ private final String NOT_LOADED = "Class [%s] was not loaded from bundle [%s] with id [%s]";
+
+ @Before
+ public void setUp() throws Exception {
+ // execute initialization code
+ super.setup();
+
+ // get osgicommand bundle
+ ServiceReference reference = context.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) context.getService(reference);
+ Bundle[] bundles = packageAdmin.getBundles(SHELL_COMMANDS_BUNDLE_NAME, null);
+ assertNotNull("No bundles with symbolic name [" + SHELL_COMMANDS_BUNDLE_NAME + "] found in bundles set " + Arrays.toString(context.getBundles()),
+ bundles);
+ assertTrue("Found [" + bundles.length + "] bundles with symbolic name [" + SHELL_COMMANDS_BUNDLE_NAME + "] in bundles set " + Arrays.toString(context.getBundles()),
+ bundles.length == 1);
+ this.shellCommandsBundle = bundles[0];
+
+ // get this bundle
+ this.currentBundle = context.getBundle();
+
+ // get the system bundle
+ this.systemBundle = context.getBundle(0);
+ }
+
+ @Test
+ public void testIsPackageExportedMethod() throws Exception {
+ // Check which bundles export CLASSLOADING_PACKAGE
+ assertTrue(String.format(EXPORTED_ERROR_MESSAGE, CLASSLOADING_PACKAGE, SHELL_COMMANDS_BUNDLE_NAME, shellCommandsBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, CLASSLOADING_PACKAGE, shellCommandsBundle));
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, CLASSLOADING_PACKAGE, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, CLASSLOADING_PACKAGE, currentBundle));
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, CLASSLOADING_PACKAGE, systemBundle.getSymbolicName(), systemBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, CLASSLOADING_PACKAGE, systemBundle));
+
+ // Check which bundles export CLASSLOADING_TEST_PACKAGE
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, TEST_CLASS_PACKAGE, SHELL_COMMANDS_BUNDLE_NAME, shellCommandsBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, TEST_CLASS_PACKAGE, shellCommandsBundle));
+ assertTrue(String.format(EXPORTED_ERROR_MESSAGE, TEST_CLASS_PACKAGE, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, TEST_CLASS_PACKAGE, currentBundle));
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, TEST_CLASS_PACKAGE, systemBundle.getSymbolicName(), systemBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, TEST_CLASS_PACKAGE, systemBundle));
+ }
+
+ @Test
+ public void testGetBundlesLoadingClassMethod() throws Exception {
+ final String CAN_LOAD_ERROR_MESSAGE = "Bundle [%s] is returned as bundle that can load the test class [%s]. The returned set of bundles is %s";
+ final String CANNOT_LOAD_ERROR_MESSAGE = "Bundle [%s] is not returned as bundle that can load the test class [%s]. The returned set of bundles is %s";
+ final String ORIGINATING_ERROR_MESSAGE = "Bundle [%s] is returned as originating bundle for class [%s]. The returned set of bundles is %s";
+ final String NON_ORIGINATING_ERROR_MESSAGE = "Bundle [%s] is not returned as originating bundle for class [%s]. The returned set of bundles is %s";
+
+ // Check which bundles can load this class
+ HashMap<Bundle, Bundle> result = ClassLoadingHelper.getBundlesLoadingClass(context, TEST_CLASS_NAME);
+ assertFalse(String.format(CAN_LOAD_ERROR_MESSAGE, SHELL_COMMANDS_BUNDLE_NAME, TEST_CLASS_NAME, Arrays.toString(result.keySet().toArray())),
+ result.containsKey(shellCommandsBundle));
+ assertFalse(String.format(ORIGINATING_ERROR_MESSAGE, SHELL_COMMANDS_BUNDLE_NAME, TEST_CLASS_NAME, Arrays.toString(result.values().toArray())),
+ result.containsValue(shellCommandsBundle));
+ assertTrue(String.format(CANNOT_LOAD_ERROR_MESSAGE, currentBundle.getSymbolicName(), TEST_CLASS_NAME, Arrays.toString(result.keySet().toArray())),
+ result.containsKey(currentBundle));
+ assertTrue(String.format(NON_ORIGINATING_ERROR_MESSAGE, currentBundle.getSymbolicName(), TEST_CLASS_NAME, Arrays.toString(result.values().toArray())),
+ result.containsValue(currentBundle));
+
+ // Check how osgicommand bundle can load BundleContext
+ result = ClassLoadingHelper.getBundlesLoadingClass(context, FRAMEWORK_CLASS_NAME, SHELL_COMMANDS_BUNDLE_NAME);
+ assertTrue(String.format(CANNOT_LOAD_ERROR_MESSAGE, SHELL_COMMANDS_BUNDLE_NAME, FRAMEWORK_CLASS_NAME, Arrays.toString(result.keySet().toArray())),
+ result.containsKey(shellCommandsBundle));
+ assertTrue(String.format(NON_ORIGINATING_ERROR_MESSAGE, systemBundle.getSymbolicName(), FRAMEWORK_CLASS_NAME, Arrays.toString(result.values().toArray())),
+ result.containsValue(systemBundle));
+ }
+
+ @Test
+ public void testTryToLoadClassMethod() throws Exception {
+ assertNotNull(String.format(NOT_LOADED, TEST_CLASS_NAME, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.tryToLoadClass(TEST_CLASS_NAME, currentBundle));
+ assertNull(String.format(LOADED, TEST_CLASS_NAME, SHELL_COMMANDS_BUNDLE_NAME, shellCommandsBundle.getBundleId(), currentBundle.getSymbolicName()),
+ ClassLoadingHelper.tryToLoadClass(TEST_CLASS_NAME, shellCommandsBundle));
+ }
+
+ @Test
+ public void testExportAndLoad() throws Exception {
+ // Check TEST_CLASS_* export and load
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, TEST_CLASS_PACKAGE, shellCommandsBundle.getSymbolicName(), shellCommandsBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, TEST_CLASS_PACKAGE, shellCommandsBundle));
+ assertNull(String.format(LOADED, TEST_CLASS_NAME, SHELL_COMMANDS_BUNDLE_NAME, shellCommandsBundle.getBundleId(), SHELL_COMMANDS_BUNDLE_NAME),
+ ClassLoadingHelper.tryToLoadClass(TEST_CLASS_NAME, shellCommandsBundle));
+ assertTrue(String.format(EXPORTED_ERROR_MESSAGE, TEST_CLASS_PACKAGE, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, TEST_CLASS_PACKAGE, currentBundle));
+ assertNotNull(String.format(NOT_LOADED, TEST_CLASS_NAME, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.tryToLoadClass(TEST_CLASS_NAME, currentBundle));
+
+ // Check FRAMEWORK_CLASS_* export and load
+ assertFalse(String.format(UNEXPORTED_ERROR_MESSAGE, FRAMEWORK_CLASS_PACKAGE, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, FRAMEWORK_CLASS_PACKAGE, currentBundle));
+ assertNotNull(String.format(NOT_LOADED, FRAMEWORK_CLASS_NAME, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.tryToLoadClass(FRAMEWORK_CLASS_NAME, currentBundle));
+ assertTrue(String.format(EXPORTED_ERROR_MESSAGE, FRAMEWORK_CLASS_PACKAGE, systemBundle.getSymbolicName(), systemBundle.getBundleId()),
+ ClassLoadingHelper.isPackageExported(context, FRAMEWORK_CLASS_PACKAGE, systemBundle));
+ assertNotNull(String.format(NOT_LOADED, FRAMEWORK_CLASS_NAME, currentBundle.getSymbolicName(), currentBundle.getBundleId()),
+ ClassLoadingHelper.tryToLoadClass(FRAMEWORK_CLASS_NAME, systemBundle));
+ }
+}
+
diff --git a/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/MANIFEST.MF
index b8639a4..302c794 100644
--- a/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/MANIFEST.MF
@@ -3,7 +3,8 @@ Export-Package: org.eclipse.virgo.kernel.osgi.test;version="2.1.0";uses:="org.ec
org.eclipse.virgo.kernel.concurrent.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.core,org.eclipse.virgo.kernel.test,org.junit",
org.eclipse.virgo.kernel.dm.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.test,org.junit",
org.eclipse.virgo.kernel.ffdc.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.test,org.junit",
- org.eclipse.virgo.kernel.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.core,org.junit,org.junit.runner"
+ org.eclipse.virgo.kernel.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.core,org.junit,org.junit.runner",
+ org.eclipse.virgo.kernel.osgicommand.helper.test;version="2.1.0";uses:="org.eclipse.virgo.kernel.core,org.junit,org.junit.runner"
Bundle-Version: 2.1.0
Tool: Bundlor not used
Bundle-Name: (incubation) Virgo Kernel Test
@@ -12,6 +13,7 @@ Bundle-SymbolicName: org.eclipse.virgo.kernel.test
Import-Package: org.eclipse.virgo.kernel.osgi.framework;version="[2.1.0,2.2.0)",
org.eclipse.virgo.kernel.osgi.quasi;version="[2.1.0,2.2.0)",
org.eclipse.virgo.kernel.osgi.region;version="[2.1.0,2.2.0)",
+ org.eclipse.virgo.kernel.osgicommand.helper;version="[2.1.0,2.2.0)",
javax.management;version=0,
org.eclipse.virgo.kernel.core;version="[2.1.0,2.2.0)",
org.eclipse.virgo.kernel.deployer.core;version="[2.1.0,2.2.0)",
@@ -21,6 +23,7 @@ Import-Package: org.eclipse.virgo.kernel.osgi.framework;version="[2.1.0,2.2.0)",
org.junit.runner;version="[4.5.0,5)",
org.osgi.framework;version=0,
org.osgi.service.framework;version=0,
+ org.osgi.service.packageadmin;version=0,
org.springframework.context;version="[2.5.6,3.1)",
org.springframework.osgi.context.support;version="[1.2.1,2)",
org.springframework.osgi.service.importer.support;version="[1.2.1,2)"
diff --git a/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/test.config.properties b/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/test.config.properties
index 2b6cc8e..7ab32c5 100644
--- a/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/test.config.properties
+++ b/org.eclipse.virgo.kernel.test/src/test/resources/META-INF/test.config.properties
@@ -34,7 +34,8 @@ launcher.bundles =\
file:../org.eclipse.virgo.kernel.dm/target/classes@start,\
file:../org.eclipse.virgo.kernel.model/target/classes@start,\
file:../org.eclipse.virgo.kernel.kerneldmfragment/target/classes,\
- file:../org.eclipse.virgo.kernel.shell/target/classes@start
+ file:../org.eclipse.virgo.kernel.shell/target/classes@start,\
+ file:../org.eclipse.virgo.kernel.osgicommand/target/classes@start
org.eclipse.virgo.test.properties.include=file:../build.versions,file:../build.properties