Andrea de'Rose
Andrea de'Rose

Reputation: 57

Java not finding .so C library for native methods

I've followed this guide to access two C native methods, but when I call

 System.loadLibrary("SensorReader");

I get

Exception in thread "main" java.lang.UnsatisfiedLinkError: no SensorReader in java.library.path

I've followed the guide explaining I have to export the path to have it working temporarily or put the .so library in ld paths. I've even checked for java properties and got this:

java.library.path = .
    /usr/java/packages/lib/arm
    /lib
    /usr/lib

but even if I put a copy of SensorReader.so in any of those directories (the first one doesn't even exist) nothing changes. Here is the SensorReader.c code I made the library with:

#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;
}

Executing

$ 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 no errors and the SensorReader.so file is created, I just get the problem when I try to run Java. I'm not sure but I think the .so library is called on execution and not on compilation, but just in case I've tried both to just execute and compile then execute the code directly on the target Raspberry device and nothing changed.

Upvotes: 0

Views: 120

Answers (2)

Andrea de&#39;Rose
Andrea de&#39;Rose

Reputation: 57

So apparently the wrong thing was the missing "lib" before "SensorReader.so" file name.

Changing

$ gcc SensorReader.o -shared -o SensorReader.so -Wl,-soname,SensorReader

with

$ gcc SensorReader.o -shared -o libSensorReader.so -Wl,-soname,SensorReader

or maybe just renaming the .so file, then moving it to /lib and executing

# ldconfig

solved the problem and now Java actually finds the library.

Upvotes: 1

Jorge_B
Jorge_B

Reputation: 9872

Just a long shot: I have had similar problems trying to load a 64-bit compiled native library with a 32-bit java virtual machine. You should make sure that both are 64-bit (or 32-bit if it fits better your needs).

In any other case, I would have a second look at the library paths.

Upvotes: 0

Related Questions