RFR: Add `--library-path-resolver` option for custom library path resolving
Maurizio Cimadamore
mcimadamore at openjdk.org
Thu Nov 13 12:32:47 UTC 2025
On Thu, 13 Nov 2025 08:37:25 GMT, devjeonghwan <duke at openjdk.org> wrote:
> #### 1. Status Quo
>
> Currently, `jextract` generates code using two standard loading mechanisms:
>
> 1. **Default:** `SymbolLookup.libraryLookup(System.mapLibraryName("name"), ...)`
> 2. **With `--use-system-load-library`:** `System.loadLibrary("name")`
>
> Both methods depend on static paths (e.g., `java.library.path`) and do not support runtime path resolution (hooking) without manual code modification.
>
> #### 2. Problem
>
> Standard loading fails in dynamic deployment scenarios:
>
> * **Bundled Libraries:** Native libraries inside JARs (extracted to temp directories) require loading from an absolute path.
> * **Dynamic Paths:** Paths determined at runtime based on OS/Arch cannot be handled by static system properties.
>
> Users currently must manually edit the generated source to inject custom loading logic.
>
> #### 3. Fix
>
> Introduced a new CLI option: `--library-path-resolver`.
> This option injects a user-defined static method to resolve the library path (or name) at runtime.
>
> **Usage:**
>
>
> jextract ... --library-path-resolver com.example.Resolver#resolvePath
>
>
> **Code Generation:**
>
> **Case 1: Default (SymbolLookup)**
>
>
> // Before
> SymbolLookup.libraryLookup(System.mapLibraryName("foo"), ARENA);
>
> // After
> SymbolLookup.libraryLookup(com.example.Resolver.resolvePath("foo"), ARENA);
>
>
> **Case 2: With `--use-system-load-library`**
>
>
> // Before
> System.loadLibrary("foo");
>
> // After
> System.load(com.example.Resolver.resolvePath("foo"));
>
>
> #### 4. Additional Notes
>
> * **Method Signature:** The resolver method must match `String <method_name>(String <parameter_name>)`.
> * **Return Value:**
> * For `--use-system-load-library`: Must return an **absolute path** (required by `System.load()`).
> * For Default: Returns a path or name accepted by `SymbolLookup`.
>
> #### 5. Testing
>
> Added `TestLibraryPathResolver`.
>
> * Dynamic compilation and loading of a custom resolver class.
> * Correct code generation when the option is present.
> * Verifying that the custom resolver is actually invoked and that the native library is successfully loaded and linked via the resolved path
>
> All tests pass locally.
Before we jump on a solution, I think it would be better to understand what the problem is. I think for path that depends on OS/Platform, jextract (and FFM) actually has a good solution, which is to just use a dynamic linker name. For instance, the jextract guide has this example:
-l :libGL.so.1
Note the `:` prefix -- which basically will avoid the `mapLibraryName` and will just call `libraryLookup` with whatever you put in there (which will then rely on the dynamic linker). But, even when `:` is omitted, if `--use-system-load-library` is `false`, we never use `java.library.path`.
So, I believe the problem is mostly with paths that are generated on the fly (e.g. because a library is extracted from the jar, and then moved to some tmp folder).
Can you please confirm this is the case?
-------------
PR Comment: https://git.openjdk.org/jextract/pull/295#issuecomment-3527590520
More information about the jextract-dev
mailing list