Jni

28 respostas
T

Estou com problema para conectar Java e C, via JNI, sempre está dando UnsatisfieldLinkError. Vejam como estou fazendo pra usar em um simples helloworld:

HelloNative.java:

public class HelloNative {

public static native void greeting();

static {

System.loadLibrary(libHelloNative.dll);

}

}

HelloNative.h atrevés do javah:
/* DO NOT EDIT THIS FILE - it is machine generated /
#include <jni.h>
/
Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern “C” {
#endif
/*

  • Class: HelloNative
  • Method: greeting
  • Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloNative_greeting
    (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

HelloNative.c
#include “HelloNative.h”
#include<stdio.h>

JNIEXPORT void JNICALL Java_HelloNative_greeting

(JNIEnv *env, jclass cl)

{

printf(Hello world!!!\n);

}
e a classe principal

HelloNativeTest.java:

class HelloNativeTest {

public static void main(String args[]) {

HelloNative.greeting();

}

}

para compilar os arquivos java, estou fazendo java

para compilar o arquivo .c, usando gcc que vem com o DevC++:
gcc -o libHelloNative.dll HelloNative.c -I “C:\Arquivos de programas\Java\jdk1.5.0_04\include” -I “C:\Arquivos
de programas\Java\jdk1.5.0_04\include\win32” -c

eu também tentei colocar -c no lugar de -shared e nada

quando eu vou colocar para funcionar eu uso:

java HelloNativeTest

, mas sempre  essa saída:

Exception in thread main java.lang.UnsatisfiedLinkError: no libHelloNative.dll

in java.library.path

at java.lang.ClassLoader.loadLibrary(Unknown Source)

at java.lang.Runtime.loadLibrary0(Unknown Source)

at java.lang.System.loadLibrary(Unknown Source)

at HelloNative.(HelloNative.java:4)

at HelloNativeTest.main(HelloNativeTest.java:3)

eu tentei usar o método load, em vez do loadLibrary, mas consegui apenas no Linux e colocando o endereço absoluto(apenas com enedereço relativo não funcionava), no Ruindows não sai. Eu dei uma pesquisada e achei um exemplo idêntico que baixei que um cara fez, mas para compilar a dll ele usou o compilador do Visual C++(com outras opções de compilação, claro!!) e eu testei o exemplo que ele fez, e funcionou legal. Acredito que o problema esteja nas opções de compilação que estou passando para o gcc.
Se alguem souber onde estou errando, ajuda seria bem-vinda.

ah sim, antes que alguem fale que estou errado nisso, em:

HelloNative.java:

System.loadLibrary(libHelloNative.dll);

eu também testei usando apenas o nome da dll dessa forma:

System.loadLibrary(libHelloNative);

flw

28 Respostas

I

Minha experiencia com JNI eh fazendo codigo C++ acessar codigo java (o contrário do que vc está precisando) mas, pela mensagem de erro, eu desconfio que a maquina virtual nao esteja conseguindo encontrar sua dll.

“no libHelloNative.dll in java.library.path”

Tente executar a JVM informando como classpath o caminho do diretorio onde encontra-se o arquivo dll.

java -cp <caminho_arquivo_dll> HelloNative.

Espero ter ajudado.

K

fala lek…
blz? faz assim… eu fiz e funcionou

HelloNative.java:

public class HelloNative {
    public static native void greeting();
    static {
        System.loadLibrary("libHelloNative.dll");
    }
}

HelloNative.h:

HelloNative.h atrevés do javah:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
    #endif
    /*
    * Class: HelloNative
    * Method: greeting
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloNative_greeting
    (JNIEnv *, jobject);

    #ifdef __cplusplus
}
#endif
#endif

HelloNative.c

#include "HelloNative.h"
#include<stdio.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *env, jobject obj)
    {
        printf("Hello world!!!\n");
    }

HelloNativeTest.java

class HelloNativeTest {
    public static void main(String args[]) {
        HelloNative.greeting();
    }
}

Coloque sua DLL no diretorio windows\SYSTEM32

aguardo resposta

Abraços

T

Eu também já tentei isso, além do mais a dll está no mesmo diretório da aplicação, eu também tentei colocar em um diretório que está no pah do sistema(tipo system32) e nada!!
vlw!

T

kubanacan:
fala lek…
blz? faz assim… eu fiz e funcionou

HelloNative.java:

public class HelloNative {
    public static native void greeting();
    static {
        System.loadLibrary("libHelloNative.dll");
    }
}

HelloNative.h:

HelloNative.h atrevés do javah:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */

