Tutorial JNI
JNI, Java Native Interface, é uma suíte de programação que permite código em Java rodando sob uma máquina virtual Java (JVM) chamar e ser chamada por aplicações nativas. Aplicações nativas são programas escritos para plataformas de hardware e sistema operacional específicos. É possível fazer chamadas para C, C++ e Assembly.

JNI – Usando coisas que estão fora do Java
1. Porque?
- Aplicações legadas que não podem ser reimplementadas
- Bibliotecas nativas específicas que não possuem binding ou implementação em para Java
- Trechos críticos da aplicação onde a performance do Java é inferior a uma implementação nativa.
2. Como Fazer?
Vamos fazer um olá mundo do JNI, uma aplicação Java vai chamar um programa em C que imprime “Ola Mundo”.
Essa vai ser a classe OlaMundo:
class OlaMundo {
public native void diga ();
static {
System.loadLibrary("olanativo");
}
public static void main (String[] args) {
OlaMundo ola = new OlaMundo ();
ola.diga();
}
}
Primeiro nós declaramos uma classe chamada OlaMundo. Essa classe possui um método chamado diga que recebe nenhum parâmetro e não retorna nada. Através da palavra reservada native nos declaramos que esse método é uma implementação nativa e portanto sua implementação não feita aqui.
Em seguida nos declaramos um bloco estático e chamamos o método loadLibrary do System. Nós pedimos para ele abrir a biblioteca olanativo (isso será explicado melhor mais adiante). É importante que o nome da biblioteca esteja todo em minúsculo.
No método main nós instanciamos o objeto OlaMundo e chamamos seu método diga.
Compilamos isso:
$ javac OlaMundo.java
Se você escreveu tudo certo a compilação não irá dar nenhum problema.
Agora vamos tentar rodar:
$ java OlaMundo
Exception in thread “main” java.lang.UnsatisfiedLinkError: no olanativo in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:992)
at OlaMundo.(OlaMundo.java:5)
Não deu certo. Não foi possível linkar o programa com a biblioteca olanativo. Tudo bem, nós não escrevemos ela ainda. Isso não serviu pra nada, eu só mostrei isso para sublinhar que os nossos erros serão geralmente em tempo de execução e não em tempo de compilação.
Agora vamos gerar os cabeçalhos (headers) para fazermos nossa implementação nativa. A ferramenta javah faz isso pra nós, basta chamar javah seguido do nome da classe que vai chamar uma implementação nativa.
$ javah OlaMundo
Esse comando vai gerar esse OlaMundo.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class OlaMundo */
#ifndef _Included_OlaMundo
#define _Included_OlaMundo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: OlaMundo
* Method: diga
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_OlaMundo_diga
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Não é importante você entender esse código acima. Nós vamos incluir ele com um include na nossa implementação. Ele inclui o jni.h onde estão declarados toda a parte de conversão de tipo do Java/C e vai declarar o cabeçalho da função diga, que agora passa a se chamar Java_OlaMundo_diga.
Agora vamos, finalmente, a nossa implementação nativa.
#include
#include "OlaMundo.h"
JNIEXPORT void JNICALL Java_OlaMundo_diga (JNIEnv * env, jobject jobj){
printf("ola mundo\n");
}
Nós incluímos o OlaMundo.h e escrevemos a função Java_OlaMundo_diga, que simplesmente imprime um “ola mundo” e pula a linha.
Agora vamos compilar esse código, mas primeiro temos que descobrir onde está o jni.h. Ele vai estar dentro da pasta onde seu java está instalado e isso vai variar muito de distribuição para distribuição. Alguns comandos podem te dar pistas:
$ whereis java
Isso vai te dar vários lugares, veja se em algum desses lugares tem uma pasta chamada include e lá dentro o jni.h. No Ubuntu que eu estou usando o java está em /opt/jdk1.6.0/include/.
Nos vamos compilar nosso código em uma biblioteca. Essa bibliteca vai se chamar libolanativo.so. Esse nome não foi escolhido arbitrariamente, ele é formado pela string que nós citamos no primeiro programa, na linha 5, precedida por “lib” e sucedida por “.so”. Se estivermos usando o Windows, seria libolanativo.dll.
É necessária uma longa linha de comando para compilar isso com o gcc, vamos a ela:
$ gcc -o libolanativo.so -shared -Wl,-soname,libolanativo.so -I/opt/jdk1.6.0/include -I/opt/jdk1.6.0/include/linux OlaMundo.c -static -lc
Lembrando mais uma vez que você vai trocar os dois /opt/jdk1.6.0/include pelo diretório do Java onde está o jni.h.
Está quase tudo pronto, mas se você tentar executar o OlaMundo agora vai dar aquele primeiro erro. A linkagem com a libnativo.so não poderá ser feita porque o java não consegue encontrar ela. Vamos setar uma variável de ambiente que diz onde se deve procurar as bibliotecas para serem linkadas, vamos dizer . (ponto) que quer dizer o diretório corrente.
No terminal:
$ LD_LIBRARY_PATH=.
$ export LD_LIBRARY_PATH
Rufem os tambores, já está tudo pronto para executar a classe OlaMundo. No terminal:
$ java OlaMundo
ola mundo
3. Desvantagens de se usar JNI
- Perda da portabilidade. Uma aplicação que usa uma implementação nativa só funcionará para os binários compilados disponíveis.
- Complicação. Muitos conceitos estão envolvidos para fazer uma aplicação JNI funcionar. É necessário conhecimento em mais de uma linguagem.
4. Links Úteis:
- Artigo da Wikipédia anglofôna sobre JNI
- Especificação da JNI
- Capítulo 5 do livro Advanced Programming for the Java 2 Platform
- Artigo da revista JavaWorld sobre JNI
- http://public.cabit.wpcarey.asu.edu/janjua/java/jni/
- http://www.codeproject.com/java/jnibasics1.asp
- http://java.sun.com/docs/books/tutorial/information/download.html
- http://www.gmonline.demon.co.uk/cscene/CS4/CS4-04.html
- http://www.javafree.org/javabb/viewtopic.jbb?t=13913



