System.loadLibrary()是在使用Java的JNI机制时


System.loadLibrary()是在使用Java的JNI机制时,会用到的一个非常重要的函数,它的作用即是把实现native方法的那个链接库load进来,或者load其他什么动态连接库。

System.loadLib()的实现(code在libcore/luni/src/main/java/java/lang/System.java这个文件中):
/**
 * Loads and links the library with the specified name. The mapping of the
 * specified library name to the full path for loading the library is
 * implementation-dependent.
 *
 * @param libName
 *            the name of the library to load.
 * @throws UnsatisfiedLinkError
 *             if the library could no<span style="color:#003399;"></span>t be loaded.
 */
public static void loadLibrary(String libName) {
    Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
}

Java中,`System.loadLibrary()`方法用于加载动态链接库(`.dll`、`.so`或`.dylib`文件),但具体文件的读取路径和方式取决于JVM的规则和操作系统的配置。以下是详细说明和解决方法: --- ### **1. 动态库的加载规则** - **`System.loadLibrary(String libname)`**: - 参数是库的**名称**(如`tpmp4`),而非文件名(如`tpmp4.dll`)。 - JVM会根据操作系统的规则,在以下路径中搜索库文件: 1. **JVM的默认库路径**:通过`java.library.path`系统属性指定。 2. **临目录**:某些情况下,JVM可能从临目录加载(如通过`-Djava.io.tmpdir`指定)。 3. **绝对路径**:如果库文件位于JVM的库搜索路径中。 - **文件命名规则**: - **Windows**:`tpmp4.dll` - **Linux**:`libtpmp4.so` - **macOS**:`libtpmp4.dylib` --- ### **2. 如何确保库文件被正确加载?** #### **方法1:将库文件放在JVM的默认搜索路径中** 1. **查找`java.library.path`**: ```java System.out.println(System.getProperty("java.library.path")); ``` 输出示例: ``` /usr/lib:/usr/local/lib:/path/to/your/libs ``` 2. **将库文件(如`libtpmp4.so`和`libtpmp4jni.so`)复制到上述路径之一**。 #### **方法2:通过启动参数指定库路径** 在启动JVM,显式指定库路径: ```bash java -Djava.library.path=/path/to/libs -jar YourApp.jar ``` #### **方法3:使用绝对路径加载** 如果库文件不在默认路径中,可以使用`System.load()`直接指定绝对路径: ```java static { System.load("/absolute/path/to/libtpmp4.so"); System.load("/absolute/path/to/libtpmp4jni.so"); } ``` #### **方法4:打包库文件到JAR中并动态提取** 如果库文件打包在JAR的`resources`目录下,可以通过以下步骤加载: 1. **从JAR中提取库文件到临目录**: ```java private static void extractLibrary(String name) throws IOException { String resourcePath = "/" + name + ".dll"; // 根据操作系统调整后缀 InputStream in = YourClass.class.getResourceAsStream(resourcePath); if (in == null) { throw new FileNotFoundException("Library not found: " + resourcePath); } Path tempFile = Files.createTempFile(name, ".dll"); Files.copy(in, tempFile, StandardCopyOption.REPLACE_EXISTING); in.close(); System.load(tempFile.toAbsolutePath().toString()); } static { try { extractLibrary("tpmp4"); extractLibrary("tpmp4jni"); } catch (IOException e) { throw new RuntimeException("Failed to load libraries", e); } } ``` --- ### **3. 常见问题排查** 1. **`UnsatisfiedLinkError`**: - 原因:库文件未找到或格式不匹配(如32位/64位冲突)。 - 解决:检查文件名、路径和操作系统兼容性。 2. **依赖其他库**: - 如果`tpmp4jni`依赖`tpmp4`,需确保加载顺序正确(如代码中先加载`tpmp4`)。 3. **调试技巧**: - 使用`ldd`(Linux)或`Dependency Walker`(Windows)检查库的依赖是否完整。 --- ### **4. 示例代码(完整流程)** ```java public class LibraryLoader { static { try { // 方法1:通过java.library.path加载 System.loadLibrary("tpmp4"); System.loadLibrary("tpmp4jni"); // 或者方法2:使用绝对路径 // System.load("/opt/libs/libtpmp4.so"); // System.load("/opt/libs/libtpmp4jni.so"); } catch (UnsatisfiedLinkError e) { System.err.println("Failed to load libraries: " + e.getMessage()); System.exit(1); } } public static void main(String[] args) { System.out.println("Libraries loaded successfully!"); } } ``` --- ### **总结** - **关键点**:`System.loadLibrary()`依赖`java.library.path`或系统默认路径,需确保库文件命名正确且位于搜索路径中。 - **推荐做法**: 1. 使用`-Djava.library.path`指定路径。 2. 或通过代码动态提取库文件到临目录后加载。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值