diff options
author | Thomas Watson | 2020-07-01 14:35:27 +0000 |
---|---|---|
committer | Thomas Watson | 2020-07-01 15:45:10 +0000 |
commit | d5a30b98485696d2234fef700bc2eaacdaacd599 (patch) | |
tree | 273c85b5663b7f60e0a7c2781d8055d5da715ae4 | |
parent | 6963810c21497ddd03f14a02241ec807fdc5441b (diff) | |
download | rt.equinox.framework-d5a30b98485696d2234fef700bc2eaacdaacd599.tar.gz rt.equinox.framework-d5a30b98485696d2234fef700bc2eaacdaacd599.tar.xz rt.equinox.framework-d5a30b98485696d2234fef700bc2eaacdaacd599.zip |
Bug 417869 - Avoid adding dev class path entries that are dups
There are cases where PDE will add class path to the dev settings which
are duplicate paths specified on the Bundle-ClassPath header. The
DevClassLoadingHook should avoid doing adding the duplicate paths which
the framework will add itself.
Change-Id: Ie069f2bbf137a2de16fe1168d251669843266cb6
4 files changed, 106 insertions, 2 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java index 2c3c875ce..018a04095 100755 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java @@ -2416,7 +2416,8 @@ public class SystemBundleTests extends AbstractBundleTests { return manifest; } - static File createBundle(File outputDir, String bundleName, Map<String, String> headers, Map<String, String>... entries) throws IOException { + public static File createBundle(File outputDir, String bundleName, Map<String, String> headers, + Map<String, String>... entries) throws IOException { Manifest m = new Manifest(); Attributes attributes = m.getMainAttributes(); attributes.putValue("Manifest-Version", "1.0"); diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java index 3e35b9314..6b21ff26a 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2015 IBM Corporation and others. + * Copyright (c) 2013, 2020 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -26,6 +26,7 @@ public class AllFrameworkHookTests { suite.addTest(new TestSuite(DevClassPathWithExtensionTests.class)); suite.addTest(new TestSuite(EmbeddedEquinoxWithURLInClassLoadTests.class)); suite.addTest(new TestSuite(ActivatorOrderTest.class)); + suite.addTest(new TestSuite(DevClassPathDuplicateTests.class)); return suite; } } diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/DevClassPathDuplicateTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/DevClassPathDuplicateTests.java new file mode 100644 index 000000000..ad19f46a7 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/DevClassPathDuplicateTests.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2020 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.tests.hooks.framework; + +import static org.eclipse.osgi.tests.bundles.AbstractBundleTests.stopQuietly; + +import java.io.File; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.osgi.internal.framework.EquinoxConfiguration; +import org.eclipse.osgi.tests.OSGiTestsActivator; +import org.eclipse.osgi.tests.bundles.SystemBundleTests; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; +import org.osgi.framework.launch.Framework; + +public class DevClassPathDuplicateTests extends AbstractFrameworkHookTests { + private Map<String, String> configuration; + private Framework framework; + private String location; + + @Override + protected void setUp() throws Exception { + super.setUp(); + File store = OSGiTestsActivator.getContext().getDataFile(getName()); + configuration = new HashMap<>(); + configuration.put(Constants.FRAMEWORK_STORAGE, store.getAbsolutePath()); + configuration.put(EquinoxConfiguration.PROP_DEV, "duplicate/"); + framework = createFramework(configuration); + + Map<String, String> headers = new HashMap<>(); + headers.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + headers.put(Constants.BUNDLE_SYMBOLICNAME, "b.dup.cp"); + headers.put(Constants.BUNDLE_CLASSPATH, "duplicate/"); + Map<String, String> entries = new HashMap<>(); + entries.put("duplicate/", null); + entries.put("duplicate/resource.txt", "hello"); + File testBundle = SystemBundleTests.createBundle(store, "b.dup.cp", headers, entries); + location = testBundle.toURI().toASCIIString(); + } + + @Override + protected void tearDown() throws Exception { + stopQuietly(framework); + super.tearDown(); + } + + private void initAndStartFramework() throws Exception { + initAndStart(framework); + } + + private Bundle installBundle() throws Exception { + return framework.getBundleContext().installBundle(location); + } + + public void testDevClassPathWithExtension() throws Exception { + initAndStartFramework(); + + Bundle b = installBundle(); + b.start(); + Enumeration<URL> resources = b.getResources("resource.txt"); + assertNotNull("no resources", resources); + int cnt = 0; + while (resources.hasMoreElements()) { + cnt++; + resources.nextElement(); + } + assertEquals("Wrong number of resources.", 1, cnt); + } +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java index 8d26f1fb8..d7ec50bc4 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java @@ -16,6 +16,11 @@ package org.eclipse.osgi.internal.hooks; import java.io.File; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import org.eclipse.osgi.container.ModuleCapability; +import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace; import org.eclipse.osgi.framework.util.KeyedElement; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook; @@ -50,8 +55,22 @@ public class DevClassLoadingHook extends ClassLoaderHook implements KeyedElement // check that dev classpath entries have not already been added; we mark this in the first entry below if (cpEntries.size() > 0 && cpEntries.get(0).getUserObject(KEY) != null) return false; // this source has already had its dev classpath entries added. + + // get the specified classpath from the Bundle-ClassPath header to check for dups + List<ModuleCapability> moduleDatas = sourceGeneration.getRevision().getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE); + @SuppressWarnings("unchecked") + List<String> specifiedCP = Optional.ofNullable(moduleDatas.isEmpty() + ? + null + : (List<String>) moduleDatas.get(0).getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_CLASSPATH)) + .orElse(Collections.singletonList(".")); //$NON-NLS-1$ boolean result = false; for (String devClassPath : devClassPaths) { + if (specifiedCP.contains(devClassPath)) { + // dev properties contained a duplicate of an entry on the Bundle-ClassPath header + // don't add anything, the framework will do it for us + continue; + } if (hostmanager.addClassPathEntry(cpEntries, devClassPath, hostmanager, sourceGeneration)) { result = true; } else { |