about 5 years ago
Muito com o post sobre JNI, bem explicado e me ajudou muito… parabéns
about 2 years ago
Muito obrigado mesmo.
Já tinha seguido alguns tutoriais, mas esse foi o único onde eu não obtive nenhum erro.
Good work!
about 2 years ago
Um bom exemplo de aplicacao que utiliza JNI é o JVR. Ele encapsula o acesso a API de placas telefonicas Dialogic.
O endereco é: http://threebit.net/projects/jvr/
about 1 year ago
Excelente post, já estava pra desistir, pensei em roubar, matar, mas você me tirou do mau caminho.
Parabéns!
about 1 year ago
Pergunta daria pra criar as dll no vb6 ?
para o java acessar atravez do jni ???
about 1 year ago
I just can not imagine with strong your blog greatly that warned me! God bless you “I am among those who think that science has great beauty. A scientist in his laboratory is not only a technician: he is also a child placed before natural phenomena which impress him like a fairy tale.” – Marie Curie
about 11 months ago
советы диетолога похудеть на 5 кг в месяцдвухнедельная бессолевая диетадиабед диетаможно ли похудеть питаясь рисом и зеленым горошкомкак правильно качать пресс для похуденияуспехи в похудениидиета белковая углеводнаяфито препараты при диете5лида средство для похудения в магнитогорскеупражнения для похудения икр ног с картинкамидиета по 200 граммдиета каша и молояные продуктыупражнения для похуденния ног и попыхронический гастрит диета 1как подключиться к эгрэгору соблюдающих диетудиеты которые дают результат за 1 месяц на 10 кгварьирование массы тела в результате увеличения диетамияично-апельсиновая диетеполезная диета убрать живот и жир под лопаткамипохудение по броменталю
about 11 months ago
hi amazing thread we have going there.
about 11 months ago
Just looked through the topic! great work.
about 11 months ago
The holidays offer plenty of opportunities for overindulgence: wasteful dinners, tantalizing treats, etc. Occasionally the lead on can be thorny to resist – resulting in vacation burden gain. But around implementing a serviceable heaviness demise strategy, losing those leave of absence pounds – and uniform lifetime weight restraint – can be well within your reach.
about 11 months ago
I am not sure coz i am new in this forum as you may notice
about 10 months ago
hire car sydney chauffer
about 10 months ago
Good day !
I made this account to spam on your forum.
Please, delete my account and this topic, and I delete your forum by my spam-base.
With best regards…
—————— * * * ——————
Привет…
Я собираю базу немодерируемых форумов. Я уважаю труд администраторов и модераторов, тем более, сам являюсь модератором форума.
И потому прошу: Удалить этот топик. Или даже этот мой аккаунт. После этого я удалю ваш ресурс из своей базы. И более никогда не побеспокою вас.
С наилучшими пожеланиями!
about 10 months ago
moral gonna phrase hello…
about 10 months ago
http://www.youtube.com/watch?v=uPzFOgJfoDo-hd20-2
about 10 months ago
Hello, Every body
I’m new here.I Will greatly appreciate all your assist.
Thanks
about 9 months ago
[size=5][color=red][b]
I am very happy to talk with you and you grant me many help! Thanks for that, I am learned if i can touch you via email when i meet brother? Gucci Womens Casual Shoes
[/b][/color][/size]
about 9 months ago
Уважаемая администрация сайта! Прошу удалить это сообщение!! я нечаяно
about 9 months ago
about 9 months ago
about 9 months ago
I wanted to follow along and let you know how much I cherished discovering this blog today. I would consider it a real honor to do things at my business office and be able to make real use of the tips discussed on your web-site and also get involved in visitors’ comments like this. Should a position involving guest article writer become available at your end, please let me know.
about 9 months ago
Achei seu post excelente, me ajudou a entender muita coisa.
Mas ainda não consegui resolver meu problema, tenho um método em C que carrega uma função de um arquivo “.o”, quando peço para compilar ele não encontra essa tal função… alguém consegue me ajudar?
about 5 months ago
Hey .
Welcome from Switzerland
about 4 months ago
Amigo, parabens pelo post.
Dá pra utilizar dll do VB6 no java ?
about 2 months ago
Very very good
Thanks man,
about 2 months ago
Amigo, você me ajudou muito. Fiz um pequeno exemplo seguindo o que você ensinou e funcionou de primeira. Entretanto, em minha aplicação, aparece o seguinte erro. Sabe me informar o que pode estar ocorrendo?
obg
$ java main
PhGA in Java
Exception in thread “main” java.lang.UnsatisfiedLinkError: /home/cin/Dropbox/Doutorado/phiga/phigaDanilo/java/libphga_interface.so: /home/cin/Dropbox/Doutorado/phiga/phigaDanilo/java/libphga_interface.so: undefined symbol: _ZN4phga16setMaxPopulationEi
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at phga_interface.(phga_interface.java:52)
at main.main(main.java:13)