Sun Campus Ambassador at UFBA
Java invocando Ruby - JSR 223
A JSR 223 define um padrão para uso de linguagens de scripts com a plataforma Java, isto é, de uma aplicação Java podemos utilizar os recursos de diversas linguagens de Script, tais como Python/Ruby/Tcl/JavaScript/etc, invocando funções, definindo classes e utilizando-as no código Java, resumindo, podemos extrair o melhor da linguagem de script escolhida e unir ao poder da plataforma Java.
A fim de utilizar a API de Scripting, faz-se necessário obter o engine apropriado, por padrão, o Java 6 tem a implementação de um engine para JavaScript denominado Mozilla Rhino. No nosso caso, iremos utilizar Ruby como linguagem de script, portanto devemos adicionar o engine ao conjunto de bibliotecas da nossa aplicação, como também o jruby. Não se preocupem, pois deixarei os arquivos disponíveis para download ao final do post.
Como citado anteriormente, o primeiro passo é baixar o engine da sua linguagem de script e demais .jar e adicioná-los ao conjunto de bibliotecas da sua aplicação. Para aqueles que não estão familiarizados com a sintaxe de Ruby, aconselho a dar uma rápida estudada de 15 minutinhos, acredite Ruby é muito fácil e intuitivo.
Nossa aplicação contém um arquivo denominado script.rb, no qual teremos a definição de funções e de uma classe que, de ambos, faremos uso na aplicação Java. Acredito que a melhor forma de aprender é na prática e explicando passo-a-passo. Vamos agora dissecar a nosso método principal da aplicação Java.
O primeiro passo para se utilizar Scripting é obter uma referência ao ScriptEngineManager, cuja função é 'fabricar' os engines, além de identificar quais estão disponíveis, para este recurso recomendo dar uma olhada no método getEngineFactories().
ScriptEngineManager manager = new ScriptEngineManager();
Uma vez com uma referência ao Manager, nós podemos obter a referência ao ScriptEngine, que será responsável pela análise de blocos, invocar funções e métodos. Reparem que ao obter tal instância, devemos passar o nome do engine requerido, para uma lista completa é interessante conferir o site oficial do projeto Scripting, no qual podemos baixar os engines.
ScriptEngine engine = manager.getEngineByName("jruby");
Com a referência ao engine, podemos invocar método Ruby simplesmente passando como argumento o nosso código. No caso exemplo abaixo, declaro uma variável e invoco o método puts do Ruby para exibir na saída padrão.
engine.eval("x = 10; puts \"Hello World! #{x}\"");
Até o momento só vimos um único exemplo em que passávamos o bloco de código em Ruby para execução, então podemos nos perguntar se será sempre dessa maneira. A resposta, obviamente é não, no seguinte trecho fazendo uma análise por inteiro de um arquivo Ruby.
engine.eval(new BufferedReader(new FileReader("./src/scripting/script.rb")));
Para de fato invocar as funções e métodos que já foram 'reconhecidas' pelo engine devemos utilizar uma interface denominada Invocable. Basicamente, tal interface nos permite invocar Funções e Método. A obtenção da referência é feita simplesmente com um simples Cast.
Invocable invoke = (Invocable) engine;
A fim de invocar uma funçao definida no nosso arquivo Ruby, utilizamos o método invokeFunction, cujo primeiro parâmetro é nome da função, enquanto o segundo é um Varargs de Object (VarArgs tema de certificação SCJP!!)
invoke.invokeFunction("soma", 1, 2);
A seguinte declaração merece uma atenção especial:
long idade = (Long) invoke.invokeMethod(p1, "idade");
Utilizamos o método invokeMethod que retorna uma referência a object, reparem que fizemos um cast para Long, por quê? A explicação vem da seguinte tabela de conversões de tipos java (à direita) para Ruby (à esquerda):
Boolean boolean, java.lang.Boolean
Fixnum byte, java.lang.Byte, short, java.lang.Short, int, java.lang.Integer
Float float, java.lang.Float, double, java.lang.Double
String char, java.lang.String
Array java.util.List
Hash java.util.Map
Alguns trechos que não foram explanados ficam como exercício.
Links:
JRuby.jar - Não pude anexar por conta do tamanho do arquivo, mas vocês podem encontrá-lo na página oficial do projeto ou na pasta do Netbeans/ruby2
JRuby-engine
Projeto Exemplo
Posted at 10:26AM Jul 14, 2008 by Ramon Lopes in Personal | Comments[2]
Descobrindo JRuby
Acredito que muitas pessoas nunca ouviram falar sobre Ruby ou Ruby on Rails, imagina JRuby. Tomando tal desconhecimento como motivação, além de meu gosto por Java e Ruby, resolvi fazer um pequeno post sobre como brincar com JRuby.
Acredito que seja desnecessário fazer um longa introdução sobre Ruby e JRuby, portanto recomendo a leitura de um pequeno post aqui
Vamos ao que interessa! Hoje, pensei em construir uma pequena aplicação que reunisse características fortes de ambas as linguagens:
Java: Construção de interfaces gráficas, utilizando o Matisse é claro!
Ruby: Manipulação de arquivos e simplicidade da sintaxe.
Nossa pequena aplicação simplesmente abrirá um arquivo texto, localizado na pasta do projeto, e exibirá o conteúdo no jTextArea da nossa aplicação Swing. Ao final do artigo, deixarei os links para download.
O primeiro passo é criar um projeto Java, em seguida elaborar um belo JPanel e um jTextArea. Nesta etapa, a parte mais complexa é criar um método que irá receber uma string e adicionará ao textArea, pois o Matisse já facilita boa parte do trabalho.
Com o JRuby nós podemos utilizar bibliotecas Java, logo temos disponíveis todo o poder do nosso bom Java. Vamos entender linha-linha nosso extenoso código (comentários em Ruby é com o caracter #):
#Diretiva abaixo nos dará acesso às bibliotecas Java, como se estivéssemos dizendo: Não vou usar apenas código Ruby!
require "java"
#RubyDesktop.jar contém nosso fragmento Swing da aplicação, logo estamos 'carregando' suas classes
require "RubyDesktop.jar"
#Mesma função do import em Java, caso contrário deveríamos sempre usar o caminho completo
import 'javax.swing.JFrame'
#A classe Painel pertence ao RubyDesktop.jar, sendo a classe que contém os widgets
import 'Painel'
#Variavel em Ruby que diferentemente de Java é dinamicamente tipada.
s = ""
#Abrimos o arquivo teste.txt para leitura
arquivo = File.open("teste.txt","r")
#Intuitivo, não? Para cada linha do arquivo, associo a variável l e concateno com a variável s. Ruby é demais!!
arquivo.each_line do |l|
s.concat(l)
end
arquivo.close
#Começamos agora de fato a brincar com JRuby
#Em Ruby instanciamos um classe da seguinte forma: NomeClasse.new
painel = Painel.new
#O nosso objeto painel e uma instancia de uma classe java, que por sua vez possui métodos. A linha abaixo acessa
#o metodo insertText(String s) da classe Painel. Fiz questao de usar _ (underline) a fim de demonstrar a conveção Ruby
#para declaração de métodos, contudo o método na classe Painel foi declarado seguindo as convenções JavaBeans Fantástico!
painel.insert_text(s)
#Aqui em diante é puramente Java!
frame = JFrame.new("Java + Ruby = JRuby")
frame.getContentPane.add(painel)
#O operador :: serve para acessarmos campos estáticos da classe
frame.setDefaultCloseOperation(javax.swing.JFrame::EXIT_ON_CLOSE)
frame.pack
frame.setSize(300,300)
frame.setVisible(true)
Acredito que podemos concluir o quão simples Ruby é e aliada aos recursos do Java... torna-se fantástico.
JRuby é apenas uma das 'linguagens' que estão sendo incorporadas ao Java tais como: Python (Jython), maiores informações aqui
Como prometido, os links para download:
Aplicação JRuby link1
Aplicação Swing link2
Até o próximo post!!
Posted at 12:11PM Jul 10, 2008 by Ramon Lopes in Personal | Comments[1]
Today's Page Hits: 70