Providing your own SymbolLookup / ServiceLoader for SymbolLookup
some-java-user-99206970363698485155 at vodafonemail.de
some-java-user-99206970363698485155 at vodafonemail.de
Tue Aug 20 22:42:27 UTC 2024
Hello,
first of all thank you for your work on the FFM API and jextract! It is
really great that interoperability with native libraries becomes easier.
One issue I currently have with jextract is that none of its `--library`
or `--use-system-load-library` options seem to offer a way for users to
provide their own SymbolLookup. Why is this an issue?
- The header class generated by jextract and possibly additional
bindings classes might be generated by a third-party project, so you
cannot easily modify the source code to change the SymbolLookup creation
(unless you want to fork that project).
- For convenience Java projects often bundle native libraries, extract
them to a temporary file and then load them, for example even JavaFX
does this (see its `NativeLibLoader` class). This avoids requiring users
to configure `java.library.path`. There are probably advantages and
disadvantages with this approach, but nonetheless it would be useful if
developers had the choice, by providing their own SymbolLookup and
specifying the path of the library.
- `SymbolLookup#libraryLookup` seems to be currently the only API which
allows manually unloading the library (by closing the `Arena`). All
other approaches either keep the library loaded until JVM exit, or until
the classloader is garbage collected which might be JVM exit as well (?).
Especially on Windows this is a problem because it prevents the
deletion of the file while the library is loaded, so `File#deleteOnExit`
or similar won't have any effect.
Ideally a solution would put the choice of how the library is loaded in
the hands of the consumers of the generated headers, and not the users
of jextract (since they might be a different person, e.g. if a
third-party project provides bindings). Otherwise if this is something
users of jextract have to manually enable, then most of them will likely
not do it.
Therefore maybe one approach could be to offer some kind of
`SymbolLookupProvider` which is used with a ServiceLoader:
```
interface SymbolLookupProvider {
Optional<SymbolLookup> getSymbolLookup(Class<?> caller, String libName);
}
```
The `caller` here is whoever calls `SymbolLookup#libraryLookup(String,
Arena)`. This might help if someone is unlucky enough to have multiple
dependencies which expect a different library of the same name. If
possible it would be useful if `System#loadLibrary` could use
SymbolLookupProvider as well. And only in case no SymbolLookupProvider
provided a SymbolLookup, the existing default logic is used.
This would be a bit similar to the existing `ClassLoader#findLibrary`,
except that using that method for this purpose seems difficult (you need
a custom class loading setup) respectively impossible (when
`SymbolLookup#libraryLookup` is used).
There are a few open questions though:
- `SymbolLookup#libraryLookup(String, Arena)` already provides an Arena.
Should that be ignored if a SymbolLookupProvider can provide a lookup,
or should the SymbolLookupProvider have the choice to use the given
Arena or use its own. But then the guarantee of
`SymbolLookup#libraryLookup` that closing the Arena unloads the library
might no longer hold.
- `System#loadLibrary` seems to not use SymbolLookup internally at the
moment, so supporting that would not be easily possible probably.
What do you think? Do you have any other ideas for solving the current
issues with jextract mentioned above?
Was there already an discussion about this or a similar issue in the
past? (I tried to search the jextract archives but could not find anything)
Kind regards
(Maybe the proposal here is not specific to jextract and applies to the
FFM API in general. Please let me know if I should forward this mail to
panama-dev.)
More information about the jextract-dev
mailing list