- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
SymbolLookup
is a preview API of the Java platform.
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:
- It can be passed to a
Linker
PREVIEW to create a downcall method handle, which can then be used to call the foreign function at the segment's address. - It can be passed to an existing downcall method handlePREVIEW, as an argument to the underlying foreign function.
- It can be storedPREVIEW inside another memory segment.
- It can be used to access the region of memory backing a global variable (this might require
resizing
PREVIEW the segment first).
Obtaining a symbol lookup
The factory methodslibraryLookup(String, SegmentScope)
and libraryLookup(Path, SegmentScope)
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, is associated
with a scopePREVIEW; when the scope becomes not SegmentScope.isAlive()
PREVIEW, the library is unloaded:
try (Arena arena = Arena.openConfined()) {
SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so", arena.scope()); // 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();
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", scope).find("glGetString").isPresent(); // true
loaderLookup().find("glGetString").isPresent(); // false
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", scope).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();
-
Method Summary
Modifier and TypeMethodDescriptionReturns the address of the symbol with the given name.static SymbolLookupPREVIEW
libraryLookup
(String name, SegmentScopePREVIEW scope) Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library.static SymbolLookupPREVIEW
libraryLookup
(Path path, SegmentScopePREVIEW scope) Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library.static SymbolLookupPREVIEW
Returns a symbol lookup for symbols in the libraries associated with the caller's class loader.
-
Method Details
-
find
Returns the address of the symbol with the given name.- Parameters:
name
- the symbol name.- Returns:
- a zero-length memory segment whose address indicates the address of the symbol, if found.
-
loaderLookup
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 ofSystem.load(String)
orSystem.loadLibrary(String)
from code in a class defined byCL
. If that code makes further invocations ofSystem.load(String)
orSystem.loadLibrary(String)
, then more libraries are loaded and associated withCL
. 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 backed by a scope that is always alive and 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 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.
- Returns:
- a symbol lookup for symbols in the libraries associated with the caller's class loader.
- See Also:
-
libraryLookup
Loads a library with the given name (if not already loaded) and creates a symbol lookup for symbols in that library. The library will be unloaded when the provided scope becomes not alivePREVIEW, if no other library lookup is still using it.- Implementation Note:
- The process of resolving a library name is OS-specific. For instance, in a POSIX-compliant OS,
the library name is resolved according to the specification of the
dlopen
function for that OS. In Windows, the library name is resolved according to the specification of theLoadLibrary
function.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.
- Parameters:
name
- the name of the library in which symbols should be looked up.scope
- the scope associated with symbols obtained from the returned lookup.- Returns:
- a new symbol lookup suitable to find symbols in a library with the given name.
- Throws:
IllegalArgumentException
- ifname
does not identify a valid library.IllegalCallerException
- If the caller is in a module that does not have native access enabled.
-
libraryLookup
Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library. The library will be unloaded when the provided scope becomes not alivePREVIEW, if no other library lookup is still using it.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.
- Implementation Note:
- On Linux, the functionalities provided by this factory method and the returned symbol lookup are
implemented using the
dlopen
,dlsym
anddlclose
functions. - Parameters:
path
- the path of the library in which symbols should be looked up.scope
- the scope associated with symbols obtained from the returned lookup.- Returns:
- a new symbol lookup suitable to find symbols in a library with the given path.
- Throws:
IllegalArgumentException
- ifpath
does not point to a valid library.IllegalCallerException
- If the caller is in a module that does not have native access enabled.
-
SymbolLookup
when preview features are enabled.