Desenvolvimento - Java

JNI: interação Java e outras linguagens

Neste artigo vamos ver conceitos, vantagens e desvantagens da utilização do JNI (Java Native interface) na integração de códigos Java e demais linguagens (no caso Delphi).

por Gustavo S. Semaan



Introdução

O JNI é uma interface de comunicação (API) desenvolvida pela Sun que permitem aos códigos executados pela VM (Java Virtual Machine) interoperarem de forma bidirecional com aplicações e bibliotecas desenvolvidas de outras linguagens, como C/C++, assembly ou Delphi.

Neste artigo iremos conceituar o JNI bem como as vantagens e desvantagens em sua utilização. Abordaremos um exemplo com interação com um código Java acessando uma biblioteca Delphi/Kylix. Não exemplificaremos a contra-partida (Delphi acessando Java) pois nos exigiria mais conhecimentos de Delphi e este não é o foco deste artigo.

Ferramentas utilizadas

- Borland Delphi 7
- Compilador: J2SE SDK
- Ferramenta para geração do DPR
http://home.pacifier.com/~mmead/jni/delphi/files/jni_pas.zip
http://home.pacifier.com/~mmead/jni/delphi/JEDI/PAS/JNI_MD.INC

Conceitos do JNI

Quando desenvolvemos aplicações utilizando Java podemos nos deparar com situações onde esta linguagem pode não atender ou não ser a solução ótima para o dado problema. Problemas relativamente simples como, por exemplo, acesso a uma biblioteca de hardware desenvolvida em C++ ou problemas de performance.

O JNI tem como principal objetivo e qualidade "driblar" as restrições impostas pelo uso da VM. Com ele podemos acessar de classes do Java a bibliotecas desenvolvidas em linguagens com maior suporte a hardware (baixo nível) ou desenvolver em C/C++ algoritmos críticos onde o desempenho é primordial.

Inicialmente o JNI só possuía uma ferramenta que atendia somente C/C++, porém estudiosos interessados nesta solução disponibilizam outras ferramentas para facilitar a comunicação com outras linguagens, como Delphi.

Utilizando JNI você poderá, por exemplo:

  • Trabalhar com objetos Java, incluindo arrays
  • Chamar métodos Java
  • Gerar ou tratar exceções
  • Carregar e obter informações das classes


Representação das camadas de comunicação.

Porém existem desvantagens em sua implementação, como:

  • Poucas ferramentas para facilitar a criação das interfaces de comunicação.
  • O código nativo irá suportar somente a(s) plataforma(as) suportada(s) pela sua linguagem, restringindo uma das principais qualidades da VM, ser multi-plataforma.

Exemplo: Acesso do Java a uma biblioteca desenvolvida em Delphi

Iremos neste exemplo acessar pelo Java uma biblioteca (dll) desenvolvida em Delphi. Como o objetivo do artigo não é focar no desenvolvimento de dlls em Delphi, abordaremos o assunto necessário para bom entendimento do mesmo no quadro Off Topic a seguir.

Passo 1: Desenvolver o código Java.

Criar um arquivo Sysinfo.java com o código

public class SysInfo {
  //Declaro como nativo e estático este método  
  public native void SysMsg(); static{
    //Carrego a dll que já está em um formato entendido pela VM  
    System.loadLibrary("SysLib");
  }
}

Criar um arquivo JavaExecDelphi.java com o código

/* 
 Irei acessar a classe SysInfo, que tem acesso a DLL desenvolvida em Delphi.
 Poderia ser um .so desenvolvido no Kylix.
*/
public class JavaExecDelphi {

  public static void main(String[] args){
    //Instancio a classe que irá acessar a biblioteca
    SysInfo si = new SysInfo(); 
    //Chamo o metodo que carrega e executa a dll
    si.SysMsg();
  } 
}

Vamos compilar estes arquivos.

javac Sysinfo.java
javac JavaExecDelphi.java

Passo 2: Desenvolver o código Delphi/Kylix.

Para o funcionamento correto da interação são necessárias algumas regras de sintaxe (Link da documentação disponível nas referências deste artigo).

Para facilitar a aplicação destas regras que podem até mesmo causar erros existem ferramentas disponíveis. No próprio pacote JDK possui o javah.exe que gera o código com a sintaxe disponível para C/C++. Como este artigo tem seu foco na interação com Delphi utilizaremos uma ferramenta desenvolvida por Matthew Mead que faz o mesmo para a linguagem Delphi / Kylix (Link da ferramenta disponível na introdução deste artigo).

Descompacte o arquivo jni_pas.zip no mesmo diretório onde salvou o arquivo JNI_MD.INC. Compilemos então o arquivo JavaToDPR.Java e em seguida o executamos para geração do arquivo dpr (Arquivo de projeto do Delphi).

javac JavaToDPR.Java
java JavaToDPR SysInfo> SysLib.dpr

Arquivo Gerado: SysLib.dpr

O código em vermelho e itálico é o exemplo e não foi gerado pelo JavaToDPR.
Serão utilizados comandos simples para ilustrar o exemplo apenas.

library SysInfo;

uses
  //SysUtils contém informações sobre Data e Hora utilizadas
  JNI, SysUtils;

procedure Java_SysInfo_SysMsg(PEnv: PJNIEnv; Obj: JObject); {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF 
LINUX} cdecl; {$ENDIF}
begin
  Writeln("====================================================================");
  Writeln("Informações do Systema");
  Writeln("Data: " + DateToStr(Date));
  Writeln("Hora: " + TimeToStr(Time));
  Writeln("====================================================================");
end;

exports
  Java_SysInfo_SysMsg;
end.

Compilando pelo delphi teremos SysLib.dll.

Passo 3: Executar o JavaExecDelphi

java JavaExecDelphi

Pronto! O resultado de sua biblioteca desenvolvida em Delphi será exibido!

Off Topic

Alguns detalhes para a geração da dll.

É necessário copiar o arquivo borlndmm.dll para o mesmo diretório da gerada (Arquivo existente em qualquer máquina que possua o Delphi instalado).

As dlls deverão estar em algum PATH padrão, por exemplo, System32 dentro do diretório do seu Windows.

Representação das etapas C/C++ e Delphi

Conclusões

Com a utilização do JNI podemos otimizar algoritmos críticos e "driblar" restrições impostas pela VM. Contudo nossa aplicação ficará dependente das plataformas que a linguagem utilizada pode ser executada. Por exemplo, conseguiríamos executar nosso teste apenas em Microsoft Windows ou em alguns Linux que suportem softwares compilados em Kylix.

Referências

ECKEL B. - Thinking in Java, Prenticel Hall, 2a Edição, 2000.
DEITEL, H. M.; DEITEL, P.J. Java- Como Programar, Bookman, 4a. Edição, 2003.
Documentação da Sun relativa ao JNI
Documentação da ferramenta utilizada.

Faça o download do exemplo.

Gustavo S. Semaan

Gustavo S. Semaan - Bacharelando em Sistemas de Informação, Técnico em Informática Industrial, é Analista de Sistemas do CAEd / UFJF, desenvolvendo sistema escolar e soluções em avaliações educacionais. Possui experiência em Delphi, vb.NET, PHP e JAVA e utiliza banco de dado SQL Server, Interbase/Firebird e MySQL.