#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
    #endif
    /*
    * Class: HelloNative
    * Method: greeting
    * Signature: ()V
    */
    JNIEXPORT void JNICALL Java_HelloNative_greeting
    (JNIEnv *, jobject);

    #ifdef __cplusplus
}
#endif
#endif

HelloNative.c

#include "HelloNative.h"
#include<stdio.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *env, jobject obj)
    {
        printf("Hello world!!!\n");
    }

HelloNativeTest.java

class HelloNativeTest {
    public static void main(String args[]) {
        HelloNative.greeting();
    }
}

Coloque sua DLL no diretorio windows\SYSTEM32

aguardo resposta

Abraços

Eu tentei isso e nada.
Acredito eu o meu erro seja na forma de como estou chamando o gcc, como eu expliquei no primeiro post eu peguei um exemplo pronto, praticamente idêntico, a única diferença é que ele compilou sua dll no compilador do visual C++. Então acho que utilizar -c para compilar a dll não é o certo, deve haver outra opção mais apropriada
vlw!

K

só pode ser… eu fiz em Borlad C++ e funcionou tranks… tenho aplicações minhas q usam JNI e roda tudo blz…

T

@kubanacan
Realmente!!! o problema é que não posso usar esses compiladores :x !! pois o projeto que estou fazendo é opensource!!

K

sakei… ja tentou usar o DEV-C++??

T

Tentei também, usando a opção de projeto ‘criar dll’ e nada, eu adicionei as pastas dos includes(…/java/include e …/java/include/win32) então não deu erro nenhum de compilação, nem linkedição, como também não tinha dado na compilação na mão :cry:!! mas o erro persiste na hora da execução! e além do mais, tenho que descobrir como isso é feito na mão, já que tenho de criar um *.so para usar este programa em Linux
Este problema já está virando uma Cruzada minha contra os compiladores!!!
vlw pela ajuda!!

H
java -Djava.library.path=/usr/lib -jar aplicacao.jar
T

hashcode:
java -Djava.library.path=/usr/lib -jar aplicacao.jar

C:\Documents and Settings\Ivo Augusto\Desktop\JNI>java -Djava.library.path="C:\D
ocuments and Settings\Ivo Augusto\Desktop\JNI" HelloNativeTest
Exception in thread "main" java.lang.UnsatisfiedLinkError: no libHelloNative.dll
 in java.library.path
        at java.lang.ClassLoader.loadLibrary(Unknown Source)
        at java.lang.Runtime.loadLibrary0(Unknown Source)
        at java.lang.System.loadLibrary(Unknown Source)
        at HelloNative.<clinit>(HelloNative.java:4)
        at HelloNativeTest.main(HelloNativeTest.java:3)

Mesma coisa! mas ainda não tive tempo de testar em Linux para ver o resultado!
Sem contar que no exemplo que peguei ne net, eu não precisei colocar nenhuma diretiva para o java, foi só java aplicacao
Continua…

H

No caso do windows acho que vc tem que colocar a DLL dentro de %windir%\system32

H

Djava.library.path=/usr/lib sem aspas

T

já tentei isso e como expliquei acima, no exemplo que peguei não precisei fazer isso porque a dll estava no próprio diretório
flw!! :!:

H

Tem que tacar as DLL no diretório padrão para o linker do SO achar o cara. Vai por mim.
Ah! troque

System.loadLibrary("libHelloNative.dll");

por

System.loadLibrary("HelloNative");
T
hashcode:
Tem que tacar as DLL no diretório padrão para o linker do SO achar o cara. Vai por mim. Ah! troque
System.loadLibrary("libHelloNative.dll");
por
System.loadLibrary("HelloNative");

Pode acreditar, eu já tentei tudo isso :x , já coloquei a dll na system32, já acrescentei a pasta da aplicação na PATH, já chamei loadLibrary("libHelloNative.dll") e loadLibrary("libHelloNative"). O jeito é largar tudo é virar filósofo ou estudante de letras ou programador em BrainFuck :lol: !!
Eu ainda estou convencido que o problema é nas opções de compilação passadas ao gcc e não no código java, acho que está sendo criado apenas um código objeto em vez de uma biblioteca dinâmica, mas tentei -shared que seria a opção óbvia mas nada
continua...

H

Já tentou compilar com o gcc na mão?

T

É justamente isso que preciso fazer.
Veja como estou colocando para compilar:
eu tentei assim

C:\Documents and Settings\Ivo Augusto\Desktop\JNI>gcc -I "C:\Arquivos de programas\Java\jdk1.5.0_04\include" -I "C:\Arquivos de programas\Java\jdk1.5.0_04\include\win32" -o libHelloNative.dll HelloNative.c -c

