Zero-Dependency Java bindings for FUSE using JEP 419.
This is currently an experimental library requiring JDK 18. As long as the Foreign Function & Memory API is incubating, the required JDK will increase.
Currently, it only provides bindings for libfuse 2.x. Once stable, a new branch for libfuse 3.x will be added.
Not all fuse_operations are supported yet.
| Status | |
|---|---|
| getattr | ✅ |
| readlink | ✅ |
| use readdir | |
| use create | |
| mkdir | ✅ |
| unlink | ✅ |
| rmdir | ✅ |
| symlink | ✅ |
| rename | ✅ |
| link | ❌ |
| chmod | ✅ |
| chown | ❌ |
| truncate | ✅ |
| use utimens | |
| open | ✅ |
| read | ✅ |
| write | ✅ |
| statfs | ✅ |
| flush | ❌ |
| release | ✅ |
| fsync | ❌ |
| setxattr | ❌ |
| getxattr | ❌ |
| listxattr | ❌ |
| removexattr | ❌ |
| opendir | ✅ |
| readdir | ✅ |
| releasedir | ✅ |
| fsyncdir | ❌ |
| init | ✅ |
| destroy | ✅ |
| access | ✅ |
| create | ✅ |
| ftruncate | ❌ |
| fgetattr | ❌ |
| lock | ❌ |
| utimens | ✅ |
| bmap | ❌ |
| ioctl | ❌ |
| poll | ❌ |
| write_buf | ❌ |
| read_buf | ❌ |
| flock | ❌ |
| fallocate | ❌ |
Usage examples can be found under /jfuse-examples/. You basically need to implement FuseOperations and pass it to the Fuse.builder():
var builder = Fuse.builder();
var fs = new MyFileSystem(builder.errno());
try (var fuse = builder.build(fs)) {
int result = fuse.mount("my-awesome-fs", mountPoint);
// thread will now block until unmounted or failed
}During runtime, you will need to add allow native access from platform-specific implementations via --enable-native-access, e.g.:
java -p path/to/mods \
-m com.example.mymodule/com.example.mymodule \
--enable-native-access=org.cryptomator.jfuse.mac \
--add-modules jdk.incubator.foreignDue to slight differences in memory layout, each platform needs its own implementation. Currently, the following operating systems and architectures are supported:
| Linux | Mac (macFUSE) | Windows (WinFSP) | |
|---|---|---|---|
| x86_64 | jfuse-linux-amd64 | jfuse-mac | jfuse-win-amd64 |
| arm64 | jfuse-linux-aarch64 | jfuse-mac |
Due to the magic of the Foreign Function & Memory API, you can build all modules on any platform that you can find a JDK for.
Each platform has its own module. In rare cases, we need to update jextracted classes.
In most cases this requires you to run the build on the target platform, as you need access to its system-specific header files and (most likely) build tools. See module readme for specific requirements.
In order to run jextract, use the corresponding Maven profile (-Pjextract).
Before adding a new module, you might want to change the header search path in one of the existing modules and run jextract. If there is no diff at all, you can most likely add a @SupportedPlatform annotation to its FuseBuilder and check if it works.
Otherwise, you'd need to add a copy of the module. Make sure to open it to the api in the module-info.java, as the api module needs reflective access.
This library is not ready for production use. Currently, your best bet would be the awesome jnr-fuse, which will eventually become the benchmark we want to beat.