`

java.library.path属性在代码中设置不生效问题

    博客分类:
  • Java
阅读更多

前两天想的屏幕抓图的程序,想给加个系统全局的热键,也就是说,在程序不处于当前激活下也可响应键盘事件。通过java自己应该是实现不了了。
想到使用JNI,还好找到一篇介绍使用JIntellitype的文章,写得挺好的,下面的是链接:
http://walsece.iteye.com/blog/191169

可是在使用上面文章介绍的动态库时,遇上了加载问题,也就是将动态库放到什么位置合适?文章中说可以放到System32目录,但我不想这样做,我更希望的是可以自己定制dll库的位置~~

没有将lib放到System32目录,而是放到了自己的lib目录,程序在启动的过程中会报下面的错误:
java.lang.UnsatisfiedLinkError: no JIntellitype in java.library.path

根据上面的提示信息在VM参数处通过-Djava.library.path将加载路径指定到自己的lib目录后,程序可以正常启动。

这种方式不是太好,因为要手动的去指定虚拟机参数,于是想通过System类的setProperty函数来在代码中动态的改变一下java.library.path的值。
使用

System.setProperty("java.library.path", "./lib");   

 

后,启动程序总是报错"no JIntellitype in java.library.path"
了半天没有想明白,为什么代码的设置就不起作用,而在虚拟机参数处指定就是好的?

Google了半天才知道原因,这里整理一下,以方便以后查找。
代码中设置不起作用,主要是因为java.library.path只在jvm启动时读取一次,其他情况下的修改不会起作用的。可以参考下面的这个bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4280189

原因和ClassLoader的实现有关系,
ClassLoader.loadLibrary() method:

if (sys_paths == null) {   
        usr_paths = initializePath("java.library.path");   
        sys_paths = initializePath("sun.boot.library.path");   
}   

 

系统缓存了java.library.path的值,并且一直都会是第一次加载时的值。有人提到了下面的修改方法,

if (sys_paths == null) {   
       sys_paths = initializePath("sun.boot.library.path");   
}   
usr_paths = initializePath("java.library.path");   

 

但是从2002年到现在Sun一直都没有改,不知道出于什么原因考虑的。

有问题,就会有人解决问题,antony_miguel在一篇文章中,使用java的反射机制,完成了对于ClassLoader类中的usr_paths变量的动态修改,

public static void addDir(String s) throws IOException {   
    try {   
        Field field = ClassLoader.class.getDeclaredField("usr_paths");   
        field.setAccessible(true);   
        String[] paths = (String[])field.get(null);   
        for (int i = 0; i < paths.length; i++) {   
            if (s.equals(paths[i])) {   
                return;   
            }   
        }   
        String[] tmp = new String[paths.length+1];   
        System.arraycopy(paths,0,tmp,0,paths.length);   
        tmp[paths.length] = s;   
        field.set(null,tmp);   
    } catch (IllegalAccessException e) {   
        throw new IOException("Failed to get permissions to set library path");   
    } catch (NoSuchFieldException e) {   
        throw new IOException("Failed to get field handle to set library path");   
    }   
}   

 

 

文章也同时指出了这种实现的局限性,和jvm的实现强关联,只要jvm实现不是用的变量usr_paths来保存java.library.path的值,这个方法就不能用了。
但是只要知道源代码,小小的改动就应该可以实现了。 
 

分享到:
评论

相关推荐

    Ubantu tomocat启动报错 no opencv_java249 in java.library.path问题解决方案压缩包

    错误提示"no opencv_java249 in java.library.path"表明Java程序在运行时找不到名为`opencv_java249`的本地库,这个库是OpenCV的Java接口,用于在Java代码中调用OpenCV的功能。 2. **检查环境变量**: 首先,检查...

    java中path和classpath的设置

    在Java环境中,我们需要通过设置`path`变量来告诉操作系统在哪里可以找到`java.exe`和`javac.exe`等Java工具的可执行文件。这样,在任何目录下都能够执行这些命令。 **具体设置方法:** 假设你的JDK安装路径为`D:\...

    MAC下java调用opencv包含opencv_454.jar和libopencv_java454.dylib

    在实际开发中,可能还需要考虑兼容性问题,比如OpenCV的版本与操作系统、Java版本之间的兼容性,以及OpenCV库与特定硬件(如GPU)的交互。此外,对于复杂的计算机视觉任务,可能需要深入学习OpenCV的API,了解各种...

    Java零基础 - 环境变量PATH配置.md

    4. **添加环境变量**:在文件末尾添加以下两行代码,并将`JAVA_HOME`设置为你在步骤2中找到的路径: ```sh export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home export PATH=$JAVA...

    Java零基础 - 环境变量PATH.md

    7. **重新加载配置文件**:在终端中运行`source ~/.bash_profile`或`source ~/.zshrc`命令来使新的环境变量设置生效。 #### 三、示例源码及测试 配置好环境变量后,可以通过编写和运行一个简单的Java程序来测试...

    jsp中报c标签错误时导包

    在JavaServer Pages (JSP) 开发中,`c`标签通常指的是来自JSTL (JavaServer Pages Standard Tag Library) 的Core库中的标签。当你在JSP页面中使用`开头的标签,如`&lt;c:forEach&gt;`、`&lt;c:if&gt;`等,并遇到错误提示时,这...

    Linux下使用Java调用Hikvision设备网络SDK的使用指南.pdf

    - readme.txt文件:包含了设置环境变量的指导,即设置LD_LIBRARY_PATH环境变量,以便在系统中加载动态库。 4. 设置LD_LIBRARY_PATH环境变量的方法: - 直接在终端输入export命令,临时修改环境变量。 - 修改用户...

    完整的java成功导入openCV步骤

    为了帮助开发者们解决在Java中成功导入OpenCV的问题,下面详细阐述了导入过程中的关键步骤和注意事项。 首先,了解OpenCV的基本概念是重要的第一步。OpenCV(Open Source Computer Vision Library)是一个开源的...

    JDK--Java环境配置.zip

    2. 使用`sudo xcode-select -s /path/to/jdk`设置Java开发工具链。 3. 更新系统路径。打开`~/.bash_profile`,添加类似Linux系统的环境变量配置,然后执行`source ~/.bash_profile`。 4. 检查版本:在终端输入`java ...

    DB2 解决连接问题方案

    本篇文章主要针对"DB2连接"的问题,详细阐述如何解决在Java JSP中连接DB2数据库时遇到的`java.lang.UnsatisfiedLinkError: no db2jdbc in java.library.path`异常。 首先,我们需要理解这个异常的原因。`...

    解决eclpise中启动tomcat6出现红色警告的问题

    2. **APR Native库缺失**:如果Java环境路径(`java.library.path`)中没有包含正确的Apache Tomcat Native库,那么Tomcat将无法利用该库来提高性能。 #### 解决方案 1. **禁用`source`属性** - 在Eclipse的Servers...

    JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    在JavaWeb项目中实现dll文件的动态加载是一个需要综合运用Java本地接口...需要注意的是,使用反射技术修改系统属性可能会带来安全风险,且在不同Java版本和中间件中可能存在兼容性问题,因此在实际应用中应当谨慎使用。

    Windows下的Java访问USB库文件

    解压后,需要将包含的`.dll`文件放置到系统的`java.library.path`指定的目录下,或者通过Java的`System.loadLibrary()`方法指定加载路径。这样,Java程序就能调用libusb的功能,如枚举USB设备、打开设备、读写数据等...

    jdk1.8.0_144 (Java SE Development Kit 8u144)

    2. 安装:双击.dmg文件,按照提示完成安装过程,通常会将JDK安装在 `/Library/Java/JavaVirtualMachines` 目录下。 3. 配置环境变量:为了使系统能够识别新安装的JDK,需要更新`~/.bash_profile`或`~/.zshrc`文件,...

    Linux配置Java版gdal环境离线包

    在Linux系统中配置Java版GDAL(Geospatial Data Abstraction Library)环境通常涉及几个关键步骤,这包括安装GDAL库、配置Java绑定以及确保所有依赖项都已正确解决。GDAL是一个开源的地理空间数据处理库,它提供了对...

    Mac版本Java8下载 jdk-8u391-macosx-x64.dmg (zip)

    Java是世界上最流行的编程语言之一,尤其在企业级应用开发领域占据主导地位。Mac OS作为一款稳定且用户...在后续的开发过程中,了解和掌握Java 8的核心特性如Lambda表达式和Stream API,将有助于提高代码质量和效率。

    CXF-JAXB包的处理问题

    然而,像问题描述中那样,即使设置了这个属性,问题仍然存在,可能是因为endorsed目录的设置没有正确生效,或者有其他的类加载顺序问题。 在这种情况下,关键的解决步骤是确保JRE系统的库被正确地优先加载。这可以...

    WEBLOGIC找不到libmuxer.so 的问题

    如果需要,可以在`commEnv.sh`中添加调整`LD_LIBRARY_PATH`的代码,但需要注意的是,修改此脚本可能会影响其他WebLogic实例的配置。 总之,解决“找不到libmuxer.so”的问题需要对Unix/Linux环境和WebLogic服务器有...

Global site tag (gtag.js) - Google Analytics