From 768e5be705c8f2947dfc54ce829a8fdea06dabe9 Mon Sep 17 00:00:00 2001 From: Jan-Willem Harmannij Date: Sun, 31 Mar 2024 16:08:33 +0200 Subject: [PATCH] Use SymbolLookup::libraryLookup to load libraries, remove custom LibLoad class --- .../groovy/java-gi.library-conventions.gradle | 15 +-- .../javagi/configuration/ClassNames.java | 1 - .../javagi/generators/NamespaceGenerator.java | 4 +- .../github/jwharm/javagi/interop/Interop.java | 17 +++- .../github/jwharm/javagi/interop/LibLoad.java | 99 ------------------- 5 files changed, 16 insertions(+), 120 deletions(-) delete mode 100644 modules/glib/src/main/java/io/github/jwharm/javagi/interop/LibLoad.java diff --git a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle index c7b21d41..bab24617 100644 --- a/buildSrc/src/main/groovy/java-gi.library-conventions.gradle +++ b/buildSrc/src/main/groovy/java-gi.library-conventions.gradle @@ -11,7 +11,7 @@ import io.github.jwharm.javagi.GenerateSources * - Set JDK version * - Configure 'generateSources' action * - Enable preview features - * - Set OS-specific library paths for unit tests + * - Set OS-specific JVM parameters * - Set common POM metadata and enable signing */ @@ -84,22 +84,11 @@ tasks.named('test', Test) { enabled = false } - // Configure library path for MacOS (Homebrew) and set MacOS-specific JVM parameter + // Set MacOS-specific JVM parameter if (Os.isFamily(Os.FAMILY_MAC)) { - jvmArgs += '-Djava.library.path=/opt/homebrew/lib' jvmArgs += '-XstartOnFirstThread' } - // Configure library path for Arch, Fedora and Debian/Ubuntu - else if (Os.isFamily(Os.FAMILY_UNIX)) { - jvmArgs += '-Djava.library.path=/usr/lib64:/lib64:/lib:/usr/lib:/lib/x86_64-linux-gnu' - } - - // Configure library path for Windows (MSYS2) - else if (Os.isFamily(Os.FAMILY_WINDOWS)) { - jvmArgs += '-Djava.library.path=C:/msys64/mingw64/bin' - } - useJUnitPlatform() jvmArgs += '--enable-preview' jvmArgs += '--enable-native-access=ALL-UNNAMED' diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/ClassNames.java b/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/ClassNames.java index 011f43ef..59ef1e44 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/ClassNames.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/configuration/ClassNames.java @@ -49,7 +49,6 @@ public final class ClassNames { public static final ClassName ARENA_CLOSE_ACTION = get(PKG_INTEROP, "ArenaCloseAction"); public static final ClassName MEMORY_CLEANER = get(PKG_INTEROP, "MemoryCleaner"); public static final ClassName INTEROP = get(PKG_INTEROP, "Interop"); - public static final ClassName LIB_LOAD = get(PKG_INTEROP, "LibLoad"); public static final ClassName PLATFORM = get(PKG_INTEROP, "Platform"); public static final ClassName AUTO_CLOSEABLE = get(PKG_GIO, "AutoCloseable"); diff --git a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java index ac4ac52d..d223a78a 100644 --- a/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java +++ b/buildSrc/src/main/java/io/github/jwharm/javagi/generators/NamespaceGenerator.java @@ -83,7 +83,7 @@ private CodeBlock loadLibraries() { Platform.toString(platform)); for (String libName : library.split(",")) block.addStatement("$T.loadLibrary($S)", - ClassNames.LIB_LOAD, + ClassNames.INTEROP, libName); block.endControlFlow(); } @@ -92,7 +92,7 @@ private CodeBlock loadLibraries() { else { block.addStatement("case $S -> $T.loadLibrary($S)", Platform.toString(platform), - ClassNames.LIB_LOAD, + ClassNames.INTEROP, library); } } diff --git a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java b/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java index dd122300..46c52805 100644 --- a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java +++ b/modules/glib/src/main/java/io/github/jwharm/javagi/interop/Interop.java @@ -51,13 +51,20 @@ private record FunctionPointer(MemorySegment address, private static final Map namedFunctions = new HashMap<>(); private static final Map functionPointers = new HashMap<>(); - private final static SymbolLookup symbolLookup; private final static Linker linker = Linker.nativeLinker(); - static { - SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); - symbolLookup = name -> loaderLookup.find(name).or(() -> - linker.defaultLookup().find(name)); + public static SymbolLookup symbolLookup = SymbolLookup.loaderLookup() + .or(Linker.nativeLinker().defaultLookup()); + + /** + * Load the specified library using + * {@link SymbolLookup#libraryLookup(String, Arena)}. + * + * @param name the name of the library + */ + public static void loadLibrary(String name) { + Interop.symbolLookup = SymbolLookup.libraryLookup(name, Arena.global()) + .or(Interop.symbolLookup); } /** diff --git a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/LibLoad.java b/modules/glib/src/main/java/io/github/jwharm/javagi/interop/LibLoad.java deleted file mode 100644 index f980e9b2..00000000 --- a/modules/glib/src/main/java/io/github/jwharm/javagi/interop/LibLoad.java +++ /dev/null @@ -1,99 +0,0 @@ -/* Java-GI - Java language bindings for GObject-Introspection-based libraries - * Copyright (C) 2022-2024 Jan-Willem Harmannij - * - * SPDX-License-Identifier: LGPL-2.1-or-later - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -package io.github.jwharm.javagi.interop; - -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.stream.Stream; - -/** - * The LibLoad class is used by Java-GI to load native libraries by name. - */ -public class LibLoad { - - static { - String javagiPath = System.getProperty("javagi.path"); - String javaPath = System.getProperty("java.library.path"); - if (javagiPath != null) { - if (javaPath == null) - System.setProperty("java.library.path", javagiPath); - else - System.setProperty("java.library.path", - javaPath + File.pathSeparator + javagiPath); - } - } - - /** - * Load the native library with the provided name. - * - * @param name the name of the library - */ - public static void loadLibrary(String name) { - InteropException fail = new InteropException("Could not load library " + name); - - // Try System::loadLibrary first - try { - System.loadLibrary(name); - return; - } catch (Throwable t) { - fail.addSuppressed(t); - } - - // Loop through all paths defined in java.library.path - String[] libraryPaths = System.getProperty("java.library.path") - .split(File.pathSeparator); - - for (String s : libraryPaths) { - if (s.isBlank()) - continue; - - // Get a direct path to the directory - Path pk = Path.of(s).toAbsolutePath().normalize(); - if (!Files.isDirectory(pk)) - continue; - - // List the files in the directory - Path[] files; - try (Stream p = Files.list(pk)) { - files = p.toArray(Path[]::new); - } catch (Throwable t) { - fail.addSuppressed(t); - continue; - } - - // Find the file with the requested library name - for (Path path : files) { - try { - String fn = path.getFileName().toString(); - if (fn.equals(name)) { - - // Load the library - System.load(path.toString()); - return; - } - } catch (Throwable t) { - fail.addSuppressed(t); - } - } - } - throw fail; - } -}