e assim:

C:\Documents and Settings\Ivo Augusto\Desktop\JNI>gcc -I "C:\Arquivos de programas\Java\jdk1.5.0_04\include" -I "C:\Arquivos de programas\Java\jdk1.5.0_04\inclu
de\win32" -o libHelloNative.dll HelloNative.c -shared

e da mesma forma em linux, alterando apenas as opções -I para :

-I $JAVA_HOME/include -I $JAVA_HOME/include/linux

respectivamente. Este teste em linux foi realizado em Slackware

I

ajuda ?

http://blogs.sun.com/roller/page/alanbur?entry=building_win32_jni_code_using

H
txithihausen:
hashcode:
Tem que tacar as DLL no diretório padrão para o linker do SO achar o cara. Vai por mim. Ah! troque
System.loadLibrary("libHelloNative.dll");
por
System.loadLibrary("HelloNative");
Pode acreditar, eu já tentei tudo isso :x , já coloquei a dll na system32, já acrescentei a pasta da aplicação na PATH, já chamei loadLibrary("libHelloNative.dll") e loadLibrary("libHelloNative"). O jeito é largar tudo é virar filósofo ou estudante de letras ou programador em BrainFuck :lol: !! Eu ainda estou convencido que o problema é nas opções de compilação passadas ao gcc e não no código java, acho que está sendo criado apenas um código objeto em vez de uma biblioteca dinâmica, mas tentei -shared que seria a opção óbvia mas nada continua...
Pelo que entendi vc não tirou o lib da frente do nome. Tem que ser assim
System.loadLibrary("HelloNative");
pelo menos no linux.
D

Fui fazer o teste aqui e também não consegui criar um programa usando jni.

Usei o google e achei dois links:

MinGW - Frequently Asked Questions
MinGW - JNI-Min GW-DLL

Depois disso se vc conseguir mostra aqui pra mim, pois o maldito proxy não deixa acessar o site (proxy FDP!!!)

flw

T
hashcode:
txithihausen:
hashcode:
Tem que tacar as DLL no diretório padrão para o linker do SO achar o cara. Vai por mim. Ah! troque
System.loadLibrary("libHelloNative.dll");
por
System.loadLibrary("HelloNative");
Pode acreditar, eu já tentei tudo isso :x , já coloquei a dll na system32, já acrescentei a pasta da aplicação na PATH, já chamei loadLibrary("libHelloNative.dll") e loadLibrary("libHelloNative"). O jeito é largar tudo é virar filósofo ou estudante de letras ou programador em BrainFuck :lol: !! Eu ainda estou convencido que o problema é nas opções de compilação passadas ao gcc e não no código java, acho que está sendo criado apenas um código objeto em vez de uma biblioteca dinâmica, mas tentei -shared que seria a opção óbvia mas nada continua...
Pelo que entendi vc não tirou o lib da frente do nome. Tem que ser assim
System.loadLibrary("HelloNative");
pelo menos no linux.

Testado e continua a dar erro!!

T

dudaskank:
Fui fazer o teste aqui e também não consegui criar um programa usando jni.

Usei o google e achei dois links:

MinGW - Frequently Asked Questions
MinGW - JNI-Min GW-DLL

Depois disso se vc conseguir mostra aqui pra mim, pois o maldito proxy não deixa acessar o site (proxy FDP!!!)

flw

No site http://www.mingw.org/MinGWiki/index.php/JNI-MinGW-DLLé utilizada esta forma para :

C:\Documents and Settings\Ivo Augusto\Desktop\JNI>gcc -Wall -D_JNI_IMPLEMENTATIO
N_ -Wl, --kill-at -I "C:\Arquivos de programas\Java\jdk1.5.0_04\include" -I "C:\
Arquivos de programas\Java\jdk1.5.0_04\include\win32" -shared -o libHelloNative.
dll HelloNative.c

Porém não é encontrada a opção --kill-at, olha a saída do compilador:

cc1.exe: error: unrecognized command line option "-fkill-at"

Tentei tirar a opção --kill-at, ele compila, mas gera o seguinte erro na hora de utiliza-lo

C:\Documents and Settings\Ivo Augusto\Desktop\JNI>java HelloNativeTest
Exception in thread "main" java.lang.UnsatisfiedLinkError: greeting
        at HelloNative.greeting(Native Method)
        at HelloNativeTest.main(HelloNativeTest.java:3)

