Jruby - Ruby em Ambientes 100% Java

93
Tirando o máximo da JVM com Ruby Hugo Roque [email protected] hugolnx.com @hugolnx Sergio Azevedo Junior [email protected] sagadoprogramador.com.br @sergioazevedo Saturday, July 2, 2011

description

Apresentação realizada no CaelumDay RJ 2011 (02/07/2011)

Transcript of Jruby - Ruby em Ambientes 100% Java

Nós não somos o

Douglas Campos@qmx

Saturday, July 2, 2011

Java

Saturday, July 2, 2011

Java

10 anos de mercado

multiplataformacompilado JVM

JITframeworks

bibliotecas

comunidadeestático

Saturday, July 2, 2011

Java - classe Tarefa

public class Tarefa{private Long id;private String descricao;private Calendar dataFinalizacao;

public Long getId(){ return this.id;}public void setId(Long id){this.id = id;

} public String getDescricao(){return this.descricao;

}public void setDescricao(String descricao){ this.descricao = descricao;}public String getDataFinalizacao(){return this.dataFinalizacao;

}public void setDataFinalizacao(Calendar novaData){ this.dataFinalizacao = novaData;}

}

Saturday, July 2, 2011

Java - Usando a classe Tarefa

public class TesteTarefa{

public static void main(String[] args){

Tarefa tarefa = new Tarefa();

tarefa.setId(10);

tarefa.setDescricao("Criar gerenciador de tarefa");

System.out.println("tarefa:"+tarefa.getId()+ "-" + tarefa.getDescricao());

}

}

Saturday, July 2, 2011

Ruby

Saturday, July 2, 2011

modinha

dinâmicopoderoso

interpretado

Orientado a Objetos

flexivel

comunidade

elegante

emo

Ruby

Saturday, July 2, 2011

modinha

dinâmicopoderoso

interpretado

Orientado a Objetos

flexivel

comunidade

elegante

emo

Ruby hum..vai dizer que Java não serve mais?

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef getId() return @idend

def setId(id)@id = id

end

def getDescricao()return @descricao

end

def setDescricao(descricao) @descricao = descricaoend

def getDataFinalizacao()return @dataFinalizacao

end

def setDataFinalizacao(novaData) @dataFinalizacao = novaData;end

end

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef getId() return @idend

def setId(id)@id = id

end

def getDescricao()return @descricao

end

def setDescricao(descricao) @descricao = descricaoend

def getDataFinalizacao()return @dataFinalizacao

end

def setDataFinalizacao(novaData) @dataFinalizacao = novaData;end

end

A grande vantagem então é não declarar os tipos das variaveis e

niveis de acesso?

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef getId() return @idend

def setId(id)@id = id

end

def getDescricao()return @descricao

end

def setDescricao(descricao) @descricao = descricaoend

def getDataFinalizacao()return @dataFinalizacao

end

def setDataFinalizacao(novaData) @dataFinalizacao = novaData;end

end

Existem vantagens comoexpressividade

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef getId() return @idend

def setId(id)@id = id

end

def getDescricao()return @descricao

end

def setDescricao(descricao) @descricao = descricaoend

def getDataFinalizacao()return @dataFinalizacao

end

def setDataFinalizacao(novaData) @dataFinalizacao = novaData;end

end

Existem vantagens comoexpressividade

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef id return @idend

def id=(id)@id = id

end

def descricaoreturn @descricao

end

def descricao=(descricao) @descricao = descricaoend

def data_finalizacaoreturn @data_finalizacao

end

def data_finalizacao=(novaData) @data_finalizacao = novaData;end

end

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef id return @idend

def id=(id)@id = id

end

def descricaoreturn @descricao

end

def descricao=(descricao) @descricao = descricaoend

def data_finalizacaoreturn @data_finalizacao

end

def data_finalizacao=(novaData) @data_finalizacao = novaData;end

end

Saturday, July 2, 2011

