Open benson-basis opened 8 years ago
See https://shomeier.wordpress.com/2015/03/01/implementing-a-filesystemprovider-in-an-osgi-compliant-manner/ for a discussion of this issue.
Maybe this amounts to an opportunity for doc.
Hmm... I wonder if making JimfsFileSystem
public would fix this issue. SystemJimfsFileSystemProvider
is actually intended to fix problems that arise in multiple classloader environments like this, but it looks like the security manager isn't allowing JimfsFileSystem.toPath(URI)
to be invoked (presumably because it's a public method on a package-private class, and also not part of the FileSystem
interface).
It looks to me as if the FileSystemProviders is just another one of those Java 'global' mechanisms that messes up (with) OSGi. Adding your package to the system bundle works just fine. I haven't looked into whether ServiceMix has done something in this area. I made a PR, as you've undoubtedly seen, with some doc. However, your remark about package-private suggests that it could work. I could make a pax-exam test in a PR to demonstrate this and try the fix if you like.
So, I've had a related problem which I commented about here: https://github.com/google/jimfs/issues/7#issuecomment-1244373117
My issue is that I can create a JIMFS virtual filesystem in my little OSGi bundle just fine, but anytime something tries to access one of the files via a jimfs://
URI, it fails, thinking that the JIMFS URL Handler isn't installed.
The reason for my problem is that Java's Paths.get
(called in PathURLConnection#connect
) tries to load the URL handler from the system classloader (via ServiceLoader.load(FileSystemProvider.class, ClassLoader.getSystemClassLoader())
in FileSystemProvider#loadInstalledProviders
). However, Jimfs registered its handler in my Bundle's classloader, as it probably should.
I've been mulling over the best approach to solving the problem. I reckon it's probably to rewrite PathURLConnection
and Handler
to have some knowledge about the classloader they're registered with. That's tricky, though. I can't simply call ServiceLoader.load(FileSystemProvider.class, SystemJimfsFileSystemProvider.class.getClassLoader())
, as that still tries to load and instantiate other FileSystemProviders like com.sun.nio.zipfs.ZipFileSystemProvider
, which, annoyingly, are only visible to the system classloader in the particular OSGi walled garden I get to play in.
Would happily accept some pointers from @cpovirk or @cgdecker if there's a rough direction you'd like to take this but haven't got the time at the moment. I went ahead and signed the contributor agreement.
Feel free to tell me this isn't the same issue & I should get my own thread, but this seems closely enough related that I wanted to note it here.
If I try to call the Jimfs via Paths.get of a Jimfs URI inside an OSGi bundle, I get an illegal access exception from the reflection code in the file system provider. I'm not sure what the fuss is about: this is a pax-exam osgi test that uses Jimfs, and it so all the Jimfs stuff should be in one class loader: the class loader for the jimfs bundle.
In the debugger, toPath.getClass().getClassLoader() is null. fileSystem.getClass().getClassLoader() is org.eclipse.osgi.internal.loader.EquinoxClassLoader@1437268e[com.google.jimfs:1.1.0(id=37)] -- the jimfs bundle.
I see; the collection of file systems in the main 'Paths' class are all loaded by the app class loader, so we're using SystemJimfsClassLoader from the wrong class loader.
Perhaps this is just a typical 'OSGi versus SPI' problem?