Tuomas Kiviaho created ARIES-1924:
-------------------------------------

             Summary: Provider bundle service url tracking with bundle wiring 
instead of custom urls
                 Key: ARIES-1924
                 URL: https://issues.apache.org/jira/browse/ARIES-1924
             Project: Aries
          Issue Type: Improvement
          Components: SPI Fly
    Affects Versions: spifly-1.2.3
            Reporter: Tuomas Kiviaho


getMetaInfServiceURLsFromJar seems to be crafting custom urls and for some 
reason they fail in Eclipse PDE. I didn't look any deeper why this is (most 
likely due to entries containing urls from outside classpath) because I 
remembered that BundleWiring contains wildcard support for resource lookup 
nowadays and there is no need for custom embedded jar file handling that seems 
to leak outside of the appropriate resources.

java.nio.file.NoSuchFileException: 
...\tmp\jar_cache931050380819344291.tmpjava.nio.file.NoSuchFileException: 
...\tmp\jar_cache931050380819344291.tmp at 
sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) at 
sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) at 
sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) at 
sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
 at java.nio.file.Files.newByteChannel(Files.java:361) at 
java.nio.file.Files.createFile(Files.java:632) at 
java.nio.file.TempFileHelper.create(TempFileHelper.java:138) at 
java.nio.file.TempFileHelper.createTempFile(TempFileHelper.java:161) at 
java.nio.file.Files.createTempFile(Files.java:897) at 
sun.net.www.protocol.jar.URLJarFile$1.run(URLJarFile.java:218) at 
sun.net.www.protocol.jar.URLJarFile$1.run(URLJarFile.java:216) at 
java.security.AccessController.doPrivileged(Native Method) at 
sun.net.www.protocol.jar.URLJarFile.retrieve(URLJarFile.java:215) at 
sun.net.www.protocol.jar.URLJarFile.getJarFile(URLJarFile.java:71) at 
sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:94) at 
sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122) at 
sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:152)
 at java.net.URL.openStream(URL.java:1045) at 
org.apache.aries.spifly.ProviderBundleTrackerCustomizer.addingBundle(ProviderBundleTrackerCustomizer.java:141)

Here's a patch that I'm using:

{code:patch|title=ProviderBundleTrackerCustomizer}
@@ -24,21 +24,20 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Dictionary;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
+import java.util.Optional;
 import java.util.logging.Level;
+import java.util.stream.Collectors;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleEvent;
-import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServicePermission;
 import org.osgi.framework.ServiceRegistration;
@@ -111,26 +110,13 @@
             activator.registerProviderBundle(svc, bundle, customAttributes);
         }
 
-        List<URL> serviceFileURLs = new ArrayList<URL>();
-
-        Enumeration<URL> entries = bundle.findEntries(METAINF_SERVICES, "*", 
false);
-        if (entries != null) {
-            serviceFileURLs.addAll(Collections.list(entries));
-        }
-
-        Object bcp = bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
-        if (bcp instanceof String) {
-            for (String entry : ((String) bcp).split(",")) {
-                entry = entry.trim();
-                if (entry.equals("."))
-                    continue;
-
-                URL url = bundle.getResource(entry);
-                if (url != null) {
-                    serviceFileURLs.addAll(getMetaInfServiceURLsFromJar(url));
-                }
-            }
-        }
+        List<URL> serviceFileURLs = 
Optional.ofNullable(bundle.adapt(BundleWiring.class)).flatMap(bundleWiring -> {
+            Collection<String> resources = 
bundleWiring.listResources(METAINF_SERVICES, "*", 
BundleWiring.LISTRESOURCES_LOCAL);
+            return 
Optional.ofNullable(resources).map(Collection::stream).map(stream -> {
+                ClassLoader classLoader = bundleWiring.getClassLoader();
+                return 
stream.map(classLoader::getResource).collect(Collectors.toList());
+            });   
+        }).orElseGet(Collections::emptyList);
 
         final List<ServiceRegistration> registrations = new 
ArrayList<ServiceRegistration>();
         for (URL serviceFileURL : serviceFileURLs) {
@@ -326,31 +312,6 @@
         return null;
     }
 
-    private List<URL> getMetaInfServiceURLsFromJar(URL url) {
-        List<URL> urls = new ArrayList<URL>();
-        try {
-            JarInputStream jis = null;
-            try {
-                jis = new JarInputStream(url.openStream());
-
-                JarEntry je = null;
-                while((je = jis.getNextJarEntry()) != null) {
-                    if (je.getName().startsWith(METAINF_SERVICES) &&
-                        je.getName().length() > (METAINF_SERVICES.length() + 
1)) {
-                        urls.add(new URL("jar:" + url + "!/" + je.getName()));
-                    }
-                }
-            } finally {
-                if (jis != null) {
-                    jis.close();
-                }
-            }
-        } catch (IOException e) {
-            log(Level.SEVERE, "Problem opening embedded jar file: " + url, e);
-        }
-        return urls;
-    }
-
     @Override
     public void modifiedBundle(Bundle bundle, BundleEvent event, Object 
registrations) {
         // should really be doing something here...

{code}



--
This message was sent by Atlassian Jira
(v8.3.2#803003)

Reply via email to