Details
-
Improvement
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
spifly-1.2.3
-
None
-
None
-
Patch
Description
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:
@@ -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...
Attachments
Issue Links
- duplicates
-
ARIES-1998 IllegalStateException on service unregistration in ProviderBundleTrackerCustomizer.removedBundle
- Closed