Ruby - Usando a classe Tarefa

tarefa = Tarefa.newtarefa.id = 10tarefa.descricao = "Criar gerenciador de tarefa"

puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"

Saturday, July 2, 2011

Ruby - Usando a classe Tarefa

tarefa = Tarefa.newtarefa.id = 10tarefa.descricao = "Criar gerenciador de tarefa"

puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"

Setter

’s

Saturday, July 2, 2011

Ruby - Usando a classe Tarefa

tarefa = Tarefa.newtarefa.id = 10tarefa.descricao = "Criar gerenciador de tarefa"

puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"

Parênteses opcionais + Syntax Sugar = código mais expressivo.

Setter

’s

Getter

’s

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef id return @idend

def id=(id)@id = id

end

def descricaoreturn @descricao

end

def descricao=(descricao) @descricao = descricaoend

def data_finalizacaoreturn @data_finalizacao

end

def data_finalizacao=(novaData) @data_finalizacao = novaData;end

end

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef id return @idend

def id=(id)@id = id

end

def descricaoreturn @descricao

end

def descricao=(descricao) @descricao = descricaoend

def data_finalizacaoreturn @data_finalizacao

end

def data_finalizacao=(novaData) @data_finalizacao = novaData;end

end

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefadef id return @idend

def id=(id)@id = id

end

def descricaoreturn @descricao

end

def descricao=(descricao) @descricao = descricaoend

def data_finalizacaoreturn @data_finalizacao

end

def data_finalizacao=(novaData) @data_finalizacao = novaData;end

end

Com metaprogramação diga adeus aos repetidos “get’s/set’s”

Saturday, July 2, 2011

Ruby - classe Tarefa

class Tarefa

attr_accessor :id, :descricao, :data_finalizacao

end

hahahahaha. Hum....

Saturday, July 2, 2011

E com Banco de Dados?

Saturday, July 2, 2011

Java - classe Tarefa com Hibernate

@Entityclass Tarefa{ @Id @GeneratedValueprivate Long id;private String descricao;private Calendar dataFinalizacao;

public Long getId(){ return this.id;}public void setId(Long id){this.id = id;

} public String getDescricao(){return this.descricao;

}public void setDescricao(String descricao){ this.descricao = descricao;}public String getDataFinalizacao(){return this.dataFinalizacao;

}...

}

Saturday, July 2, 2011

Ruby - classe Tarefa com BD

class Tarefa < ActiveRecord::Base

end

Menos código ainda

Saturday, July 2, 2011

E com Aplicações Web?

Saturday, July 2, 2011

Web Dev - Java x Ruby

Saturday, July 2, 2011

Vamos largar o Java e migrar para Ruby e Rails ?!

Saturday, July 2, 2011

Mas antes, Tem coisas que

precisamos saber.

Saturday, July 2, 2011

Ruby - Desvantagens

‣ Performance‣ Ruby é lento, =~ 10x mais lento que Java‣ Totalmente interpretado (sem JIT Compiler)

ref: http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=yarv&lang2=java

Saturday, July 2, 2011

Ruby - Desvantagens

‣ Garbage Collection‣ Não eficiente para aplicações Server Side.

ref: http://www.ruby-forum.com/topic/215163#934681

ref: http://jabberwocky.eu/2010/09/03/ruby-garbage-collection/

“ 99.999% is a bit over-exaggerated, but it is true that garbage collection algorithm of YARV and MRI focus for throughput on non-memory extensive short-running programs, and GC of REE is not suitable for those programs.”

Yukihiro Matsumoto

Saturday, July 2, 2011

Ruby/Rails - Desvantagens

Saturday, July 2, 2011

Ruby/Rails - Desvantagens

Deploy ‣ Heroku ‣ https://github.com/heroku/heroku

Saturday, July 2, 2011

Ruby/Rails - Desvantagens

Deploy ‣ Heroku ‣ https://github.com/heroku/heroku

