Skip to content

Commit

Permalink
Add support for ModuleReferences
Browse files Browse the repository at this point in the history
  • Loading branch information
crschnick committed Jan 19, 2023
1 parent fa9c9d6 commit d1bdcd7
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 10 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
The ModuleFS library provides a simple file system implementation to access the contents of Java modules in a unified way.
It also comes with a variety of neat features that will make working with modules more enjoyable for you.
You can get the library through [maven central](https://search.maven.org/artifact/io.xpipe/modulefs).
Note that at least Java 17 is required as it is the first LTS release that includes all necessary bug fixes for the internal module file systems.


## Motivation
Expand Down Expand Up @@ -131,6 +132,21 @@ As ModuleFS does only work through the underlying file systems,
you will not run into any permission issues when using ModuleFS, i.e.
you can even access resources from modules that are not open at all.

### Module References

In case you are loading modules at runtime and want to access the file system of a module before a proper module layer is created,
you can also create a module file system for a
[ModuleReference](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ModuleReference.html) like this:

````java
Path path = ...;
var finder = ModuleFinder.of(path);
var moduleReference = finder.find("myorg.mymodule")
.orElseThrow(() -> new IllegalArgumentException("Module not found"));
try (var fs = ModuleFileSystem.create(moduleReference)) {
...
}
````


## Development
Expand Down
2 changes: 1 addition & 1 deletion modulefs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'signing'
}

version '0.1.5-SNAPSHOT'
version '0.1.5'
group 'io.xpipe'
archivesBaseName = 'modulefs'

Expand Down
13 changes: 13 additions & 0 deletions modulefs/src/main/java/io/xpipe/modulefs/ModuleFileSystem.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.xpipe.modulefs;

import java.io.IOException;
import java.lang.module.ModuleReference;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.UserPrincipalLookupService;
Expand All @@ -20,6 +21,18 @@ public static ModuleFileSystem create(String uri) throws IOException {
return fsp.newFileSystem(URI.create(uri), Map.of());
}

public static ModuleFileSystem create(ModuleReference reference) throws IOException {
ModuleFileSystemProvider fsp = FileSystemProvider.installedProviders().stream()
.filter(p -> p instanceof ModuleFileSystemProvider)
.map(p -> (ModuleFileSystemProvider) p)
.findFirst()
.orElseThrow(() -> new ProviderNotFoundException("modulefs provider not found"));
var location = reference.location().orElseThrow(() -> new IllegalArgumentException("Module reference location is unknown"));
var name = reference.descriptor().name();
var uri = URI.create("module:/" + name);
return fsp.newFileSystem(uri, Map.of("location", location));
}

private final String module;
private final FileSystemProvider provider;
protected Path basePath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.module.ModuleReference;
import java.lang.module.ResolvedModule;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
Expand Down Expand Up @@ -77,21 +78,26 @@ public ModuleFileSystem newFileSystem(URI uri, Map<String, ?> env) throws IOExce
checkUri(uri);

var layer = env.containsKey("layer") ? (ModuleLayer) env.get("layer") : ModuleLayer.boot();
var moduleLocation = env.containsKey("location") ? (URI) env.get("location") : null;
String moduleName = uri.getPath().substring(1);
var loc = resolveModule(moduleName, layer)
.orElseThrow(() -> new FileSystemNotFoundException(
"Module " + moduleName + " was not resolved"));
var modUri = loc.reference().location().orElseThrow(() -> new IllegalArgumentException(
"Location of module " + moduleName + " is unknown"));

if (moduleLocation == null) {
var loc = resolveModule(moduleName, layer)
.orElseThrow(() -> new FileSystemNotFoundException(
"Module " + moduleName + " was not resolved"));
moduleLocation = loc.reference().location().orElseThrow(() -> new IllegalArgumentException(
"Location of module " + moduleName + " is unknown"));
}

var scheme = moduleLocation.getScheme();
var fs = Stream.of(
JrtModuleFileSystem.create(moduleName, this, uri, modUri),
JarModuleFileSystem.create(moduleName, this, modUri),
ExplodedModuleFileSystem.create(moduleName, this, modUri))
JrtModuleFileSystem.create(moduleName, this, uri, moduleLocation),
JarModuleFileSystem.create(moduleName, this, moduleLocation),
ExplodedModuleFileSystem.create(moduleName, this, moduleLocation))
.flatMap(Optional::stream)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
"Unsupported module file system type " + modUri.getScheme()));
"Unsupported module file system type " + scheme));
filesystems.put(moduleName, fs);
return fs;
}
Expand Down

0 comments on commit d1bdcd7

Please sign in to comment.