Eu ainda vou ver se encontro uma saída neste site, foi onde achei material mais promissor. Quanto ao outro site, ainda não tive tempo de dar uma olhada para ver se funciona, quando eu ver posto aqui a resposta
Eu ainda venço a guerra contra o JNI
:lol:

T

Finalmente consegui!!! venci a batalha :lol: :lol: !!
A resposta estava no site http://www.mingw.org/MinGWiki/index.php/JNI-MinGW-DLL mesmo

para compilar a dll eu usei mesmo:

gcc -I"C:\Arquivos de programas\Java\jdk1.5.0_04\include"
-I"C:\Arquivos de programas\Java\jdk1.5.0_04\include\win32"
-Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared -o
libHelloNative.dll HelloNative.c

estava dando problema porque eu estava separando depois da virgula

-Wl,--kill-at

porém faz parte de uma única opção de compilação!
Só para complementar, não foi necessário eu colocar a dll na system32 não do próprio diretório funcionou. vlw pela ajuda de todos
flw :roll:

T

txithihausen:
Finalmente consegui!!! venci a batalha :lol: :lol: !!
A resposta estava no site http://www.mingw.org/MinGWiki/index.php/JNI-MinGW-DLL mesmo

para compilar a dll eu usei mesmo:

gcc -I"C:\Arquivos de programas\Java\jdk1.5.0_04\include"
-I"C:\Arquivos de programas\Java\jdk1.5.0_04\include\win32"
-Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared -o
libHelloNative.dll HelloNative.c

estava dando problema porque eu estava separando depois da virgula

-Wl,--kill-at

porém faz parte de uma única opção de compilação!
Só para complementar, não foi necessário eu colocar a dll na system32 não do próprio diretório funcionou. vlw pela ajuda de todos
flw :roll:

De volta aos problemas. Essa solução que eu encontrei para criar dll não funciona para o caso de criar .so para linux a opção -Wl,–kill-at não foi encontrada. Eu dei uma pesquisada no google e achei esta página em cache:
http://64.233.161.104/search?q=cache:NcyVNXLlxGoJ:quong.
best.vwh.net/java/native102.html+Creating+a+JNI+so+with+gcc+%2B+
linux&hl=pt-BR&gl=br&ct=clnk&cd=10

ela recomenda utilizar a opção -Wl,-soname, mas não está funcionando. Ainda estou na busca de criar uma lib para o linux. Se alguém souber como se faz isso, ajuda seria muito bem-vinda

D

Bom, achei esse endereço no google que parece interessante também, vê se ajuda:

Unix JNI How-To

flw

T

Finalmente consegui criar as dll e libs tanto para linux quanto para windows:
vou colocar abaixo o que fiz para quem estiver interessado em JNI não precisar quebrar a cabeça como eu: :lol:

em windows:

gcc -I"C:\Arquivos de programas\Java\jdk1.5.0_04\include"
-I"C:\Arquivos de programas\Java\jdk1.5.0_04\include\win32"
-Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared -o
libHelloNative.dll HelloNative.c

java HelloNativeTest

em linux:

gcc -I /usr/jdk1.5.0_05/include/ -I /usr/jdk1.5.0_05/include/linux/ -c HelloNative.c -o HelloNative.o

ld -shared  HelloNative.o -o libHelloNative.so

java -Djava.library.path=&lt;diretório da lib&gt; HelloNativeTest

na chamada
em windows
a chamada é dada por System.loadLibrary(“libHelloNative”);
para uma dll chamada libHelloNative.dll

e em linux usa-se:
System.loadLibrary(“HelloNative”);
para lib chamada : libHelloNative.so

B

txithihausen:
@kubanacan
Realmente!!! o problema é que não posso usar esses compiladores :x !! pois o projeto que estou fazendo é opensource!!

Você pode tentar o MinGW que é um gcc para Windows:

http://www.mingw.org/

Aí você usa o seguinte comando para gerar as DLLs:

gcc -Wl,--kill-at, -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared sua_lib.c -o sua_lib.dll

t+

T

bobmoe:
txithihausen:
@kubanacan
Realmente!!! o problema é que não posso usar esses compiladores :x !! pois o projeto que estou fazendo é opensource!!

Você pode tentar o MinGW que é um gcc para Windows:

http://www.mingw.org/

Aí você usa o seguinte comando para gerar as DLLs:

gcc -Wl,--kill-at, -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -shared sua_lib.c -o sua_lib.dll

t+


Eu já estou usando o gcc que vem com o DevC++, que usa o MinGw. Mas mesmo assim vlw.

flw

Criado 25 de julho de 2006
Ultima resposta 27 de jul. de 2006
Respostas 28
Participantes 7