‣ Engine Yard ‣ https://github.com/engineyard/engineyard

Não é

desvan

tagem

Também

não

é desv

antage

m

Saturday, July 2, 2011

Ruby/Rails - Desvantagens

Deploy ‣ Heroku ‣ https://github.com/heroku/heroku

‣ Engine Yard ‣ https://github.com/engineyard/engineyard

‣ Outros ‣ capistrano? ‣ rpm?‣ deb?

Não é

desvan

tagem

Também

não

é desv

antage

m

Saturday, July 2, 2011

Ruby/Rails - Desvantagens

Deploy ‣ Heroku ‣ https://github.com/heroku/heroku

‣ Engine Yard ‣ https://github.com/engineyard/engineyard

‣ Outros ‣ capistrano? ‣ rpm?‣ deb?

Não é

desvan

tagem

Também

não

é desv

antage

m

Aqui s

im

você p

ode

ter pr

oblema

Saturday, July 2, 2011

Java = BurocráticoRuby/Rails = lento

E agora?

Saturday, July 2, 2011

Java = BurocráticoRuby/Rails = lento

E agora?Só falta mudar

pra .net

Saturday, July 2, 2011

.net ???Tira essa farda preta porque

você é moleque!!!

Saturday, July 2, 2011

Uma implementação 100% Java da

linguagem RubySaturday, July 2, 2011

Java como plataforma

ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011

JRuby - Features

Saturday, July 2, 2011

JRuby - Features

‣ Roda na JVM ‣ Threads Nativas‣ JIT ( Just In Time compiler )‣ O melhor GC do mundo

Saturday, July 2, 2011

JRuby - Features

‣ Roda na JVM ‣ Threads Nativas‣ JIT ( Just In Time compiler )‣ O melhor GC do mundo

‣ Permite o uso das bibliotecas e classes Java‣ JDBC, Servlets, Hibernate‣ seus prórprios JAR’s

Saturday, July 2, 2011

JRuby - Features

‣ Roda na JVM ‣ Threads Nativas‣ JIT ( Just In Time compiler )‣ O melhor GC do mundo

‣ Permite o uso das bibliotecas e classes Java‣ JDBC, Servlets, Hibernate‣ seus prórprios JAR’s

‣ Suporta Rubygems

Saturday, July 2, 2011

JRuby - Features

‣ Roda na JVM ‣ Threads Nativas‣ JIT ( Just In Time compiler )‣ O melhor GC do mundo

‣ Permite o uso das bibliotecas e classes Java‣ JDBC, Servlets, Hibernate‣ seus prórprios JAR’s

‣ Suporta Rubygems‣ Suporta Rails

Saturday, July 2, 2011

JRuby - Features

‣ Roda na JVM ‣ Threads Nativas‣ JIT ( Just In Time compiler )‣ O melhor GC do mundo

‣ Permite o uso das bibliotecas e classes Java‣ JDBC, Servlets, Hibernate‣ seus prórprios JAR’s

‣ Suporta Rubygems‣ Suporta Rails‣ Deixa até você usar Ruby com Windows

Saturday, July 2, 2011

Legal! Mas e aquele

papo de Ruby no Java?

Saturday, July 2, 2011

Vejamos algumas situações do

dia a dia

Saturday, July 2, 2011

JRuby - Cenário 1

Importar planilha

Empresa 100% Java precisa fazer uma carga de dados a partir de uma planilha excel.

Saturday, July 2, 2011

Uma solução comum seria usar Java + Apache POI

ref: http://poi.apache.org

Saturday, July 2, 2011

