diff --git a/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java b/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java index 1d04032a1ff..de955a02541 100644 --- a/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java +++ b/src/java.base/share/classes/java/lang/foreign/SymbolLookup.java @@ -37,6 +37,7 @@ import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import java.lang.invoke.MethodHandles; +import java.nio.file.FileSystems; import java.nio.file.Path; import java.util.Objects; import java.util.Optional; @@ -284,6 +285,7 @@ public interface SymbolLookup { * @throws WrongThreadException if {@code arena} is a confined arena, and this method * is called from a thread {@code T}, other than the arena's owner thread * @throws IllegalArgumentException if {@code path} does not point to a valid library + * in the default file system * @throws IllegalCallerException If the caller is in a module that does not have * native access enabled */ @@ -292,6 +294,9 @@ public interface SymbolLookup { static SymbolLookup libraryLookup(Path path, Arena arena) { Reflection.ensureNativeAccess(Reflection.getCallerClass(), SymbolLookup.class, "libraryLookup"); + if (path.getFileSystem() != FileSystems.getDefault()) { + throw new IllegalArgumentException("Path not in default file system: " + path); + } return libraryLookup(path, RawNativeLibraries::load, arena); } diff --git a/test/jdk/java/foreign/LibraryLookupTest.java b/test/jdk/java/foreign/LibraryLookupTest.java index 90aa589654b..950e769b0f6 100644 --- a/test/jdk/java/foreign/LibraryLookupTest.java +++ b/test/jdk/java/foreign/LibraryLookupTest.java @@ -23,10 +23,16 @@ import org.testng.annotations.Test; +import java.io.IOException; import java.lang.foreign.*; import java.lang.foreign.Arena; import java.lang.invoke.MethodHandle; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Path; +import java.util.HashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -91,6 +97,37 @@ public class LibraryLookupTest { } } + @Test + void testLoadLibraryNonDefaultFileSystem() throws URISyntaxException, IOException { + try (FileSystem customFs = fsFromJarOfClass(org.testng.annotations.Test.class)) { + try (Arena arena = Arena.ofConfined()) { + Path p = customFs.getPath("."); + try { + SymbolLookup.libraryLookup(p, arena); + fail("Did not throw IAE"); + } catch (IllegalArgumentException iae) { + assertTrue(iae.getMessage().contains("not in default file system")); + } + } + } + } + + private static FileSystem fsFromJarOfClass(Class clazz) throws URISyntaxException, IOException { + String name = clazz.getName(); + final int lastDot = name.lastIndexOf('.'); + if (lastDot != -1) { + name = name.substring(lastDot + 1); + } + URI uri = clazz.getResource(name + ".class").toURI(); + if (uri.getScheme().equals("jar")) { + final String[] parts = uri.toString().split("!"); + if (parts.length == 2) { + return FileSystems.newFileSystem(URI.create(parts[0]), new HashMap<>()); + } + } + throw new AssertionError("Unable to create file system from " + clazz); + } + private static MemorySegment loadLibrary(Arena session) { SymbolLookup lib = SymbolLookup.libraryLookup(LIB_PATH, session); MemorySegment addr = lib.find("inc").get();