Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2020-07-27 15:26:23 +0000
committerThomas Watson2020-07-27 15:29:12 +0000
commit16056e80642d4dc9708672243c05b3917b764ecd (patch)
treec81caaa5ffe2156a70cbb099df14c6f0c0583d50
parentb09ea5dba4030ea2685ba3e72f05a6c9361839ff (diff)
downloadrt.equinox.framework-I20200731-0520.tar.gz
rt.equinox.framework-I20200731-0520.tar.xz
rt.equinox.framework-I20200731-0520.zip
When searching for a resource that is indexed by a bundle URL the search must not return an entry unless the index properly matches the class path index. This issue is surfaced when taking the external String from a bundle resource URL and creating a new URL from it. Here the index is stored in the port of the URL and it must be validated when searching for the entry when opening the connection to the new URL Change-Id: I74685811c39ba10af2c92851759cd1eb6ffcf339 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java77
-rwxr-xr-xbundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/SystemBundleTests.java26
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java13
3 files changed, 110 insertions, 6 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
index f279c8c3c..516f80c41 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
@@ -14,6 +14,7 @@
package org.eclipse.osgi.tests.bundles;
import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@@ -39,6 +40,8 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -2454,6 +2457,80 @@ public class ClassLoadingBundleTests extends AbstractBundleTests {
assertNull("Found more events.", events.poll(1, TimeUnit.SECONDS));
}
+ public void testBug565522FragmentClasspath() throws IOException, BundleException {
+ ByteArrayOutputStream libResourceJarBytes1 = new ByteArrayOutputStream();
+ try (JarOutputStream libResourceJar = new JarOutputStream(libResourceJarBytes1)) {
+ libResourceJar.putNextEntry(new JarEntry("META-INF/"));
+ libResourceJar.closeEntry();
+ libResourceJar.putNextEntry(new JarEntry("META-INF/services/"));
+ libResourceJar.closeEntry();
+ libResourceJar.putNextEntry(new JarEntry("META-INF/services/some.bundle.Factory"));
+ libResourceJar.write("testFactory1".getBytes());
+ libResourceJar.closeEntry();
+ }
+ ByteArrayOutputStream libResourceJarBytes2 = new ByteArrayOutputStream();
+ try (JarOutputStream libResourceJar = new JarOutputStream(libResourceJarBytes2)) {
+ libResourceJar.putNextEntry(new JarEntry("META-INF/"));
+ libResourceJar.closeEntry();
+ libResourceJar.putNextEntry(new JarEntry("META-INF/services/"));
+ libResourceJar.closeEntry();
+ libResourceJar.putNextEntry(new JarEntry("META-INF/services/some.bundle.Factory"));
+ libResourceJar.write("testFactory2".getBytes());
+ libResourceJar.closeEntry();
+ }
+
+ File outputDir = OSGiTestsActivator.getContext().getDataFile(getName()); // $NON-NLS-1$
+ outputDir.mkdirs();
+
+ Map<String, String> hostHeaders = new HashMap<>();
+ hostHeaders.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ hostHeaders.put(Constants.BUNDLE_SYMBOLICNAME, "host");
+ hostHeaders.put(Constants.BUNDLE_CLASSPATH, "., lib/resource.jar");
+ Map<String, byte[]> hostEntries = new HashMap<>();
+ hostEntries.put("lib/", null);
+ hostEntries.put("lib/resource.jar", libResourceJarBytes1.toByteArray());
+ File hostFile = SystemBundleTests.createBundleWithBytes(outputDir, "host", hostHeaders, hostEntries);
+
+ Map<String, String> fragHeaders = new HashMap<>();
+ fragHeaders.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ fragHeaders.put(Constants.BUNDLE_SYMBOLICNAME, "fragment");
+ fragHeaders.put(Constants.BUNDLE_CLASSPATH, "., lib/resource.jar");
+ fragHeaders.put(Constants.FRAGMENT_HOST, "host");
+ Map<String, byte[]> fragEntries = new HashMap<>();
+ fragEntries.put("lib/", null);
+ fragEntries.put("lib/resource.jar", libResourceJarBytes2.toByteArray());
+ File fragFile = SystemBundleTests.createBundleWithBytes(outputDir, "frag", fragHeaders, fragEntries);
+
+ Bundle host = null, frag = null;
+ try {
+ host = getContext().installBundle(hostFile.toURI().toASCIIString());
+ frag = getContext().installBundle(fragFile.toURI().toASCIIString());
+ host.start();
+ Enumeration<URL> eResources = host.getResources("META-INF/services/some.bundle.Factory");
+ assertNotNull("No resources found.", eResources);
+ List<URL> resources = new ArrayList<>();
+ while (eResources.hasMoreElements()) {
+ resources.add(eResources.nextElement());
+ }
+ assertEquals("Wrong number of resources.", 2, resources.size());
+ assertEquals("Wrong content for resource 1", "testFactory1", readURL(resources.get(0)));
+ assertEquals("Wrong content for resource 2", "testFactory2", readURL(resources.get(1)));
+
+ // round trip the URLs
+ URL copyURL1 = new URL(resources.get(0).toExternalForm());
+ URL copyURL2 = new URL(resources.get(1).toExternalForm());
+ assertEquals("Wrong content for url copy 1", "testFactory1", readURL(copyURL1));
+ assertEquals("Wrong content for url copy 2", "testFactory2", readURL(copyURL2));
+ } finally {
+ if (host != null) {
+ host.uninstall();
+ }
+ if (frag != null) {
+ frag.uninstall();
+ }
+ }
+ }
+
void refreshBundles(Collection<Bundle> bundles) throws InterruptedException {
final CountDownLatch refreshSignal = new CountDownLatch(1);
getContext().getBundle(Constants.SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class).refreshBundles(bundles, new FrameworkListener() {
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 018a04095..b0e9ab909 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
@@ -2442,6 +2442,32 @@ public class SystemBundleTests extends AbstractBundleTests {
return file;
}
+ public static File createBundleWithBytes(File outputDir, String bundleName, Map<String, String> headers,
+ Map<String, byte[]>... entries) throws IOException {
+ Manifest m = new Manifest();
+ Attributes attributes = m.getMainAttributes();
+ attributes.putValue("Manifest-Version", "1.0");
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
+ attributes.putValue(entry.getKey(), entry.getValue());
+ }
+ File file = new File(outputDir, "bundle" + bundleName + ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
+ JarOutputStream jos = new JarOutputStream(new FileOutputStream(file), m);
+ if (entries != null) {
+ for (Map<String, byte[]> entryMap : entries) {
+ for (Map.Entry<String, byte[]> entry : entryMap.entrySet()) {
+ jos.putNextEntry(new JarEntry(entry.getKey()));
+ if (entry.getValue() != null) {
+ jos.write(entry.getValue());
+ }
+ jos.closeEntry();
+ }
+ }
+ }
+ jos.flush();
+ jos.close();
+ return file;
+ }
+
public void testBug405919() throws Exception {
File config = OSGiTestsActivator.getContext().getDataFile(getName());
config.mkdirs();
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
index fa24f45f3..ec13c9096 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -521,17 +521,18 @@ public class ClasspathManager {
}
private BundleEntry findLocalEntry(String path, ClasspathEntry[] cpEntries, int classPathIndex, int[] curIndex) {
- BundleEntry result = null;
for (ClasspathEntry cpEntry : cpEntries) {
if (cpEntry != null) {
- result = cpEntry.findEntry(path);
- if (result != null && (classPathIndex == -1 || classPathIndex == curIndex[0])) {
- return result;
+ if (classPathIndex == -1 || classPathIndex == curIndex[0]) {
+ BundleEntry result = cpEntry.findEntry(path);
+ if (result != null) {
+ return result;
+ }
}
}
curIndex[0]++;
}
- return result;
+ return null;
}
/**

Back to the top