import org.apache.poi.hssf.usermodel.*;//mais importspublic class ExcelReadExample { public static void main(String[] args) throws Exception { String filename = "..\\data.xls"; List sheetData = new ArrayList(); FileInputStream fis = null; try { fis = new FileInputStream(filename); HSSFWorkbook workbook = new HSSFWorkbook(fis); HSSFSheet sheet = workbook.getSheetAt(0); Iterator rows = sheet.rowIterator(); while (rows.hasNext()) { HSSFRow row = (HSSFRow) rows.next(); Iterator cells = row.cellIterator(); List data = new ArrayList(); while (cells.hasNext()) { HSSFCell cell = (HSSFCell) cells.next(); data.add(cell); } sheetData.add(data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { fis.close(); } } showExelData(sheetData); }//mais código ainda

Importar Planilha - Java + Apache POI

Saturday, July 2, 2011

import org.apache.poi.hssf.usermodel.*;//mais importspublic class ExcelReadExample { public static void main(String[] args) throws Exception { String filename = "..\\data.xls"; List sheetData = new ArrayList(); FileInputStream fis = null; try { fis = new FileInputStream(filename); HSSFWorkbook workbook = new HSSFWorkbook(fis); HSSFSheet sheet = workbook.getSheetAt(0); Iterator rows = sheet.rowIterator(); while (rows.hasNext()) { HSSFRow row = (HSSFRow) rows.next(); Iterator cells = row.cellIterator(); List data = new ArrayList(); while (cells.hasNext()) { HSSFCell cell = (HSSFCell) cells.next(); data.add(cell); } sheetData.add(data); } } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { fis.close(); } } showExelData(sheetData); }//mais código ainda

Importar Planilha - Java + Apache POI

Saturday, July 2, 2011

JRuby pode desburocratizar

este código

Saturday, July 2, 2011

require 'java'require "lib/dom4j-1.6.1"require "lib/poi-3.7-20101029"require "lib/poi-ooxml-3.7-20101029"require "lib/poi-ooxml-schemas-3.7-20101029"require "lib/xmlbeans-2.3.0"

//imports

inp = FileInputStream.new('./dados.xlsx')wb = WorkbookFactory.create(inp)sheet = wb.sheet_at 0 nomes = []rows = sheet.rowIterator()rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell endendnomes.each{ |nome| puts nome }

Importar Planilha - JRuby + Apache POI

Saturday, July 2, 2011

require 'java'require "lib/dom4j-1.6.1"require "lib/poi-3.7-20101029"require "lib/poi-ooxml-3.7-20101029"require "lib/poi-ooxml-schemas-3.7-20101029"require "lib/xmlbeans-2.3.0"

//imports

inp = FileInputStream.new('./dados.xlsx')wb = WorkbookFactory.create(inp)sheet = wb.sheet_at 0 nomes = []rows = sheet.rowIterator()rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell endendnomes.each{ |nome| puts nome }

Importar Planilha - JRuby + Apache POI

Saturday, July 2, 2011

require 'java'require "lib/dom4j-1.6.1"require "lib/poi-3.7-20101029"require "lib/poi-ooxml-3.7-20101029"require "lib/poi-ooxml-schemas-3.7-20101029"require "lib/xmlbeans-2.3.0"

//imports

inp = FileInputStream.new('./dados.xlsx')wb = WorkbookFactory.create(inp)sheet = wb.sheet_at 0 nomes = []rows = sheet.rowIterator()rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell endendnomes.each{ |nome| puts nome }

Importar Planilha - JRuby + Apache POI

Saturday, July 2, 2011

require 'java'require "lib/dom4j-1.6.1"require "lib/poi-3.7-20101029"require "lib/poi-ooxml-3.7-20101029"require "lib/poi-ooxml-schemas-3.7-20101029"require "lib/xmlbeans-2.3.0"

//imports

inp = FileInputStream.new('./dados.xlsx')wb = WorkbookFactory.create(inp)sheet = wb.sheet_at 0 nomes = []rows = sheet.rowIterator()rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell endendnomes.each{ |nome| puts nome }

Importar Planilha - JRuby + Apache POI

Saturday, July 2, 2011

