Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public static final class Builder {
private HostIO allowHostIO = HostIO.READ_WRITE;
private boolean caseInsensitive = VirtualFileSystemImpl.isWindows();

private Class<?> resourceLoadingClass;
private ClassLoader resourceClassLoader;

private String resourceDirectory;

private Builder() {
Expand Down Expand Up @@ -238,7 +239,7 @@ public Builder unixMountPoint(String unixMountPoint) {

/**
* By default, virtual filesystem resources are loaded by delegating to
* <code>VirtualFileSystem.class.getResource(name)</code>. Use
* <code>VirtualFileSystem.class.getClassLoader().getResource(name)</code>. Use
* <code>resourceLoadingClass</code> to determine where to locate resources in
* cases when for example <code>VirtualFileSystem</code> is on module path and
* the jar containing the resources is on class path.
Expand All @@ -249,7 +250,24 @@ public Builder unixMountPoint(String unixMountPoint) {
* @since 24.2.0
*/
public Builder resourceLoadingClass(Class<?> c) {
resourceLoadingClass = c;
resourceClassLoader = c.getClassLoader();
return this;
}

/**
* By default, virtual filesystem resources are loaded by delegating to
* <code>VirtualFileSystem.class.getClassLoader().getResource(name)</code>. Use
* <code>resourceClassLoader</code> to determine where to locate resources in
* cases when for example <code>VirtualFileSystem</code> is on module path and
* the jar containing the resources is on class path.
*
* @param cl
* the classloader used to load resources
* @return this builder
* @since 26.0.0
*/
public Builder resourceClassLoader(ClassLoader cl) {
resourceClassLoader = cl;
return this;
}

Expand Down Expand Up @@ -292,8 +310,8 @@ public VirtualFileSystem build() {
? Path.of(DEFAULT_WINDOWS_MOUNT_POINT)
: Path.of(DEFAULT_UNIX_MOUNT_POINT);
}
return new VirtualFileSystem(extractFilter, mountPoint, allowHostIO, resourceLoadingClass,
resourceDirectory, caseInsensitive);
return new VirtualFileSystem(extractFilter, mountPoint, allowHostIO, resourceClassLoader, resourceDirectory,
caseInsensitive);
}
}

Expand All @@ -308,10 +326,10 @@ private static Path getMountPointAsPath(String mp) {
}

private VirtualFileSystem(Predicate<Path> extractFilter, Path mountPoint, HostIO allowHostIO,
Class<?> resourceLoadingClass, String resourceDirectory, boolean caseInsensitive) {
ClassLoader resourceClassLoader, String resourceDirectory, boolean caseInsensitive) {

this.impl = new VirtualFileSystemImpl(extractFilter, mountPoint, resourceDirectory, allowHostIO,
resourceLoadingClass, caseInsensitive);
resourceClassLoader, caseInsensitive);
this.delegatingFileSystem = VirtualFileSystemImpl.createDelegatingFileSystem(impl);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,10 @@ private static String absoluteResourcePath(String... components) {
private final Map<String, BaseEntry> vfsEntries = new HashMap<>();

/**
* Class used to read resources with getResource(name). By default
* Classloader used to read resources. By defaut, the classloader of
* VirtualFileSystem.class.
*/
private Class<?> resourceLoadingClass;
private final ClassLoader resourceClassLoader;

static final String PLATFORM_SEPARATOR = Paths.get("").getFileSystem().getSeparator();
private static final char RESOURCE_SEPARATOR_CHAR = '/';
Expand Down Expand Up @@ -310,11 +310,11 @@ private void removeExtractDir() {
* argument may be {@code null} causing that no extraction will happen.
*/
VirtualFileSystemImpl(Predicate<Path> extractFilter, Path mountPoint, String resourceDirectory, HostIO allowHostIO,
Class<?> resourceLoadingClass, boolean caseInsensitive) {
if (resourceLoadingClass != null) {
this.resourceLoadingClass = resourceLoadingClass;
ClassLoader resourceClassLoader, boolean caseInsensitive) {
if (resourceClassLoader != null) {
this.resourceClassLoader = resourceClassLoader;
} else {
this.resourceLoadingClass = VirtualFileSystem.class;
this.resourceClassLoader = VirtualFileSystem.class.getClassLoader();
}
this.caseInsensitive = caseInsensitive;
this.mountPoint = mountPoint;
Expand All @@ -323,10 +323,14 @@ private void removeExtractDir() {
this.platformVenvPath = resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_VENV));
this.platformSrcPath = resourcePathToPlatformPath(absoluteResourcePath(vfsRoot, VFS_SRC));

fine("VirtualFilesystem %s, allowHostIO: %s, resourceLoadingClass: %s, caseInsensitive: %s, extractOnStartup: %s%s",
mountPoint, allowHostIO.toString(), this.resourceLoadingClass.getName(), caseInsensitive,
extractOnStartup, extractFilter != null ? "" : ", extractFilter: null");

if (LOGGER.isLoggable(Level.FINE)) {
var classLoaderLabel = this.resourceClassLoader == VirtualFileSystem.class.getClassLoader()
? "VirtualFileSystem"
: "custom";
fine("VirtualFilesystem %s, allowHostIO: %s, resourceClassLoader: %s, caseInsensitive: %s, extractOnStartup: %s%s",
mountPoint, allowHostIO.toString(), classLoaderLabel, caseInsensitive, extractOnStartup,
extractFilter != null ? "" : ", extractFilter: null");
}
this.extractFilter = extractFilter;
if (extractFilter != null) {
try {
Expand Down Expand Up @@ -670,7 +674,7 @@ public boolean equals(Object obj) {
private List<URL> getFilelistURLs(String filelistPath) {
List<URL> filelistUrls;
try {
filelistUrls = Collections.list(this.resourceLoadingClass.getClassLoader().getResources(filelistPath));
filelistUrls = Collections.list(resourceClassLoader.getResources(filelistPath));
} catch (IOException e) {
throw new IllegalStateException("IO error during reading the VirtualFileSystem metadata", e);
}
Expand Down Expand Up @@ -745,8 +749,7 @@ private void validateMultipleVFSLocations(List<URL> filelistUrls) {
// by the Maven/Gradle plugin and should contain "pip freeze" of the venv
ArrayList<URL> installedUrls;
try {
installedUrls = Collections.list(
this.resourceLoadingClass.getClassLoader().getResources(resourcePath(vfsRoot, INSTALLED_FILE)));
installedUrls = Collections.list(resourceClassLoader.getResources(resourcePath(vfsRoot, INSTALLED_FILE)));
} catch (IOException e) {
warn("Cannot check compatibility of the merged virtual environments. Cannot read list of packages installed in the virtual environments. IOException: "
+ e.getMessage());
Expand Down Expand Up @@ -790,8 +793,7 @@ private void validateMultipleVFSLocations(List<URL> filelistUrls) {
// Check compatibility of GraalPy versions that were used to create the VFSs
ArrayList<URL> contentsUrls;
try {
contentsUrls = Collections.list(
this.resourceLoadingClass.getClassLoader().getResources(resourcePath(vfsRoot, CONTENTS_FILE)));
contentsUrls = Collections.list(resourceClassLoader.getResources(resourcePath(vfsRoot, CONTENTS_FILE)));
} catch (IOException e) {
warn("Cannot check compatibility of the merged virtual environments. Cannot read GraalPy version of the virtual environments. IOException: "
+ e.getMessage());
Expand Down Expand Up @@ -831,7 +833,7 @@ private void validateMultipleVFSLocations(List<URL> filelistUrls) {
}

private URL getResourceUrl(String path) throws IOException {
List<URL> urls = Collections.list(this.resourceLoadingClass.getClassLoader().getResources(path.substring(1)));
List<URL> urls = Collections.list(resourceClassLoader.getResources(path.substring(1)));
if (vfsRootURL != null) {
urls = getURLInRoot(urls);
}
Expand Down
Loading