Você pode ganhar um iPad 2 na promoção do Javafree
O Portal javafree.org inicia mais uma promoção para os usuários do fórum. Quem publicar mais posts válidos (perguntas ou respostas) entre 16/4 a 13/7 levará para casa um iPad 2 de 16GB!
Clique aqui e saiba mais.
Home > Artigos > Java em Geral >
JNI - Java Native Interface
Publicado por cleuber_s em 23/06/2010 - 122.554 visualizações
Leia também:
JNI - Iteração Java e Delphi
JNI em Linux com GCC
Devido aos vários questionamentos, de várias pessoas, e aqui mesmo no Fórum JavaFree, e por se tratar de um recurso valioso que pode ter uma grande aplicabilidade. Estou disponibilizado este singelo tutorial sobre JNI ( Java Native Interface). Ao longo deste tutorial poderemos formar uma base de conhecimento sobre o assunto, a ser complementado com os livros e tutoriais na web que indico no final do mesmo.
Quote:Breve respostas:
* O que preciso instalar?
Precisa ter instalado o J2SDK, e é claro o compilador para a biblioteca nativa que você irá utilizar.
* O que preciso conhecer?
Precisa saber lidar com conhecimento básico de Java, exceções e OO; além disso conhecer bem a linguagem da biblioteca nativa.
* Existe dificuldade?
Não existe dificuldade desde que preenchido os pré-requisitos anteriores.
1. Visão Geral de JNI
A Java Native Interface, é um framework que fornece recursos, com a Máquina Virtual Java, para utilização de recursos específicos em determinado Sistema Operacional, ou biblioteca compartilhada e vice-versa. Pelo motivo o qual os Sistemas Virtuais não tem acesso direito à funções do hardware e etc. Com a JNI esta barreira é quebrada. É óbvio que a portabilidade do Java desaparecerão, porém recursos como impressoras fiscais, porta COMX, Modem, USB, e etc podem ser facilmente acessados. Estarei dando exemplos no decorrer deste tutorial.
A JNI permite que um código escrito em Java, utilize a implementação de uma biblioteca escrita em C/C++, Assembler, e outras tantas linguagens de programação.
Usa-se JNI em determinadas situações em que um código Java não pode acessar certos recursos, por causa da estrutura dos Sistemas Vituais (sob qual a Máquina Virtual Java foi implementada).
Além disso, você pode ter um conjunto de bibliotecas escritas em outras linguagens, e pode querer disponibilizá-las em seus programas Java. Isso facilita até o reuso de aplicações não-java. Pode ser usado para implementação de pontos críticos, em aplicações que exigam recursos de baixo-nível como código IN LINE, Assembler, e sua aplicação Java pode chamar todas essas funções.
A JNI, também habilita a você o uso das vantagens da Linguagem de Programação Java em seus métodos nativos, você pode capturar e lançar exceções de uma biblioteca qualquer, e tratá-las dentro de seu programa Java.
Para exemplo, a figura seguinte mostra como um programa usando código em C, pode usar JNI para ligação com classes Java.

Facilmente podemos ver que o JNI, serve para interagir entre programas Java e outros programas escritos em liguagens diferentes. A figura abaixo demonstra isso, juntamente com a possibilidade do tratamento de exceções e outras implementações da base de uma aplicação escrita em C.

[size=18:d0efc1a997]2. Escrevendo um programa Java com métodos nativos.[/size:d0efc1a997]
A partir de agora criaremos um pequeno programa Java(o básico Hello World!), porém escrito em métodos nativos. A seguinte figura ilustra como será a estrutura de nossa aplicação:

Vamos implementar uma Classe chamada HelloWorld, e declarar um de seus métodos nativo.
Quote:*Método nativo é um função que foi chamada diretamente de uma bibloteca, externa à sua aplicação Java.
O método nativo displayHelloWorld(), é o método "carregado" pelo JNI, através do comando System.loadLibrary("hello"). A palavra chave native indica ao compilador que é uma função de uma biblioteca escrita em uma outra linguagem. Existe um segmento de código nesta classe que é estático, determinando que os métodos nativos carregados podem ser usados ao longo da implementação da classe. O argumento passado em System.loadLibrary é o recurso compartilhado que iremos usar, a biblioteca específica que faremos depois.
Quote:Em seguida compile o código acima.
javac HelloWorld.java
Agora iremos desenvolver a implementação do método nativo, em outra linguagem que não seja Java.
Agora bastante atenção, iremos usar um recurso muito útil que o ambiente da JSDK nos oferece, o utilitário javah. Iremos gerar este código(o HEADER) como arquivo HelloWorld.h, que está ecrito na linguagem C++.
Quote:Execute o seguinte comando no arquivo com o utilitário do JSDK na sua classe:
javah -jni HelloWorld
A assinatura do método seguinte indica que o método será exportado pelo JNI, e usado na nossa classe HelloWorld.class:
Neste provesso é utilizada a biblioteca jni.h, que vem no jsdk(na pasta includes), esta biblioteca fornece os mecanismos JNI para o método interagir com nossa classe.
Adota-se como nomenclatura o padrão, a linguagem da exportação em seguida o underline, depois o pacote, underline, e o nome do método em si.

