You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2021/05/16 22:56:26 UTC
[felix-dev] 01/01: FELIX-6416: special case runtime ref in bundle
urls
This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch issues/FELIX-6416
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit 616c772199d5398942273c5c2783fea4467bdcd4
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Mon May 17 00:56:11 2021 +0200
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 bbde321..164d4d2 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);
}
@@ -124,17 +124,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 19d6d07..bcd5de7 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;
@@ -174,6 +179,59 @@ public class ResourceLoadingTest extends TestCase
assertTrue(testBundle.adapt(BundleWiring.class).getClassLoader().getResource("bla/bli/blub").toExternalForm().endsWith("/blub"));
}
+ 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())