This is an automated email from the ASF dual-hosted git repository. pauls pushed a commit to branch framework-6.0.5 in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit d4282bb99ec28549d2de7314aab5e406dc208a74 Author: Karl Pauls <[email protected]> AuthorDate: Wed May 26 16:32:12 2021 +0200 Merge pull request #77 from apache/issues/FELIX-6416 FELIX-6416: special case runtime ref in bundle urls --- .../framework/URLHandlersBundleURLConnection.java | 35 ++++++++++--- .../felix/framework/ResourceLoadingTest.java | 58 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java index 794af28..c1fe188 100644 --- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java +++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java @@ -48,13 +48,13 @@ class URLHandlersBundleURLConnection extends URLConnection String urlString = url.toExternalForm(); - m_path = urlString.substring(urlString.indexOf(url.getPath())); + String path = urlString.substring(urlString.indexOf(url.getPath())); // If this is an attempt to create a connection to the root of // the bundle, then throw an exception since this isn't possible. // We only allow "/" as a valid URL so it can be used as context // for creating other URLs. - if ((m_path == null) || (m_path.length() == 0) || m_path.equals("/")) + if ((path == null) || (path.length() == 0) || path.equals("/")) { throw new IOException("Resource does not exist: " + url); } @@ -125,17 +125,40 @@ class URLHandlersBundleURLConnection extends URLConnection m_classPathIdx = 0; } if (!((BundleRevisionImpl) m_targetRevision) - .hasInputStream(m_classPathIdx, m_path)) + .hasInputStream(m_classPathIdx, path)) { BundleWiring wiring = m_targetRevision.getWiring(); ClassLoader cl = (wiring != null) ? wiring.getClassLoader() : null; - URL newurl = (cl != null) ? cl.getResource(m_path) : null; + URL newurl = (cl != null) ? cl.getResource(path) : null; if (newurl == null) { - throw new IOException("Resource does not exist: " + url); + // FELIX-6416 - handle the special case of java adding a runtime ref + if (!"runtime".equals(url.getRef())) + { + throw new IOException("Resource does not exist: " + url); + } + path = url.getPath(); + if ((path == null) || (path.length() == 0) || path.equals("/")) + { + throw new IOException("Resource does not exist: " + url); + } + if (!((BundleRevisionImpl) m_targetRevision) + .hasInputStream(m_classPathIdx, path)) + { + newurl = (cl != null) ? cl.getResource(path) : null; + if (newurl == null) + { + throw new IOException("Resource does not exist: " + url); + } + m_classPathIdx = newurl.getPort(); + } + } + else + { + m_classPathIdx = newurl.getPort(); } - m_classPathIdx = newurl.getPort(); } + m_path = path; } public synchronized void connect() throws IOException diff --git a/framework/src/test/java/org/apache/felix/framework/ResourceLoadingTest.java b/framework/src/test/java/org/apache/felix/framework/ResourceLoadingTest.java index ce1167c..9e531a5 100644 --- a/framework/src/test/java/org/apache/felix/framework/ResourceLoadingTest.java +++ b/framework/src/test/java/org/apache/felix/framework/ResourceLoadingTest.java @@ -20,12 +20,17 @@ package org.apache.felix.framework; import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; @@ -124,6 +129,59 @@ public class ResourceLoadingTest extends TestCase assertEquals("This is a Test", reader.readLine()); } + public void testResourceLoadingUsingURLClassLoaderJDK9() throws Exception { + String bmf = "Bundle-SymbolicName: cap.bundle\n" + + "Bundle-Version: 1.2.3.Blah\n" + + "Bundle-ManifestVersion: 2\n" + + "Import-Package: org.osgi.framework\n"; + File bundleFile = File.createTempFile("felix-bundle", ".jar", tempDir); + ByteArrayOutputStream embeddedJar1 = new ByteArrayOutputStream(); + ByteArrayOutputStream embeddedJar2 = new ByteArrayOutputStream(); + + Manifest mf = new Manifest(new ByteArrayInputStream(bmf.getBytes("utf-8"))); + mf.getMainAttributes().putValue("Manifest-Version", "1.0"); + JarOutputStream bundle1 = new JarOutputStream(new FileOutputStream(bundleFile), mf); + JarOutputStream ej1 = new JarOutputStream(embeddedJar1, mf); + JarOutputStream ej2 = new JarOutputStream(embeddedJar2, mf); + + String ej1Entry = "ej1.txt"; + ej1.putNextEntry(new ZipEntry(ej1Entry)); + ej1.write("This is a Test".getBytes()); + ej1.close(); + + String ej2Entry = "ej2.txt"; + ej2.putNextEntry(new ZipEntry(ej2Entry)); + ej2.write("This is a Test".getBytes()); + ej2.close(); + + String bundleResource = "b1.txt"; + bundle1.putNextEntry(new ZipEntry(bundleResource)); + bundle1.write("This is a Test".getBytes()); + bundle1.putNextEntry(new ZipEntry("ej1.jar")); + bundle1.write(embeddedJar1.toByteArray()); + bundle1.putNextEntry(new ZipEntry("ej2.jar")); + bundle1.write(embeddedJar2.toByteArray()); + bundle1.close(); + + Bundle testBundle = felix.getBundleContext().installBundle(bundleFile.toURI().toASCIIString()); + + testBundle.start(); + + ClassLoader urlClassLoader = createClassLoader(testBundle); + + assertNotNull(urlClassLoader.getResource("ej2.txt")); + } + + ClassLoader createClassLoader(Bundle bundle) { + List<URL> urls = new ArrayList<URL>(); + Collection<String> resources = bundle.adapt(BundleWiring.class).listResources("/", "*.jar", BundleWiring.LISTRESOURCES_LOCAL); + for (String resource : resources) { + urls.add(bundle.getResource(resource)); + } + // Create the classloader + return new URLClassLoader(urls.toArray(new URL[urls.size()]), getClass().getClassLoader()); + } + private static void deleteDir(File root) throws IOException { if (root.isDirectory())
