Restricted Methods
Some methods in the Foreign Function and Memory (FFM) API are unsafe and therefore restricted. If used incorrectly, restricted methods can crash the JVM and may silently result in memory corruption.
You must enable native access if an application calls any of the following restricted methods:
Table 12-1 Restricted Methods from the FFM API
| Methods | Reasoning Behind Restricting the Methods | 
|---|---|
| The method enables native access for the specified module if the caller's module has native access. This method is restricted because it propagates privileges to call restricted methods. | |
| Once you have an address layout with a given target layout, you can use it in a dereference operation, for example, MemorySegment.get(AddressLayout, long), to resize the segment being read, which is unsafe. | |
| 
                              
                               Linker.downcallHandle(FunctionDescriptor, Linker.Option...) Linker.downcallHandle(MemorySegment, FunctionDescriptor, Linker.Option...)  | 
                           Creating a downcall method handle is intrinsically
                            unsafe. A linker has no way to verify that the provided function
                            descriptor is compatible with the function being called.
                               A symbol in a foreign library does not typically contain enough signature information, such as arity and the types of foreign function parameters, to enable the linker at runtime to validate linkage requests. When a client interacts with a downcall method handle obtained through an invalid linkage request, for example, by specifying a function descriptor featuring too many argument layouts, the result of such an interaction is unspecified and can lead to JVM crashes.  | 
                        
| 
                              
                               Linker.upcallStub(MethodHandle, FunctionDescriptor, Arena, Linker.Option...)  | 
                           As with creating downcall handles, the linker can't
                            check whether the function pointer you are creating (like the
                                qsort comparator in the example in Upcalls: Passing Java Code as a Function Pointer to a Foreign Function) is the correct one for the for the downcall you are
                            passing it to (like the qsort method handle in the same
                            example).
                            | 
                        
| 
                              
                               MemorySegment.reinterpret(long) MemorySegment.reinterpret(long, Arena, Consumer<MemorySegment>)  | 
                           These methods allows you to change the size and lifetime
                            of an existing segment by creating a new alias to the same region of
                            memory. See Foreign Functions That Return Pointers for more information.
                               The spatial or temporal bounds associated with the memory segment alias returned by these methods might be incorrect. For example, consider a region of memory that's 10 bytes long that's backing a zero-length memory segment. An application might overestimate the size of the region and use MemorySegment::reinterpret to obtain a segment that's 100 bytes long. Later, this might result in attempts to dereference memory outside the bounds of the region, which might cause a JVM crash or, even worse, result in silent memory corruption.  | 
                        
Loading a library can always cause execution of native
                            code. For example, on Linux, they can be executed through
                                dlopen hooks. 
                            | 
                        
Enabling Native Access
To enable native access for specific modules on the module path, specify a comma-separated list of module names:
java --enable-native-access=M1,M2,... MyApp
                  To enable native access for all code on the class path, use the following command-line option:
java --enable-native-access=ALL-UNNAMED MyApp
                  You can also specify the --enable-native-access option as
                follows:
                  
- Set it in the environment variable JDK_JAVA_OPTIONS. See Using the JDK_JAVA_OPTIONS Launcher Environment Variable.
 - Specify it in a command-line argument file. See java Command-Line Argument Files.
 - Add 
Enable-Native-Access: ALL-UNNAMEDto the manifest of an executable JAR file. See JAR Manifest. - If you have created a custom runtime for your application, specify it in the
                    jlink command through the 
--add-optionsplugin. Run the commandjlink –list-pluginsfor a list of available plugins. - If your code creates modules dynamically, enable native access for them with the ModuleLayer.Controller::enableNativeAccess method. Code can dynamically check if its module has native access with the Module::isNativeAccessEnabled method.
 
Enabling Native Access More Selectively
The --enable-native-access=ALL-UNNAMED option lifts native access
                restrictions for all classes on the class path. It’s recommended that you enable
                native access more selectively by moving JAR files that use the FFM API to the
                module path. This allows native access to be enabled for those JAR files
                specifically, not for the entire class path. You can move a JAR file from the class
                path to the module path without it being modularized. The Java runtime will treat it
                as an automatic module whose name is based on its file name. See Incremental Modularization with Automatic Modules.
                  
Controlling the Effect of Native Access Restrictions
If native access is not enabled for a module, then it is illegal for code in that
                module to call a restricted method. You can specify what happens when such a module
                calls a restricted method by setting the --illegal-native-access
                command-line option to one of the following values:
                  
- allow: Allows the restricted operation to proceed.
 - warn: Allows the restricted operation to proceed and issues a warning the first time that an illegal native access occurs in a particular module. At most one warning per module is issued. This is the default value in JDK 24 and later.
 - deny: Throws an IllegalCallerException for every illegal native access operation. This will be the default value in a future release of the JDK.