Package Summary Overview Summary

Module java.base
Package java.lang.foreign

# Interface SymbolLookup

Functional Interface:
  This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

@FunctionalInterface public interface SymbolLookup
`SymbolLookup` is a preview API of the Java platform.
Programs can only use `SymbolLookup` when preview features are enabled.
Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.
A symbol lookup is an object that may be used to retrieve 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 `lookup(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 segment PREVIEW. 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 base address.
- It can be passed to an existing downcall method handle PREVIEW, as an argument to the underlying foreign function.
- It can be storedPREVIEW inside another memory segment.
- It can be used to dereference memory associated with a global variable (this might require `resizing`PREVIEW the segment first).

## Obtaining a symbol lookup

The factory methods `libraryLookup(String, MemorySession)` and `libraryLookup(Path, MemorySession)` 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 memory session PREVIEW; when the session is closedPREVIEW, the library is unloaded:

    try (MemorySession session = MemorySession.openConfined()) {
        SymbolLookup libGL = SymbolLookup.libraryLookup("libGL.so"); // libGL.so loaded here
        MemorySegment glGetString = libGL.lookup("glGetString");
        ...
    } //  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.lookup("glGetString");

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", session).lookup("glGetString").isPresent(); // true
    loaderLookup().lookup("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", session).lookup("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.lookup("malloc");

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static SymbolLookupPREVIEW`
  `libraryLookup (String name, MemorySessionPREVIEW session)`
  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, MemorySessionPREVIEW session)`
  Loads a library from the given path (if not already loaded) and creates a symbol lookup for symbols in that library.
  `static SymbolLookupPREVIEW`
  `loaderLookup()`
  Returns a symbol lookup for symbols in the libraries associated with the caller's class loader.
  `Optional<MemorySegmentPREVIEW>`
  `lookup (String name)`
  Returns the address of the symbol with the given name.

- ## Method Details

  - ### lookup

    Optional<MemorySegmentPREVIEW> lookup (String name)
    Returns the address of the symbol with the given name.
    Parameters:
      `name` - the symbol name.
    Returns:
      a zero-length memory segment whose base address indicates the address of the symbol, if found.

  - ### loaderLookup

    static SymbolLookupPREVIEW 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 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 backed by a non-closeablePREVIEW, shared memory session 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.

    Returns:
      a symbol lookup for symbols in the libraries associated with the caller's class loader.
    See Also:
      - `System.load(String)`
      - `System.loadLibrary(String)`

  - ### libraryLookup

    static SymbolLookupPREVIEW libraryLookup (String name, MemorySessionPREVIEW session)
    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 memory session is closedPREVIEW, 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 the `LoadLibrary` 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.
      `session` - the memory session which controls the library lifecycle.
    Returns:
      a new symbol lookup suitable to find symbols in a library with the given name.
    Throws:
      `IllegalArgumentException` - if `name` does not identify a valid library.
      `IllegalCallerException` - if access to this method occurs from a module `M` and the command line option `--enable-native-access` is either absent, or does not mention the module name `M`, or `ALL-UNNAMED` in case `M` is an unnamed module.

  - ### libraryLookup

    static SymbolLookupPREVIEW libraryLookup (Path path, MemorySessionPREVIEW session)
    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 memory session is closedPREVIEW, 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` and `dlclose` functions.
    Parameters:
      `path` - the path of the library in which symbols should be looked up.
      `session` - the memory session which controls the library lifecycle.
    Returns:
      a new symbol lookup suitable to find symbols in a library with the given path.
    Throws:
      `IllegalArgumentException` - if `path` does not point to a valid library.
      `IllegalCallerException` - if access to this method occurs from a module `M` and the command line option `--enable-native-access` is either absent, or does not mention the module name `M`, or `ALL-UNNAMED` in case `M` is an unnamed module.