-
Notifications
You must be signed in to change notification settings - Fork 45
jni path
landon edited this page Sep 14, 2018
·
1 revision
- 使用jnlua
- LuaState这个类的静态初始化器会load
- System.loadLibrary("jnlua5.1")
- 关于System.loadLibrary的执行过程
- 网上几乎大部分都是说加载这个库默认是去java.library.path去load
- 这个说法没有大的问题 但还是有问题的 可以看后面的测试
- 测试过程1(windows为主)
- eclipse中首先输出:System.getProperty("java.library.path")
- 输出结果包括jre的目录/windows库目录/path目录/eclipse目录/当前目录
- 直接将jnlua5.1.dll扔到jre\bin目录,测试load,可以顺利加载到这个dll
- 脱离eclipse运行,命令行下输出System.getProperty("java.library.path")
- 输出结果没有jre的目录和eclipse目录等
- 直接将jnlua5.1.dll扔到jre\bin目录,测试load,发现也可以顺利load
- 问题:在命令行下,java.library.path根本没有jre\bin这个目录,为什么也能load成功
- eclipse中首先输出:System.getProperty("java.library.path")
- 测试过程1总结
- 去看了看System.loadLibrary的源代码{@link ClassLoader#loadLibrary},这里加载库,其实是有两个路径,一个是sys_paths#sun.boot.library.path,另外一个是usr_paths#sun.boot.library.path,而且是前者优先加载的
- 命令行下输出System.getProperty("sun.boot.library.path"),发现这个路径就是jre\bin目录
- 第一个总结:
- System.loadLibrary这个库加载是优先去sun.boot.library.path这个path去加载,如果没有才去java.library.path去加载
- 第二个总结:
- eclipse的一些路径输出和命令下的可能不同,不要认为在eclipse下测试通过,在实际命令下就通过,需要实际测试,尤其是涉及到路径相关
- 测试过程2(windows为主)
- 加载库的时候,有时候需要加载依赖的库,如jnlua.dll需要依赖lua5.1.dll
- 那么这个依赖的库是从什么路径加载的呢?
- java.library.path is for JNI libraries only, not libraries they depend on. The system path is used for those.you should set PATH, LD_LIBRARY_PATH, or DYLD_LIBRARY_PATH (on Windows, Linux, or OSX respectively)
- 即依赖加载的库是取决于是os本身,对于window来说通常是PATH,对于linux是LD_LIBRARY_PATH
- 这也解释了为什么你本地如果装了lua(lua会被配置在环境变量),加载jnilua不会报错的原因,因为会默认的去path加载依赖的lua5.1.dll
- 最终总结(不限于Windows/linux/mac)
- System.loadLibrary加载路径首先是sun.boot.library.path,然后才是java.library.path
- 如果找不到则直接抛出java.lang.UnsatisfiedLinkError: no jnlua5.1 in java.library.path
- 对于加载库所依赖的库加载,是os本身去加载的,和上面jvm的两个路径没有一毛钱关系.通常是如path(windows),ld_library_path(linux)等
- 如果找不到依赖,则抛出java.lang.UnsatisfiedLinkError: Can't find dependent libraries
- java.library.path默认包括path/ld_library_path
- 所以对于加载的库和依赖库的位置最好放在path或者ld_library_path下即可
- eclipse中输出的路径和命令下输出的路径不同
- 关于路径的测试一定要实际去测试,否则可能IDE下的结果和命令下的结果不同
- 不建议启动参数-Djava.library.path 这个会覆盖掉默认的路径,可能会出现一些问题
- System.loadLibrary加载路径首先是sun.boot.library.path,然后才是java.library.path