Agora temos abaixo a implementação do método nativo e o código completo que deve ser salvo como HeloWorldImp.c
Este método imprime o texto "HelloWorld!" com o comando printf.
- - jni.h - Esse arquivo prove infomações que o código nativo precisa para interagir com a JRE.
- - HelloWorld.h - O arquivo h. que você gerou anteriormente.
- - stdio.h - fornece mecanismos de saída (printf) e outros mais.
Além de criar os arquivos iremos também compartilhar as bibliotecas. Lembre-se que na implementação da classe HelloWorld, havia um trecho de código chamado System.loadLibrary("hello"). Então é necessário compilar essas bibliotecas, e torná-las compartilhadas para que a classe possa encontrá-las. Criaremos uma dynamic link library (DLL) chamada hello.dll. Como o processo para criar uma DLL exige a construção de um compilador. Eu estou usando o Microsoft Visual C++ Toolkit 2003 , porém por praticidade estou disponibilizando os arquivos logo abaixo.
Mas para quem for utilizar este mesmo compilador segue a linha de comando para gerar a DLL:
Ob.: Talvez você precisará copiar os aquivos "jni.h" e "jni_md.h" do J2SDK, para o diretório INCLUDE do compilador C++.
O compilador gerará alguns arquivos, mas nós precisaremos apenas do hello.dll. Esse arquivo deve ser posto no diretório de sua aplicação Java.
Depois disso devemos rodar a nossa classe HelloWorld usando o interpretador Java:
Quote:java HelloWorld
A saída será o seguinte:
Quote:Hello World!
A implementação de JNI, abre uma grande gama de possibilidades que podem ser aproveitadas, dadas as limitações da JVM. Estarei implementando a seguir um básico aplicativo , que retira os dados de variáveis de um código nativo.
Vimos, no entanto, a utilização desses códigos nativos em um programa Java de forma a executar somente funções pré-definidas. Mas agora aprederemos como implementar uma interação entre Java e uma outra linguagem.
. Interagindo Java e Programas Nativos
A Java Native Interface define um padrão de nomes e convenções de funções que só a Máquina Virtual Java pode localizar e invocar nos métodos nativos. Esta parte do tutorial ensina, como esses padrões podem ser usados para criar funções JNI e como declarar tipos e como eles podem ser corretamente usados tanto pelo programa Java, como pelo método Nativo.
É necessário lembrar que na declaração de um método nativo no Java ele precisa:
- - Ter a palavra-chave native em sua assinatura.
- - Não ter implementação alguma, no corpo do método.
Vamos implementar agora um novo exemplo que pega informações passadas como parâmetros de uma aplicação Java, processa em código nativo e devolve:
Quote:>>Desta vez temos o método nativo com um tipo de retorno inteiro e um parâmetro.
Compile o código:
Quote:javac Prompt.java
Vamos gerar o header da biblioteca automaticamente com o comando:
Quote:javah -jni Prompt
Veja que o arquivo gerado contém o seguinte:
Podemos ver que foi gerado um método nativo que contém um tipo de retorno jint, e parâmetros jint e jobject. Eles são tipos normatizados pela JNI para possibilitar a comunicação entre aplicativos. Isso faz com que o compilador C++ possa mapear todos os tipos usados e os reconheça, de acordo com a biblioteca importada (jni.h).
Abaixo segue uma tabela com os tipos Java e seus equivalentes JNI:
Quote:Tipo Java | Tipo Nativo | Tam. em bits
--------------------------------------------
boolean | jboolean | 8, sem sinal
byte | jbyte | 8
char | jchar | 16, sem sinal
short | jshort | 16
int | jint | 32
long | jlong | 64
float | jfloat | 32
double | jdouble | 64
void | void | n/a
Desta forma vemos que, com foi dito antes, a JNI é uma interface entre códigos Java e outras linguagens. Tendo a implementação JNI e seguindo seus padrões de tipos, objetos podemos facilmente estabelecer uma comunicação entre recursos de diferentes tecnologias. Como a linguagem C++ é Orientada à Objetos podemos usar recursos entre ambas, e além disso, C++ nos fornece acesso a recursos de baixo nível (low level) que podemos usar em nossas aplicações Java.
Abaixo segue também a implementação de objetos na JNI. Os objetos são passados por referência, a JNI implementa um conjunto de tipos que são todos subclasses (conceitualmente), de jobject como segue:

Agora segue a respectiva implementação do método nativo, do arquivo salvo como PromptImp.c, que deve ser compilado gerando a DLL prompt.dll:
Assim você pode compilar este código no seu compilador C++, ou como já foi descrito acima, gerando a DLL prompt.dll e rodando a classe java Prompt.class, teremos o seguinte resultado:
Quote:java Prompt
Resultado: 4
Podemos ver desta forma, que o JNI pode extender as potencialidades da linguagem Java, dando recursos que o Java pode não ter, poém sendo agregado à uma linguagem como o C++ pode ser bastante poderoso no acesso à recursos que lhe são limitados. A JNI não possibilita a interface com o C++, apenas, mas com DELPHI, e qualquer oura linguagem que tenha uma biblioteca JNI disponível, pois é ela que faz essa interação. Assim podemos acessar desde de espaço em disco e memória, até portas COM[X] para enviar e receber dados quaisquer.
Espero que tenha agregado conhecimento, um abraço!
Leia também:
JNI - Iteração Java e Delphi
JNI em Linux com GCC
- GPF - Segmentation Error
- [RESOLVIDO]Java e C no mesmo programa
- Programação direta no hardware
- Conversor de C++ para JAVA
- Listar os Processos do Windows com Java
- Máquina para Java
- Codigo para Desligar o win XP?
- declaração de função
- Path Destino em Drag and Drop
- Siglas e mais siglas
- Mensagens que não tinham tópicos
- JNI: Interação Java e Delphi
- Gravando e lendo em endereços de memória
- Duvida!!!Servlet Java manipulando socket C
- Java com C# usando método native()
- Cobol com JAVA
- JNI (Java Native Interface)

