diff options
6 files changed, 175 insertions, 5 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java index 5991c9880..f49b085a0 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java @@ -15,6 +15,7 @@ import java.net.URL; import java.util.*; import org.eclipse.osgi.container.*; import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory; +import org.eclipse.osgi.service.debug.DebugOptions; import org.eclipse.osgi.tests.container.dummys.*; import org.eclipse.osgi.util.ManifestElement; import org.junit.*; @@ -48,6 +49,10 @@ public abstract class AbstractTest { return new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.<String, String> emptyMap(), new DummyResolverHookFactory(hook)); } + protected DummyContainerAdaptor createDummyAdaptor(DebugOptions debugOptions) { + return new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.<String, String> emptyMap(), new DummyResolverHookFactory(), debugOptions); + } + protected Bundle getBundle() { return ((BundleReference) getClass().getClassLoader()).getBundle(); } diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java index cc4c2756c..2981cdb99 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java @@ -20,6 +20,7 @@ import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent; import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent; import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory; import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace; +import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.report.resolution.ResolutionReport; import org.eclipse.osgi.tests.container.dummys.*; import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyContainerEvent; @@ -1560,6 +1561,42 @@ public class TestModuleContainer extends AbstractTest { Assert.assertEquals("c should not resolve.", State.INSTALLED, uses_c.getState()); } + @Test + public void testUses1Dynamic() throws BundleException, IOException { + DummyContainerAdaptor adaptor = createDummyAdaptor(new DummyDebugOptions(Collections.singletonMap("org.eclipse.osgi/resolver/report", "true"))); + ModuleContainer container = adaptor.getContainer(); + + Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container); + + container.resolve(Arrays.asList(systemBundle), true); + Module uses_a = installDummyModule("uses.a.MF", "a", container); + Module uses_b = installDummyModule("uses.b.MF", "b", container); + Module uses_c_dynamic = installDummyModule("uses.c.dynamic.MF", "c", container); + + container.resolve(null, false); + + Assert.assertEquals("a should resolve.", State.RESOLVED, uses_a.getState()); + Assert.assertEquals("b should resolve.", State.RESOLVED, uses_b.getState()); + Assert.assertEquals("c should resolve.", State.RESOLVED, uses_c_dynamic.getState()); + + ModuleWire dynamicWire = container.resolveDynamic("uses1", uses_c_dynamic.getCurrentRevision()); + Assert.assertNotNull("No dynamic wire.", dynamicWire); + + PrintStream originalOut = Debug.out; + ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); + PrintStream testOut = new PrintStream(bytesOut); + Debug.out = testOut; + try { + dynamicWire = container.resolveDynamic("uses2", uses_c_dynamic.getCurrentRevision()); + Assert.assertNull("Dynamic wire found.", dynamicWire); + } finally { + Debug.out = originalOut; + testOut.close(); + } + String traceOutput = bytesOut.toString(); + Assert.assertTrue("Wrong traceOutput: " + traceOutput, traceOutput.startsWith("org.osgi.service.resolver.ResolutionException")); + } + /* * Test that split packages are handled ok with uses constraints */ diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java index 07dc9e89e..4d91c7db6 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 IBM Corporation and others. + * Copyright (c) 2012, 2015 IBM Corporation and others. * 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 @@ -10,13 +10,13 @@ *******************************************************************************/ package org.eclipse.osgi.tests.container.dummys; -import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyContainerEvent; -import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent; - import java.util.EnumSet; import java.util.Map; import org.eclipse.osgi.container.*; import org.eclipse.osgi.container.Module.Settings; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyContainerEvent; +import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent; import org.osgi.framework.FrameworkListener; import org.osgi.framework.hooks.resolver.ResolverHookFactory; @@ -26,16 +26,22 @@ public class DummyContainerAdaptor extends ModuleContainerAdaptor { private final DummyModuleDatabase moduleDatabase; private final ModuleContainer container; private final ResolverHookFactory resolverHookFactory; + private final DebugOptions debugOptions; public DummyContainerAdaptor(ModuleCollisionHook collisionHook, Map<String, String> configuration) { this(collisionHook, configuration, new DummyResolverHookFactory()); } public DummyContainerAdaptor(ModuleCollisionHook collisionHook, Map<String, String> configuration, ResolverHookFactory resolverHookFactory) { + this(collisionHook, configuration, resolverHookFactory, null); + } + + public DummyContainerAdaptor(ModuleCollisionHook collisionHook, Map<String, String> configuration, ResolverHookFactory resolverHookFactory, DebugOptions debugOptions) { this.collisionHook = collisionHook; this.configuration = configuration; this.resolverHookFactory = resolverHookFactory; this.moduleDatabase = new DummyModuleDatabase(this); + this.debugOptions = debugOptions; this.container = new ModuleContainer(this, moduleDatabase); } @@ -82,4 +88,10 @@ public class DummyContainerAdaptor extends ModuleContainerAdaptor { public void publishModuleEvent(ModuleEvent type, Module module, Module origin) { moduleDatabase.addEvent(new DummyModuleEvent(module, type, module.getState())); } + + @Override + public DebugOptions getDebugOptions() { + return this.debugOptions; + } + } diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyDebugOptions.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyDebugOptions.java new file mode 100755 index 000000000..debf78496 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyDebugOptions.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2015 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.tests.container.dummys; + +import java.io.File; +import java.util.Map; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.osgi.service.debug.DebugTrace; + +public class DummyDebugOptions implements DebugOptions { + private final Map<String, String> options; + + public DummyDebugOptions(Map<String, String> options) { + this.options = options; + } + + @Override + public boolean getBooleanOption(String option, boolean defaultValue) { + String value = options.get(option); + return value == null ? defaultValue : Boolean.parseBoolean(value); + } + + @Override + public String getOption(String option) { + return options.get(option); + } + + @Override + public String getOption(String option, String defaultValue) { + String value = options.get(option); + return value == null ? defaultValue : value; + } + + @Override + public int getIntegerOption(String option, int defaultValue) { + String value = options.get(option); + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + @Override + public Map<String, String> getOptions() { + return options; + } + + @Override + public void setOption(String option, String value) { + options.put(option, value); + } + + @Override + public void setOptions(Map<String, String> options) { + this.options.clear(); + this.options.putAll(options); + } + + @Override + public void removeOption(String option) { + this.options.remove(option); + } + + @Override + public boolean isDebugEnabled() { + return true; + } + + @Override + public void setDebugEnabled(boolean value) { + // nothing + } + + @Override + public void setFile(File newFile) { + // nothing + } + + @Override + public File getFile() { + // nothing + return null; + } + + @Override + public DebugTrace newDebugTrace(String bundleSymbolicName) { + // nothing + return null; + } + + @Override + public DebugTrace newDebugTrace(String bundleSymbolicName, Class<?> traceEntryClass) { + // nothing + return null; + } + +} diff --git a/bundles/org.eclipse.osgi.tests/test_files/containerTests/uses.c.dynamic.MF b/bundles/org.eclipse.osgi.tests/test_files/containerTests/uses.c.dynamic.MF new file mode 100755 index 000000000..b880d65a0 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/test_files/containerTests/uses.c.dynamic.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: uses.c +Bundle-Version: 1.0 +DynamicImport-Package: + uses1; version="[1.0,2.0)", + uses2; version="[2.0,3.0)" diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java index a3bec344f..cbde0281c 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java @@ -20,7 +20,7 @@ import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.internal.framework.EquinoxContainer; import org.eclipse.osgi.internal.messages.Msg; -import org.eclipse.osgi.report.resolution.*; +import org.eclipse.osgi.report.resolution.ResolutionReport; import org.eclipse.osgi.report.resolution.ResolutionReport.Entry; import org.eclipse.osgi.report.resolution.ResolutionReport.Entry.Type; import org.eclipse.osgi.service.debug.DebugOptions; @@ -900,6 +900,9 @@ final class ModuleResolver { } report = reportBuilder.build(result, re); if (DEBUG_REPORT) { + if (report.getResolutionException() != null) { + Debug.printStackTrace(report.getResolutionException()); + } Set<Resource> resources = report.getEntries().keySet(); if (!resources.isEmpty()) { Debug.println("RESOLVER: Resolution report"); //$NON-NLS-1$ |