[转]Linux下使用JNI的常见问题及解决方案

Linux下使用JNI的常见问题及解决方案

转载地址:http://www.cnblogs.com/javawebsoa/p/3220069.html

我碰到的问题是bad value

参考这里解决的

linux生成动态库时遇到了relocation R_X86_64_32 against `.rodata‘ can not be used when making a shared object; recompile with -fPIC错误。

由于我的系统是AMD64位的,所以需要在编译的时候添加 -fPIC选项

解决方法:

例如:

g++ -c -fPIC head.cpp    生成head.o

g++ -fpic -shared -o libfun.so head.o

JNI是java和C/C++混合编程的接口,可以很方便地实现java调用C/C++语言。具体的使用方法,网上有很多教程,在此不做过多介绍。本博客只关注在使用JNI的过程中的常见问题。

1.     生成头文件用命令:javah*.class

这是错误的。运行上述命令会提示:java.lang.IllegalArgumentException: Not a valid class name:SegNative.class错误。错误原因和利用java命令运行程序一样,只需要指出前缀即可,无需给出.class后缀。

2.     版本问题

jdk6和jdk7中某些JNI方法稍有不同,注意转换。例如,C中获取字符串的方法GetStringUTFChars在两个jdk版本中就不同。老的jdk6版本使用方法为:

char* name=(char*)(*env)->GetStringUTFChars(env,Name,NULL);

而在jdk7中,方法调用变为:

const char* name=env->GetStringUTFChars(Name,0);

其他的版本问题及函数参数含义可以通过查看API获得更全面的资料。

3.     利用g++编译源文件找不到jni.h头文件

可以在编译时利用-I选项指定jni.h头文件所在目录:

g++ -I/usr/local/jdk1.7.0_25/include/ ……

4.     利用g++编译源文件找不到jni_md.h

这是因为在jni.h中引用了jni_md.h头文件,该头文件和jni.h不在一个目录下,所以我们还需要再指定jni_md.h的目录:

g++ -I/usr/local/jdk1.7.0_25/include/  -I/usr/local/jdk1.7.0_25/include/linux/……

可以看出jni_md.h放在和jni.h同级的目录linux下。

5.     不会生成动态链接库

生成动态链接库,需要在编译时声明-shared选项:

g++ -I /usr/local/jdk1.7.0_25/include/  -I /usr/local/jdk1.7.0_25/include/linux/SegNative.cpp –shared –o lib***.so

此外,我们也无需先生成相应的.o文件,直接指定动态链接库的名字即可。

6.     编译动态链接库报错:couldnot read symbols: Bad value

需要在编译的时候指定选项:-fPIC。

g++ -I /usr/local/jdk1.7.0_25/include/  -I /usr/local/jdk1.7.0_25/include/linux/SegNative.cpp –shared –o lib***.so -fPIC

7.     运行的时候找不到动态链接库

这个问题主要有两个原因:

  • 生成的动态链接库名字不对:我们在java语言中声明的动态链接库如果名为A,则我们在编译时则需要将动态链接库的名字声明为libA.so,否则会报错。
  • 路径不对,java找不到动态链接库。java会在特定的目录寻找动态链接库,可以通过打印java.library.path查看java会在哪些目录查找动态链接库:
System.out.println(System.getProperty("java.library.path"));

我的电脑打印结果为:

.:/opt/intel/impi/3.2.1.009/lib/:/usr/local/cuda/lib/:/root/NVIDIA_CUDA_SDK/lib/:/root/NVIDIA_CUDA_SDK/common/lib/:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib

我们可以看到相关lib都包括在该路径下。特别注意一点是第一个路径是.,这表示java会在当前路径下寻找相关动态链接库。因而只要我们将动态链接库和.class文件放在一起就不会存在找不到动态链接库的问题。如果打印中不包括当前目录,我们可以通过修改LD_LIBRARY_PATH指定当前目录。

此外,我们也可以在运行的过程中指定:

java –Djava.library.path=”/home/savedlib/”executablefile

利用这种方法,程序可以指定不在当前目录的动态链接库。

时间: 2024-10-29 19:11:20

[转]Linux下使用JNI的常见问题及解决方案的相关文章

Linux下使用JNI的常见问题及解决方案

JNI是java和C/C++混合编程的接口,可以很方便地实现java调用C/C++语言.具体的使用方法,网上有很多教程,在此不做过多介绍.本博客只关注在使用JNI的过程中的常见问题. 1.     生成头文件用命令:javah*.class 这是错误的.运行上述命令会提示:java.lang.IllegalArgumentException: Not a valid class name:SegNative.class错误.错误原因和利用java命令运行程序一样,只需要指出前缀即可,无需给出.c

Linux下实现JNI期间发生的错误……【未解决】

万能的博客园啊……希望发完这个问题记录后能尽快发现自己的错误%>_<% 问题描述: 在linux下通过gcc命令编译c文件生成动态链接库.so文件时报错.之前命令内导入了jni.h和jni_md.h所在路径,报错:之后将这两个头文件复制到/usr/include/路径下, 导入,仍报错. 检查了一下JAVA_HOME路径.java.javac命令都能正常运行,普通的.c文件也能正常编译.根据报错的提示来看是.h文件中的jint.jbyte...未定义...不过根据我 浅薄的认知,这些变量不就在

Linux的zookeeper集群常见问题及解决方案

文章中所提到问题为自己遇到的问题及收集他人遇到的问题的整合 问题一: 启动报错: 解决方案: 1.查看系统防火墙是否已经关闭 如果开启状态,进行关闭 2.产生的原因:只在一台节点上启动了zookeeper,其他的节点上没有启动zookeeper,会导致拒绝连接,去其他节点启动即可 3.将linux的hosts文件的127.0.0.1那一行删掉或者注释 原因:端口绑定的地址不是127.0.0.1所以不能用这个地址 问题二: 前提:使用zookeeper版本为3.5.4 beta,jdk版本为1.8

linux下SSH远程连接服务慢解决方案

1.适用命令及方案如下:[远程连接及执行命令]ssh -p22[email protected]ssh -p22 [email protected] /sbin/ifconfig[远程拷贝:推送及拉取]scp -P22 -r -p /etc [email protected]:/tmp/scp -P22 -r -p [email protected]:/tmp/ /etc[安全的FTP功能]sftp -oPort=22 [email protected][无密码验证方案]例如利用sshkey批量

linux下mysql的root密码忘记解决方案

1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录和修改MySQL的信息.可以采用将MySQL对 外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全 状态.最安全的状态是到服务器的Console上面操作,并且拔掉网线. 2.修改MySQL的登录设置: # vi /etc/my.cnf 在[mysqld]的段中加上一句:sk

Linux 下 zip 文件解压乱码解决方案,ubuntu16.10亲测可用

文章来源: https://www.zhihu.com/question/20523036 今天邮件中收到了一个压缩文件,解压后却是乱码,从网上也找了几个方法,目前这个方法还是比较可靠的,如下所示: 7z方案 需要安装p7zip和convmv,在Fedora下的命令是 su -c 'yum install p7zip convmv' 在ubuntu下的安装命令是 sudo apt-get install p7zip convmv 安装完之后,就可以用7za和convmv两个命令完成解压缩任务.

在Linux下开发多语言软件(gettext解决方案)

最近的项目出现了一个bug.项目是基于一个已有的成熟开源软件之上做修改的,新写了加解密库,用于为该成熟开源软件增添加解密功能.功能增加完成后效果都很好,可是就是中文出不来了,也就是说没办法自适应多语言环境了(提示信息在中文操作系统下是中文,英文操作系统下是英文).使用strace -o log [要调试的命令]定位出了其在执行期间调用的语言包情况,发现它并没有调用自有的语言包,反而调用了加解密库的语言包(但是这个加解密库就没有开发任何语言包),导致找不到该语言包而默认显示代码中的英文提示信息.经

linux下rtnetlink answers file exists的解决方案

之前部署hadoop环境,在自己机器上安装了一台centos虚拟机,然后图省事,就克隆出三台,一台为master,另两台来作为 slave. 好久没用过了,昨天本想调试一下hadoop源码,打开后发现有一台主机连不上网.一直显示 "rtnetlink answers file exists" 之前也遇到过这种情况,克隆的虚拟机在网卡一直有问题,也没有太担心,无非是两种方案: 第一种: 和 NetworkManager 服务有冲突,这个好解决,直接关闭 NetworkManger 服务就

虚拟机下的JNI

对于别人写的linux下的jni写的真的不清晰.明了,甚至会出现错误:对于代码重点的就是不会的人用你的代码就可以执行就ok了!!好了,废话不说了,来开始咱们的jni了: 首先咱们得理解一下jni的概念吧: jni(java native interface)java原生接口:对于学习过java的我们并不陌生接口的概念吧,接口就是定义一系列的方法,让其实现类来实现:好了,咱们直接上代码,用代码来解决一切: 第一个程序:对于java类的属性赋值: 首先看看完成后的文件: 首先新建TestInt.ja