Jni

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 dá 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

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.

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 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!

[quote=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[/quote]

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!

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

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

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

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!!

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

[quote=hashcode] java -Djava.library.path=/usr/lib -jar aplicacao.jar [/quote]

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…

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

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

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!! :!:

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");

[quote=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

[code]

System.loadLibrary(“HelloNative”);
[/code][/quote]

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…

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

É 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

ajuda ?

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

[quote=txithihausen][quote=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

[code]

System.loadLibrary(“HelloNative”);
[/code][/quote]

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…[/quote]
Pelo que entendi vc não tirou o lib da frente do nome.
Tem que ser assim

System.loadLibrary("HelloNative");

pelo menos no linux.