SymbolLookup
is a preview API of the Java platform.
A
symbol lookupretrieves the address of a symbol in one or more libraries. A symbol is a named entity, such as a function or a global variable.
A symbol lookup is created with respect to a particular library (or libraries). Subsequently, the find(String)
method takes the name of a symbol and returns the address of the symbol in that library.
The address of a symbol is modelled as a zero-length memory segmentPREVIEW. The segment can be used in different ways:
Linker
PREVIEW to create a downcall method handle, which can then be used to call the foreign function at the segment's address.The factory methods
libraryLookup(String, Arena)
and
libraryLookup(Path, Arena)
create a symbol lookup for a library known to the operating system. The library is specified by either its name or a path. The library is loaded if not already loaded. The symbol lookup, which is known as a
library lookup, and its lifetime is controlled by an
arenaPREVIEW. For instance, if the provided arena is a confined arena, the library associated with the symbol lookup is unloaded when the confined arena is
closedPREVIEW:
try (Arena arena = Arena.ofConfined()) {
SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena); // libGL.so loaded here
MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
...
} // libGL.so unloaded here
If a library was previously loaded through JNI, i.e., by System.load(String)
or System.loadLibrary(String)
, then the library was also associated with a particular class loader. The factory method loaderLookup()
creates a symbol lookup for all the libraries associated with the caller's class loader:
System.loadLibrary("GL"); // libGL.so loaded here
...
SymbolLookup libGL = SymbolLookup.loaderLookup();
MemorySegment glGetString = libGL.find("glGetString").orElseThrow();
This symbol lookup, which is known as a
loader lookup, is dynamic with respect to the libraries associated with the class loader. If other libraries are subsequently loaded through JNI and associated with the class loader, then the loader lookup will expose their symbols automatically.
Note that a loader lookup only exposes symbols in libraries that were previously loaded through JNI, i.e., by System.load(String)
or System.loadLibrary(String)
. A loader lookup does not expose symbols in libraries that were loaded in the course of creating a library lookup:
libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
loaderLookup().find("glGetString").isPresent(); // false
Note also that a library lookup for library
L
exposes symbols in
L
even if
L
was previously loaded through JNI (the association with a class loader is immaterial to the library lookup):
System.loadLibrary("GL"); // libGL.so loaded here
libraryLookup("libGL.so", arena).find("glGetString").isPresent(); // true
Finally, each Linker
PREVIEW provides a symbol lookup for libraries that are commonly used on the OS and processor combination supported by that Linker
PREVIEW. This symbol lookup, which is known as a default lookup, helps clients to quickly find addresses of well-known symbols. For example, a Linker
PREVIEW for Linux/x64 might choose to expose symbols in libc
through the default lookup:
Linker nativeLinker = Linker.nativeLinker();
SymbolLookup stdlib = nativeLinker.defaultLookup();
MemorySegment malloc = stdlib.find("malloc").orElseThrow();
Returns the address of the symbol with the given name.
Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library.
Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library.
Returns a symbol lookup for symbols in the libraries associated with the caller's class loader.
Returns a composed symbol lookup that returns result of finding the symbol with this lookup if found, otherwise returns the result of finding the symbol with the other lookup.
Returns the address of the symbol with the given name.
name
- the symbol name.
Returns a composed symbol lookup that returns result of finding the symbol with this lookup if found, otherwise returns the result of finding the symbol with the other lookup.
var lookup = SymbolLookup.libraryLookup("foo", arena)
.or(SymbolLookup.libraryLookup("bar", arena))
.or(SymbolLookup.loaderLookup());
The above code creates a symbol lookup that first searches for symbols in the "foo" library. If no symbol is found in "foo" then "bar" is searched. Finally, if a symbol is not found in neither "foo" nor "bar", the loader lookup is used.
other
- the symbol lookup that should be used to look for symbols not found in this lookup.
Returns a symbol lookup for symbols in the libraries associated with the caller's class loader.
A library is associated with a class loader CL
when the library is loaded via an invocation of System.load(String)
or System.loadLibrary(String)
from code in a class defined by CL
. If that code makes further invocations of System.load(String)
or System.loadLibrary(String)
, then more libraries are loaded and associated with CL
. The symbol lookup returned by this method is always current: it reflects all the libraries associated with the relevant class loader, even if they were loaded after this method returned.
Libraries associated with a class loader are unloaded when the class loader becomes unreachable. The symbol lookup returned by this method is associated with a fresh scopePREVIEW which keeps the caller's class loader reachable. Therefore, libraries associated with the caller's class loader are kept loaded (and their symbols available) as long as a loader lookup for that class loader, or any of the segments obtained by it, is reachable.
In cases where this method is called from a context where there is no caller frame on the stack (e.g. when called directly from a JNI attached thread), the caller's class loader defaults to the system class loader.
Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library. The lifetime of the returned library lookup is controlled by the provided arena. For instance, if the provided arena is a confined arena, the library associated with the returned lookup will be unloaded when the provided confined arena is
closedPREVIEW.
This method is restricted. Restricted methods are unsafe, and, if used incorrectly, their use might crash the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on restricted methods, and use safe and supported functionalities, where possible.
dlopen
function for that OS. In Windows, the library name is resolved according to the specification of the LoadLibrary
function.
name
- the name of the library in which symbols should be looked up.
arena
- the arena associated with symbols obtained from the returned lookup.
IllegalStateException
- if arena.scope().isAlive() == false
WrongThreadException
- if arena
is a confined arena, and this method is called from a thread T
, other than the arena's owner thread.
IllegalArgumentException
- if name
does not identify a valid library.
IllegalCallerException
- If the caller is in a module that does not have native access enabled.
Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library. The lifetime of the returned library lookup is controlled by the provided arena. For instance, if the provided arena is a confined arena, the library associated with the returned lookup will be unloaded when the provided confined arena is
closedPREVIEW.
This method is restricted. Restricted methods are unsafe, and, if used incorrectly, their use might crash the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on restricted methods, and use safe and supported functionalities, where possible.
dlopen
, dlsym
and dlclose
functions.
path
- the path of the library in which symbols should be looked up.
arena
- the arena associated with symbols obtained from the returned lookup.
IllegalStateException
- if arena.scope().isAlive() == false
WrongThreadException
- if arena
is a confined arena, and this method is called from a thread T
, other than the arena's owner thread.
IllegalArgumentException
- if path
does not point to a valid library.
IllegalCallerException
- If the caller is in a module that does not have native access enabled.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4