/* * 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.geronimo.osgi.registry.itest; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; import org.apache.geronimo.osgi.locator.Activator; import org.apache.geronimo.osgi.locator.ProviderLocator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.CoreOptions; import static org.ops4j.pax.exam.CoreOptions.bundle; import static org.ops4j.pax.exam.CoreOptions.equinox; import static org.ops4j.pax.exam.CoreOptions.felix; import static org.ops4j.pax.exam.CoreOptions.options; import static org.ops4j.pax.exam.CoreOptions.provision; import static org.ops4j.pax.exam.CoreOptions.wrappedBundle; import org.ops4j.pax.exam.Customizer; import org.ops4j.pax.exam.Inject; import org.ops4j.pax.exam.Option; import static org.ops4j.pax.exam.OptionUtils.combine; import org.ops4j.pax.exam.junit.JUnit4TestRunner; import org.ops4j.pax.exam.options.MavenArtifactProvisionOption; import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.*; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @RunWith(JUnit4TestRunner.class) public class OSGiLocatorTest { @Inject protected BundleContext bundleContext; @org.ops4j.pax.exam.junit.Configuration public static Option[] configuration() throws Exception { Option[] options = options( // the target code we're testing... mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-registry"), // bundle containing test resources mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-itesta"), mavenBundle("org.ops4j.pax.logging", "pax-logging-api"), felix(), equinox().version("3.5.0"), // we want to specify an activator for the test probe bundle that // is the standard one for adding the locator service to a spec // bundle. We'll use our activator instance to perform class lookups new Customizer() { @Override public InputStream customizeTestProbe( InputStream testProbe ) throws IOException { return modifyBundle(testProbe) // these two classes need to be in every participating bundle .add(org.apache.geronimo.osgi.locator.Activator.class) .add(org.apache.geronimo.osgi.locator.ProviderLocator.class) // we don't have any direct references to this class, so force it to be // included. .add(org.apache.geronimo.osgi.registry.itest.TestTargetLocal.class) // set the required activator also .set(Constants.BUNDLE_ACTIVATOR, org.apache.geronimo.osgi.locator.Activator.class.getName()) // we need an import for activator to function properly. .set(Constants.IMPORT_PACKAGE, "org.apache.geronimo.osgi.registry.api") .build(); } } ); options = updateOptions(options); return options; } @Test public void testLocator() throws Exception { Bundle bundle1 = getInstalledBundle("org.apache.geronimo.specs.geronimo-osgi-itesta"); // check for the target class a verify we got the correct one Class<?> target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.TestTarget"); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", target.getName()); List<Class<?>> targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.itest.TestTarget"); // should return one entry and it should be the same class mapping assertEquals(1, targets.size()); assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", targets.get(0).getName()); // now load the second target interface. This is really the same as the first, but // uses a different commenting style. target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.TestTarget2"); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTargetTwo", target.getName()); targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.itest.TestTarget2"); // should return one entry and it should be the same class mapping assertEquals(1, targets.size()); assertEquals("org.apache.geronimo.osgi.itesta.TestTargetTwo", targets.get(0).getName()); // this class is defined using the header form. It should map back to itself. target = ProviderLocator.locate("org.apache.geronimo.osgi.itesta.TestTarget2"); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", target.getName()); targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.itesta.TestTarget2"); // should return one entry and it should be the same class mapping assertEquals(1, targets.size()); assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", targets.get(0).getName()); // This is not in the provider registry, so it should just return null. target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.ClassNotFound"); assertNull(target); // This is in the provider registry, but the class cannot be loaded. This should still // return null. target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.NoClass"); assertNull(target); // This is defined as a header, but the class cannot be loaded. This should still // return null. target = ProviderLocator.locate("org.apache.geronimo.osgi.itesta..NoClass"); assertNull(target); // Now test some of the class loading support. This will search the provider registry first, // then the classpath. We should still get the registered class returned. target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass()); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", target.getName()); // similar to the above, but since the context class is not provided, this will fail to resolve the // locally resident class. target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.TestTarget", null); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", target.getName()); // And just a straight load class of a bundle-local class. target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.TestTargetTwo", this.getClass()); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.registry.itest.TestTargetTwo", target.getName()); // this one should be handled from the provider registry and resolve to a class // defined in the test bundle. target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.TestTarget4", this.getClass()); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", target.getName()); // this should not be located at all try { target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.ClassNotFound", this.getClass()); fail("Expected ClassNotFoundException not thrown"); } catch (ClassNotFoundException e) { } // this is in the registry, but there is an error resolving the class try { target = ProviderLocator.loadClass("org.apache.geronimo.osgi.registry.itest.NoClass", this.getClass()); fail("Expected ClassNotFoundException not thrown"); } catch (ClassNotFoundException e) { } // this is defined with a header, but there is an error resolving the class try { target = ProviderLocator.loadClass("org.apache.geronimo.osgi.itesta.NoClass", this.getClass()); fail("Expected ClassNotFoundException not thrown"); } catch (ClassNotFoundException e) { } // this mapping defines multiple classes for the single key. The first should be returned for // a singleton request, the locate all should return in definition order target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.TestTarget4"); assertNotNull(target); // this should return the given class instance assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", target.getName()); targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.itest.TestTarget4"); // should return one entry and it should be the same class mapping assertEquals(2, targets.size()); assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", targets.get(0).getName()); assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", targets.get(1).getName()); // now stop the first bundle, which should shuffle the deck bundle1.stop(); // The returned class should now be null since there are no registered providers target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.TestTarget"); assertNull(target); targets = ProviderLocator.locateAll("org.apache.geronimo.osgi.registry.itest.TestTarget"); // should return an empty list assertNotNull(targets); assertEquals(0, targets.size()); // The returned class should now be null since there are no registered providers target = ProviderLocator.locate("org.apache.geronimo.osgi.itesta.TestTarget2"); assertNull(target); // This is in the provider registry, but the class cannot be loaded. This should still // return null. target = ProviderLocator.locate("org.apache.geronimo.osgi.registry.itest.NoClass"); assertNull(target); } protected Bundle getInstalledBundle(String symbolicName) { for (Bundle b : bundleContext.getBundles()) { if (b.getSymbolicName().equals(symbolicName)) { return b; } } return null; } public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) { return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject(); } protected static Option[] updateOptions(Option[] options) { // We need to add pax-exam-junit here when running with the ibm // jdk to avoid the following exception during the test run: // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration if ("IBM Corporation".equals(System.getProperty("java.vendor"))) { Option[] ibmOptions = options( wrappedBundle(mavenBundle("org.ops4j.pax.exam", "pax-exam-junit")) ); options = combine(ibmOptions, options); } return options; } }