[Resolvido} Fazer funcionar JNI no Netbeans

1 resposta
I

Olá pessoal,

Estou precisando de ajuda novamente, dessa vez com o java. Fugi do Netbeans antes, mas agora não vai ter jeito. Tenho que integrar meu código C++ num projeto java que está pronto no Netbeans.

Meu código funciona na chamada via terminal, mas no Netbeans dá erro:
“Exception in thread “main” java.lang.UnsatisfiedLinkError: teste.JSensor.openSensor()V
at teste.JSensor.openSensor(Native Method)
at teste.Teste.main(Teste.java:21)

Já li muita coisa do google sobre o erro, mas nada me resolveu o problema. E deve ser algo bobo que está causando isso, mas como não tenho pratica nenhuma com java e pouca com linux, estou apanhando pra resolver.

O sistema está estruturado da seguinte maneira:

1- Tenho um .h e um libsensor.so, que veio com o sensor.

2- Criei um CSensor.cpp e CSensor.h com a manipulação do sensor;

3- Criei um JSensor.cpp pra servir de espelho das funções java, com as chamadas para as funções escritas no CSensor.cpp

4- Criei o JSensor.java

5- Criei o JSensor.h usando o javah

6- Compilei o JSensor.cpp (g++ -Wall -shared -fPIC -o libJSensor.so JSensor.cpp -pthread -std=c++11)

7- Copiei o .so gerado e colei na pasta onde está o código java e o .h do javah

8- Compilei o java

9- Executei usando -Djava.library.path="/home/meunome/JAVA" como parâmetro

Desse jeito funciona.
Agora no netbeans…

Abri um projeto novo, e em “Propriedades -> Bibliotecas” adicionei um .jar gerado com os arquivos acima (java e .so), mas deu o erro.
Adicionei o.so na pasta /lib e /usr/lib, mas não mudou nada.
Apaguei a biblioteca jar e criei uma classe dentro do próprio projeto com o código copiado do arquivo java que gerou o jar, e o erro não mudou.
Configurei para o projeto usar uma pasta de bibliotecas compartilhadas e coloquei os códigos lá dentro, e nada.
Até tentei jogar o libJSensor.so dentro da raiz do projeto e da pasta src.

Não sei mais o que fazer.
Sei que o código feito por mim e o JNI está ok, porque funciona via terminal

Alguém sabe dizer o que estou fazendo errado?

Abs.

1 Resposta

I

Já consegui resolver o problema. Vou descrever aqui a solução pois pode ser útil pra mais alguém.

O NetBeans cria automaticamente um pacote com as classes do projeto, mas o javah estava criando os cabeçalhos (não sei se é esse o termo correto) dos métodos sem nenhum nome do pacote, já que gerei ele com o comando javah da classe que eu tinha antes de passar para o Netbeans.

Os cabeçalhos que eu tinha eram algo assim:
Java_JSensor_openSensor(

(o padrão de criação é Java_nomedopacote_nome da classe_nome do metodo, mas como não tinha pacote, omitiu essa parte)

O Netbeans procurava por um cabeçalho assim:
Java_teste_JSensor_openSensor

Por isso carregava a biblioteca mas não achava o método.

Outra coisa que eu notei que pode dar erro de UnsatisfiedLinkError, mas com “undefined symbol”, é quando o código C++ possui mais de uma classe. Por exemplo, no meu caso tinha o JSensor.cpp e o CSensor.cpp, sendo que esse último é usado pelo anterior. Na hora de compilar, tem que colocar todos os .cpp na chamada do compliador pra gerar o .so, senão depois o método faz uma chamada pra um comando não definido na biblioteca e dá esse erro.

Ficaria algo assim:
g++ -share <demais parâmetros de compilação> libJSensor.so CSensor.cpp JSensor.cpp

O comando para saber quais undefined symbols tem no arquivo .so é:
ldd -d -r <nome do .so>

Espero que seja útil pra alguém.

Abraço!

Criado 14 de outubro de 2013
Ultima resposta 16 de out. de 2013
Respostas 1
Participantes 1