require 'java'require "lib/dom4j-1.6.1"require "lib/poi-3.7-20101029"require "lib/poi-ooxml-3.7-20101029"require "lib/poi-ooxml-schemas-3.7-20101029"require "lib/xmlbeans-2.3.0"

//imports

inp = FileInputStream.new('./dados.xlsx')wb = WorkbookFactory.create(inp)sheet = wb.sheet_at 0 nomes = []rows = sheet.rowIterator()rows.each do |row| cells = row.cellIterator cells.each do |cell| nomes << cell endendnomes.each{ |nome| puts nome }

Importar Planilha - JRuby + Apache POI

Melhorou mas não se esqueça:Com JRuby você pode usar gems

Saturday, July 2, 2011

jruby-poi

ref: http://github.com/kameeoze/jruby-poiSaturday, July 2, 2011

require 'rubygems'require 'poi'

workbook = POI::Workbook.open('./dados.xlsx')rows = workbook.worksheets.first.rowsnomes = []rows.each do |row| nomes << row[0].value unless row.index == 0end

nomes.each{ |nome| puts nome }

Importar Planilha - JRuby + jruby-poi

Saturday, July 2, 2011

require 'rubygems'require 'poi'

workbook = POI::Workbook.open('./dados.xlsx')rows = workbook.worksheets.first.rowsnomes = []rows.each do |row| nomes << row[0].value unless row.index == 0end

nomes.each{ |nome| puts nome }

Importar Planilha - JRuby + jruby-poi

Saturday, July 2, 2011

require 'rubygems'require 'poi'

workbook = POI::Workbook.open('./dados.xlsx')rows = workbook.worksheets.first.rowsnomes = []rows.each do |row| nomes << row[0].value unless row.index == 0end

nomes.each{ |nome| puts nome }

Importar Planilha - JRuby + jruby-poi

Saturday, July 2, 2011

require 'rubygems'require 'poi'

workbook = POI::Workbook.open('./dados.xlsx')rows = workbook.worksheets.first.rowsnomes = []rows.each do |row| nomes << row[0].value unless row.index == 0end

nomes.each{ |nome| puts nome }

Importar Planilha - JRuby + jruby-poi

Saturday, July 2, 2011

require 'rubygems'require 'poi'

workbook = POI::Workbook.open('./dados.xlsx')rows = workbook.worksheets.first.rowsnomes = []rows.each do |row| nomes << row[0].value unless row.index == 0end

nomes.each{ |nome| puts nome }

Importar Planilha - JRuby + jruby-poi

Gem Wins!!!

Saturday, July 2, 2011

JRuby - Cenário 2

Criar Web Service

Empresa 100% Java Precisa expor os dados de sua aplicação Web Struts2 na web

Saturday, July 2, 2011

Uma solução sofisticada seria

usar: Java + JAX-RS

http://jsr311.java.net/nonav/releases/1.1/index.html

Saturday, July 2, 2011

//imports aqui...@Path("/tarefa")public class TarefaResource { private Session session; @Context private UriInfo uriInfo; public TarefaResource() { this.session = new HibernateUtil().getSession(); } @GET @Path("{sigla}") @Produces( {MediaType.APPLICATION_XML }) public String getTarefas() { TarefaDao dao = new TarefaDao(this.session); Tarefa Tarefa = dao.listaTarefas(); String xml =

new TarefaXMLAssembler().convertTarefaToXML(Tarefa, uriInfo); return xml; } //...}

Web Service- Java + JAX-RS

Saturday, July 2, 2011

Web ServicesJRuby Way

Saturday, July 2, 2011

Sinatra é uma DSL para criação de aplicações web.

JRuby - Sinatra

ref: http://www.sinatrarb.com/

ref: https://github.com/sinatra/sinatra/

Saturday, July 2, 2011

Web Service- Estrutura do projeto

Saturday, July 2, 2011

require 'rubygems'

require 'sinatra'require 'java'

require 'jruby-rack'

