Problemas para usar JNI - UnsatisfiedLinkError [RESOLVIDO]

Olá pessoal!!

Eu preciso acessar uma DLL usando JNI, mas o problema é que não está funcionando.
Fiz tudo de acordo com esses tutoriais:
http://forum-invaders.com.br/phpBB/viewtopic.php?f=63&t=8551746
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html

segue o código do meu ExecutaDll.h

[code]/* DO NOT EDIT THIS FILE - it is machine generated /
#include <jni.h>
/
Header for class ExecutaDll */

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

  • Class: ExecutaDll
  • Method: setDateTime
  • Signature: (IIIIII)Z
    */
    JNIEXPORT jboolean JNICALL Java_ExecutaDll_setDateTime
    (JNIEnv *, jclass, jint, jint, jint, jint, jint, jint);

#ifdef __cplusplus
}
#endif
#endif[/code]
ExecutaDll.c

[code]#include “ExecutaDll.h”
#include <Windows.h>

JNIEXPORT jboolean JNICALL Java_ExecutaDll_setDateTime
(JNIEnv * env, jclass obj, jint year, jint month, jint day, jint hour, jint minute, jint second) {
SYSTEMTIME time;
time.wYear = year;
time.wMonth = month;
time.wDay = day;
time.wHour = hour + 3;
time.wMinute= minute;
time.wSecond = second;
return SetSystemTime(&time);
}[/code]
E, finalmente, o meu ExecutaDll.java

[code]package br.com.unimake.nativo;
/**
*

  • @author Eliangela
    */
    public class ExecutaDll {

    public static void main(String[] args) {
    setDateTime(2010, 02, 01, 01, 01, 01);
    }

    static {
    System.loadLibrary(“w32”);
    }

    public static native boolean setDateTime(int year, int month, int day, int hour,
    int minute, int second);
    }[/code]

Está dando esse erro:

Exception in thread "main" java.lang.UnsatisfiedLinkError: br.com.unimake.nativo.ExecutaDll.setDateTime(IIIIII)Z at br.com.unimake.nativo.ExecutaDll.setDateTime(Native Method) at br.com.unimake.nativo.ExecutaDll.main(ExecutaDll.java:32) Java Result: 1

Obrigada

Use System.load ( http://java.sun.com/javase/6/docs/api/java/lang/System.html#load(java.lang.String) ) em vez de System.loadLibrary, e especifique o nome completo da sua DLL, incluindo a extensão.

o método que você está querendo ter acesso parece não estar sendo exportado da dll. Verifica a declaração dele.

Olá thingol!
Não funcionou :frowning:
Deu o mesmo erro!

Olá juliocbq!
eu acredito que esteja certo, porque eu usei o javah -jni pra gerar o código pra mim.
Eu não entendo, fiz o tutorial dos links que eu passei e eles funcionaram. Agora eu tentei fazer o que eu preciso e não funcionou.

P.S.: Não posso usar JNA. Infelizmente tem que ser JNI.

Olá thingol!
Não funcionou :frowning:
Deu o mesmo erro!

Olá juliocbq!
eu acredito que esteja certo, porque eu usei o javah -jni pra gerar o código pra mim.
Eu não entendo, fiz o tutorial dos links que eu passei e eles funcionaram. Agora eu tentei fazer o que eu preciso e não funcionou.

P.S.: Não posso usar JNA. Infelizmente tem que ser JNI.[/quote]

Olha a palavra chave static no seu método. O método nativo não é static.

Eu tenho um bom ebook sobre jni aqui. Me passa o seu email ou msn que eu envio.

Obrigada! mandei uma MP pra vc com meu MSN e email.

Métodos nativos podem ser static (até prefiro usar assim). Só que se você marcar o método como static, a assinatura gerada pelo javah é diferente de quando ele não é static (infelizmente não lembro qual é a diferença). Você não andou “mexendo” na assinatura não, hein?

Olá!
Consegui fazer parar de dar o erro!

O erro estava acontecendo porque quando eu gerei o HEADER, o meu código não estava numa estrutura de pacotes, e agora está no pacote br.com.unimake.nativo;.
Quando eu gerei o código em C, a assinatura do método estava saindo sem a estrutura, assim: JNIEXPORT jboolean JNICALL Java_ExecutaDll_setDateTime e o certo é que fique como nos pacotes java: JNIEXPORT jboolean JNICALL Java_br_com_unimake_nativo_ExecutaDll_setDateTime.

O problema é que eu tive que alterar isso na mão, porque tive problemas para compilar com os pacotes.

Bom… mas ainda estou tendo um problema. O java está acessando a biblioteca nativa, o método está retornando TRUE, mas não está alterando a data e hora do sistema. Acredito que se fosse algum problema com permissão, o método nativo teria retornado FALSE ou teria dado alguma msg de erro.

Alguém sabe como posso resolver isso?

Obrigada

SetSystemTime ( http://msdn.microsoft.com/en-us/library/ms724942(VS.85).aspx ), conforme você disse, deveria retornar 0 se não conseguisse acertar o horário. Isso realmente está esquisito.
O problema é eu arranjar aqui na minha máquina um usuário que não seja administrador, para testar isso. (Estou em uma máquina Windows XP).
Você está tentando rodar isso em um Windows Vista? Em um Windows Vista, você precisa rodar o programa como Administrador (clicar com o botão direito sobre o ícone do Prompt de Comando, e então escolher “Rodar como Administrador”. Aí você pode tentar rodar seu programa Java.

De qualquer maneira (não que isto vá consertar seu problema) é aconselhável usar sempre algo como

return SetSystemTime(&time) != 0;

para indicar se conseguiu acertar o horário (nesse caso, retornaria 1) ou se não conseguiu (retornaria 0). A API do Windows retorna um valor diferente de 0 se conseguir acertar o horário, mas esse valor nem sempre é (jboolean) true; por isso, aconselho usar explicitamente a condição, conforme mostrei no exemplo acima.

Pode até ser que ele tenha conseguido acertar o horário, mas instantes depois alguma coisa no Windows (como o serviço “Windows Time”) tenha voltado o tempo para um valor que é difundido pelo servidor de domínio (ActiveDirectory) ou então pesquisado na Internet (no Windows Vista pode ser que sua máquina consulte diretamente o servidor “time.windows.com” de vez em quando).

Obrigada entanglement !

Realmente era a permissão.
Está funcionando certinho aqui.

Obrigada a todos que me ajudaram!