Java 找不到本地方法的 .so C 库
Java not finding .so C library for native methods
我已经按照this guide访问了两个C本地方法,但是当我调用
System.loadLibrary("SensorReader");
我明白了
Exception in thread "main" java.lang.UnsatisfiedLinkError: no SensorReader in java.library.path
我已经按照指南解释我必须导出路径以使其临时工作或将 .so 库放在 ld 路径中。我什至检查了 java 属性并得到了这个:
java.library.path = .
/usr/java/packages/lib/arm
/lib
/usr/lib
但即使我将 SensorReader.so 的副本放入这些目录中的任何一个(第一个甚至不存在),也没有任何改变。
这是我制作库的 SensorReader.c 代码:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
#include <wiringPi.h>
#include <string.h>
#include "HTU21D.h"
#include "SensorController.h"
JNIEXPORT jdouble JNICALL Java_SensorController_getCurrentTemperature
(JNIEnv *env, jobject obj) {
wiringPiSetup();
int fd = wiringPiI2CSetup(HTU21D_I2C_ADDR);
double temperature;
getTemperature(fd, &temperature);
return temperature;
}
JNIEXPORT jdouble JNICALL Java_SensorController_getCurrentHumidity
(JNIEnv *env, jobject obj) {
wiringPiSetup();
int fd = wiringPiI2CSetup(HTU21D_I2C_ADDR);
double humidity;
getHumidity(fd, &humidity);
return humidity;
}
正在执行
$ gcc -fPIC -c SensorReader.c -I $JAVA_HOME/include -I $JAVA_HOME/include/Linux
$ gcc SensorReader.o -shared -o SensorReader.so -Wl,-soname,SensorReader
returns 没有错误,SensorReader.so 文件已创建,我只是在尝试 运行 Java 时遇到问题。
我不确定,但我认为 .so 库是在执行时调用的,而不是在编译时调用的,但以防万一我尝试同时执行和编译然后直接在目标 Raspberry 设备上执行代码并且没有任何改变。
远景:我在尝试使用 32 位 java 虚拟机加载 64 位编译本机库时遇到了类似的问题。您应该确保两者都是 64 位(如果更符合您的需要,则为 32 位)。
在任何其他情况下,我会再次查看库路径。
所以显然错误的是 "SensorReader.so" 文件名之前缺少 "lib"。
改变
$ gcc SensorReader.o -shared -o SensorReader.so -Wl,-soname,SensorReader
与
$ gcc SensorReader.o -shared -o libSensorReader.so -Wl,-soname,SensorReader
或者可能只是重命名 .so 文件,然后将其移动到 /lib 并执行
# ldconfig
解决了问题,现在 Java 确实找到了图书馆。
我已经按照this guide访问了两个C本地方法,但是当我调用
System.loadLibrary("SensorReader");
我明白了
Exception in thread "main" java.lang.UnsatisfiedLinkError: no SensorReader in java.library.path
我已经按照指南解释我必须导出路径以使其临时工作或将 .so 库放在 ld 路径中。我什至检查了 java 属性并得到了这个:
java.library.path = .
/usr/java/packages/lib/arm
/lib
/usr/lib
但即使我将 SensorReader.so 的副本放入这些目录中的任何一个(第一个甚至不存在),也没有任何改变。 这是我制作库的 SensorReader.c 代码:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
#include <wiringPi.h>
#include <string.h>
#include "HTU21D.h"
#include "SensorController.h"
JNIEXPORT jdouble JNICALL Java_SensorController_getCurrentTemperature
(JNIEnv *env, jobject obj) {
wiringPiSetup();
int fd = wiringPiI2CSetup(HTU21D_I2C_ADDR);
double temperature;
getTemperature(fd, &temperature);
return temperature;
}
JNIEXPORT jdouble JNICALL Java_SensorController_getCurrentHumidity
(JNIEnv *env, jobject obj) {
wiringPiSetup();
int fd = wiringPiI2CSetup(HTU21D_I2C_ADDR);
double humidity;
getHumidity(fd, &humidity);
return humidity;
}
正在执行
$ gcc -fPIC -c SensorReader.c -I $JAVA_HOME/include -I $JAVA_HOME/include/Linux
$ gcc SensorReader.o -shared -o SensorReader.so -Wl,-soname,SensorReader
returns 没有错误,SensorReader.so 文件已创建,我只是在尝试 运行 Java 时遇到问题。 我不确定,但我认为 .so 库是在执行时调用的,而不是在编译时调用的,但以防万一我尝试同时执行和编译然后直接在目标 Raspberry 设备上执行代码并且没有任何改变。
远景:我在尝试使用 32 位 java 虚拟机加载 64 位编译本机库时遇到了类似的问题。您应该确保两者都是 64 位(如果更符合您的需要,则为 32 位)。
在任何其他情况下,我会再次查看库路径。
所以显然错误的是 "SensorReader.so" 文件名之前缺少 "lib"。
改变
$ gcc SensorReader.o -shared -o SensorReader.so -Wl,-soname,SensorReader
与
$ gcc SensorReader.o -shared -o libSensorReader.so -Wl,-soname,SensorReader
或者可能只是重命名 .so 文件,然后将其移动到 /lib 并执行
# ldconfig
解决了问题,现在 Java 确实找到了图书馆。