require 'lib/fj21-tarefas'

require 'lib/mysql-connector-java-5.1.7-bin'

require 'lib/xstream-1.3'import 'br.com.caelum.tarefas.dao.TarefaDAO'

import 'br.com.caelum.tarefas.modelo.Tarefa'

import com.thoughtworks.xstream.XStream

import com.thoughtworks.xstream.io.xml.DomDriver

import java.util.List

get '/tarefas' do tarefas = TarefaDAO.new.lista serializer = XStream.new(DomDriver.new) serializer.alias('tarefas', List.java_class) serializer.alias('tarefa', Tarefa.java_class) [200,{"Content-Type"=>"application/xml"},

serializer.to_xml(tarefas)]

end

set :environment, :production

run Sinatra::Application

Web Service- JRuby + Sinatra

config.ru

Saturday, July 2, 2011

require 'rubygems'

require 'sinatra'require 'java'

require 'jruby-rack'

require 'lib/fj21-tarefas'

require 'lib/mysql-connector-java-5.1.7-bin'

require 'lib/xstream-1.3'import 'br.com.caelum.tarefas.dao.TarefaDAO'

import 'br.com.caelum.tarefas.modelo.Tarefa'

import com.thoughtworks.xstream.XStream

import com.thoughtworks.xstream.io.xml.DomDriver

import java.util.List

get '/tarefas' do tarefas = TarefaDAO.new.lista serializer = XStream.new(DomDriver.new) serializer.alias('tarefas', List.java_class) serializer.alias('tarefa', Tarefa.java_class) [200,{"Content-Type"=>"application/xml"},

serializer.to_xml(tarefas)]

end

set :environment, :production

run Sinatra::Application

Web Service- JRuby + Sinatra

config.ru

Saturday, July 2, 2011

para executar o projeto basta fazer um:

e um servidor será iniciado na porta 9292 de localhost

JRuby - Sinatra

ref: http://www.sinatrarb.com/

ref: https://github.com/sinatra/sinatra/

rackup

Saturday, July 2, 2011

Ao fazer a requisição:

obteremos a seguinte resposta:

JRuby - Sinatra

curl localhost:9292/tarefas

Saturday, July 2, 2011

Muito Bom!Mas como eu faço deploy no Tomcat?

Saturday, July 2, 2011

warbler

ref: https://github.com/nicksieger/warblerSaturday, July 2, 2011

JRuby - Warbler

gem install warbler

Saturday, July 2, 2011

JRuby - Warbler

gem install warbler

warble config

Saturday, July 2, 2011

JRuby - Warbler

Warbler::Config.new do |config|

config.dirs = %w(lib)

config.includes = FileList["server.rb"]

config.war_name = "tarefasWS"

end

warble.rb

Saturday, July 2, 2011

JRuby - Warbler

Warbler::Config.new do |config|

config.dirs = %w(lib)

config.includes = FileList["server.rb"]

config.war_name = "tarefasWS"

end

warble.rb

Saturday, July 2, 2011

JRuby - Warbler

Warbler::Config.new do |config|

config.dirs = %w(lib)

config.includes = FileList["server.rb"]

config.war_name = "tarefasWS"

end

warble.rb

Saturday, July 2, 2011

JRuby - Warbler

Warbler::Config.new do |config|

config.dirs = %w(lib)

config.includes = FileList["server.rb"]

config.war_name = "tarefasWS"

end

warble.rb

Saturday, July 2, 2011

JRuby - Warbler

warble war

Saturday, July 2, 2011

Conclusão

Saturday, July 2, 2011

Você não precisa mudar de emprego para programar com Ruby

Conclusão - Java como Plataforma

ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011

Aceite o Java como Plataforma.

Conclusão - Java como Plataforma

ref: http://www.slideshare.net/sifra/jruby-enterprise-20Saturday, July 2, 2011

Conclusão - Seja Poliglota

Saturday, July 2, 2011