Class JLineNativeLoader
This class handles the discovery, extraction, and loading of the appropriate native library for the current platform. The native libraries are essential for certain terminal operations that require direct system calls.
Usage
Callinitialize() before using JLine features that require native support:
JLineNativeLoader.initialize();
Library Loading Process
The loader attempts to find and load the native library in the following order:- From the path specified by the
library.jline.pathsystem property - From the JAR file's embedded native libraries
- From the Java library path (
java.library.path)
Configuration Options
The following system properties can be used to configure the native library loading:library.jline.path- Custom directory path where native libraries are located. The loader will check both[library.jline.path]/[os]/[arch]and[library.jline.path]directly.library.jline.name- Custom name for the native library file. If not specified, the default name will be used (e.g., "jlinenative.dll" on Windows).jline.tmpdir- Custom temporary directory for extracting native libraries. If not specified,java.io.tmpdirwill be used.java.library.path- Standard Java property for native library search paths, used as a last resort.
Platform Detection
The loader automatically detects the current operating system and architecture usingOSInfo to determine which native library to load. Supported platforms include:
- Operating Systems: Windows, macOS (Darwin), Linux, AIX
- Architectures: x86, x86_64 (amd64), ARM (various versions), PowerPC, and others
Temporary Files
When loading from the JAR file, the native library is extracted to a temporary location. These temporary files:- Include version and UUID in the filename to avoid conflicts
- Are automatically cleaned up on JVM exit
- Old unused libraries from previous runs are cleaned up
Troubleshooting
If the library fails to load, an exception is thrown with details about:- The detected OS and architecture
- All paths that were searched
- The specific error that occurred
Java Module System (JPMS) Considerations
When using JLine with the Java Module System, you may need to add the--enable-native-access=ALL-UNNAMED JVM option to allow the native library loading.- See Also:
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) static voidcleanup()Cleans up old native library files from previous runs.private static StringcontentsEquals(InputStream in1, InputStream in2) private static voidcopy(InputStream in, OutputStream out) private static booleanextractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName, String targetFolder) Extracts a native library from the JAR file and loads it.static intReturns the major version number of the JLine library.static intReturns the minor version number of the JLine library.static StringReturns the absolute path to the loaded native library file.static StringReturns the source URL from which the native library was loaded.private static FileReturns the temporary directory used for extracting native libraries.static StringReturns the full version string of the JLine library.private static booleanhasResource(String path) static booleanLoads the JLine native library for the current platform.private static Stringprivate static voidCore method that handles the JLine native library loading process.private static booleanloadNativeLibrary(File libPath) Loads a native library from a specific file path.private static void(package private) static OutputStreamnewExclusiveStream(File file) Opens an output stream that creates a brand new file, failing if the path already exists.private static Stringprivate static intreadNBytes(InputStream in, byte[] b)
-
Field Details
-
logger
-
loaded
private static boolean loaded -
nativeLibraryPath
-
nativeLibrarySourceUrl
-
-
Constructor Details
-
JLineNativeLoader
public JLineNativeLoader()
-
-
Method Details
-
initialize
public static boolean initialize()Loads the JLine native library for the current platform.This method should be called before using any JLine features that require native support. It handles the discovery, extraction, and loading of the appropriate native library.
The method is thread-safe and idempotent - calling it multiple times has no additional effect after the first successful call. A background thread is started to clean up old native library files from previous runs.
If the library cannot be loaded, a
RuntimeExceptionis thrown with detailed information about the failure, including the OS, architecture, and paths that were searched.Example usage:
try { JLineNativeLoader.initialize(); // JLine features that require native support can be used here } catch (RuntimeException e) { // Handle the case where native library cannot be loaded System.err.println("JLine native support not available: " + e.getMessage()); }- Returns:
- True if the JLine native library is successfully loaded; this will always be true if the method returns normally, as it throws an exception on failure.
- Throws:
RuntimeException- If the native library cannot be loaded for any reason.
-
getNativeLibraryPath
Returns the absolute path to the loaded native library file.This method can be used to determine which specific native library file was successfully loaded. It's particularly useful for debugging and logging purposes.
Note: This method will return null if called before
initialize()or if the library failed to load.- Returns:
- The absolute path to the loaded native library file, or null if the library hasn't been loaded.
-
getNativeLibrarySourceUrl
Returns the source URL from which the native library was loaded.This is typically a jar:file: URL pointing to the location within the JAR file from which the native library was extracted. This information can be useful for debugging and logging purposes.
Note: This method will return null if called before
initialize()or if the library failed to load, or if the library was loaded from the filesystem rather than extracted from a JAR.- Returns:
- The source URL of the loaded native library, or null if not applicable or if the library hasn't been loaded.
-
getTempDir
Returns the temporary directory used for extracting native libraries.The directory is determined by checking the following system properties in order:
jline.tmpdir- Custom JLine-specific temporary directoryjava.io.tmpdir- Standard Java temporary directory
- Returns:
- A File object representing the temporary directory.
-
cleanup
static void cleanup()Cleans up old native library files from previous runs.This method is called automatically by
initialize()to remove old native library files that might have been left behind, particularly on Windows where DLL files are not always properly removed on JVM exit (see bug #80).The cleanup process:
- Scans the temporary directory for files matching the pattern "jlinenative-[version]*"
- Checks if each file has an associated lock file (.lck extension)
- Deletes files that don't have an associated lock file, as they are from previous runs
This method is run in a low-priority daemon thread to avoid impacting application startup time.
-
readNBytes
- Throws:
IOException
-
contentsEquals
- Throws:
IOException
-
extractAndLoadLibraryFile
private static boolean extractAndLoadLibraryFile(String libFolderForCurrentOS, String libraryFileName, String targetFolder) Extracts a native library from the JAR file and loads it.This method handles the process of extracting a native library from within the JAR file to a temporary location on the filesystem, and then loading it using
System.load(String).The extraction process includes several important steps:
- Creating a unique filename for the extracted library to avoid conflicts
- Creating a lock file to indicate that the library is in use
- Extracting the library content from the JAR to the temporary file
- Setting appropriate file permissions (readable, writable, executable)
- Verifying that the extraction was successful by comparing file contents
- Loading the extracted library using
System.load(String)
The extracted files are marked for deletion on JVM exit using
File.deleteOnExit(), but on some platforms (particularly Windows), this may not always work reliably.- Parameters:
libFolderForCurrentOS- The path within the JAR file to the native library for the current OS/architecture.libraryFileName- The filename of the native library.targetFolder- The target folder where the library will be extracted.- Returns:
- True if the library was successfully extracted and loaded; false otherwise.
-
randomUUID
-
newExclusiveStream
Opens an output stream that creates a brand new file, failing if the path already exists.CREATE_NEWmaps to an exclusive create at the OS level, so a symlink or a regular file planted at the target path in the shared temp directory is rejected rather than followed.- Throws:
IOException
-
copy
- Throws:
IOException
-
loadNativeLibrary
Loads a native library from a specific file path.This method attempts to load a native library using
System.load(String), which requires an absolute path to the library file. If successful, it sets thenativeLibraryPathfield to the absolute path of the loaded library.The method handles the following cases:
- If the file doesn't exist, it returns false without attempting to load
- If loading fails with an
UnsatisfiedLinkError, it logs the error and returns false - If loading succeeds, it sets the path and returns true
- Parameters:
libPath- A File object representing the absolute path to the native library file.- Returns:
- True if the library was successfully loaded; false otherwise.
-
loadJLineNativeLibrary
Core method that handles the JLine native library loading process.This method implements the library loading strategy, attempting to load the native library from various locations in a specific order. It's called by
initialize()and should not be called directly.The loading process follows this sequence:
- If the library is already loaded, return immediately
- Try loading from the custom path specified by
library.jline.pathsystem property:- First check
[library.jline.path]/[os]/[arch]/[library.name] - Then check
[library.jline.path]/[library.name]
- First check
- Try extracting and loading from the JAR file's embedded native libraries
- Try loading from each path in the
java.library.pathsystem property - If all attempts fail, throw an exception with detailed information
- Throws:
Exception- If the native library cannot be loaded from any location. The exception includes details about the OS, architecture, and paths searched.
-
hasResource
-
getMajorVersion
public static int getMajorVersion()Returns the major version number of the JLine library.This method extracts the major version number from the full version string. For example, if the version is "3.21.0", this method returns 3.
The version information is read from the Maven POM properties file in the JAR. If the version cannot be determined, 1 is returned as a default value.
- Returns:
- The major version number of the JLine library, or 1 if it cannot be determined.
- See Also:
-
getMinorVersion
public static int getMinorVersion()Returns the minor version number of the JLine library.This method extracts the minor version number from the full version string. For example, if the version is "3.21.0", this method returns 21.
The version information is read from the Maven POM properties file in the JAR. If the version cannot be determined or doesn't have a minor component, 0 is returned as a default value.
- Returns:
- The minor version number of the JLine library, or 0 if it cannot be determined.
- See Also:
-
getVersion
Returns the full version string of the JLine library.This method retrieves the version information from the Maven POM properties file in the JAR at "/META-INF/maven/org.jline/jline-native/pom.properties".
The version string is cleaned to include only numeric values and dots (e.g., "3.21.0"). If the version information cannot be determined (e.g., the properties file is missing or cannot be read), "unknown" is returned.
This version information is used in the naming of temporary native library files to ensure proper versioning and avoid conflicts between different JLine versions.
- Returns:
- The version string of the JLine library, or "unknown" if it cannot be determined.
-
join
-
log
-