Michael Lipp a écrit le 16/05/2017 à 23:39 : > Hi, > > I searched to no avail. Does anybody know of an implementation of > FileSystemProvider > (https://docs.oracle.com/javase/7/docs/api/java/nio/file/spi/FileSystemProvider.html) > that supports the "bundle:" scheme (similar to the Zip File System > Provider: > https://docs.oracle.com/javase/8/docs/technotes/guides/io/fsp/zipfilesystemprovider.html)? > > I have code that relies on a directory tree of resources to be available > as NIO FileSystem. This is no problem when the using the "ordinary" > class loading. The "root" is found using a resource lookup (URI resSrc = > this.getClass().getResource("").toURI();). This returns a URI with > scheme "jar", which can be passed to FileSystems.newFileSystem. When > running in the OSGi environment, I get a URI with the "bundle" scheme...
Hi, I have searched before and did not find any. Here's a summary of my previous exploration on the topic: My conclusion is that there is no proper way to do it without being the system bundle. The thing is Nio Filesystems have non-blocking IO methods (eg AsynchronousFileChannels) and Bundles are opaque, might be stored in memory (e.g installing/updating a bundle from an InputStream). A partial solution for bundles only stored in disk is not reliable either, because the bundle "location" can be anything, and is rarely if ever an absolute path... recomposing an absolute path from the workingDir + the location might work in some cases, but that's super hackish. Then, the only way to work with them is blocking (reading a resource can only be done through URL#openStream()) Blocking methods from the NIO filesystem provider could be implemented on top of those, but the non-blocking ones would have to be backed by a thread-pool, read extra bytes (it's possible with an AsyncFileChannel/RandomAccessFile to start reading at a random position) and in that case you might as well go for blocking methods and be "fake non-blocking" with your own thread-pool. Or they could throw UnsupportedOperationException, but that would probably break your consumer code, and it's a bit sad considering that's a big part of what Nio filesystems add to the File API! Because this probably requires a significant refactor of existing system bundles, my quick solution has been to lazily copy Bundle resources, when asked for, to the bundle storage area, and then use the regular filesystem API (since the bundle storage area is on disk). You can see how it's used there [1] (I happen to wrap it in reactive streams [2] for composition) Why go through all the trouble? First benefit is using nio.Files/Path API to abstract over different file-systems, another is to be able to have back-pressure with non-blocking consumers. The good news is, because those URLs are of the form bundle://<bundleId>.<bundleRevision>/resource, it does not need an update of the OSGi APIs, the system bundle can implement it, however as far as I know there are no implementation for open source frameworks, maybe there are on some proprietary ones ; and maybe it should be part of a future OSGi core spec, because that code is going to break on frameworks not implementing the extension! While it does not seem too hard to implement for bundles that stored on a file system (default filesystem provider), or as a jar file (zip filesystem), it is probably trickier for in memory-bundles: however there are existing open source in-memory filesystems like jimfs that could be used as a back-end, and the current Bundle IO/resource methods could wrap Jimfs newInputStream() calls. Hope this helps, Simon [1] https://github.com/primeval-io/primeval-codex/blob/master/src/test/java/io/primeval/codex/io/impl/ResourceFinderReaderImplTest.java [2] http://www.reactive-streams.org/ _______________________________________________ OSGi Developer Mail List osgi-dev@mail.osgi.org https://mail.osgi.org/mailman/listinfo/osgi-dev