Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Jruby - Ruby em Ambientes 100% Java
1. Tirando o máximo
da JVM com Ruby
Hugo Roque Sergio Azevedo Junior
hugo.roque@caelum.com.br sergio.junior@caelum.com.br
hugolnx.com sagadoprogramador.com.br
@hugolnx @sergioazevedo
Saturday, July 2, 2011
2. Nós não somos o
Douglas Campos
@qmx
Saturday, July 2, 2011
3. Tirando o máximo
da JVM com Ruby
Hugo Roque Sergio Azevedo Junior
hugo.roque@caelum.com.br sergio.junior@caelum.com.br
hugolnx.com sagadoprogramador.com.br
@hugolnx @sergioazevedo
Saturday, July 2, 2011
4. Ruby em Ambientes
100% Java
Hugo Roque Sergio Azevedo Junior
hugo.roque@caelum.com.br sergio.junior@caelum.com.br
hugolnx.com sagadoprogramador.com.br
@hugolnx @sergioazevedo
Saturday, July 2, 2011
6. 10 anos de mercado
multiplataforma
compilado JVM
Java
bibliotecas
frameworks
JIT
estático
comunidade
Saturday, July 2, 2011
7. 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
8. 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
10. dinâmico
poderoso
interpretado
elegante
Ruby
modinha
flexivel
comunidade emo
Orientado a Objetos
Saturday, July 2, 2011
11. dinâmico
poderoso
interpretado
elegante
Ruby hum..vai dizer que
Java não serve mais?
modinha
flexivel
comunidade emo
Orientado a Objetos
Saturday, July 2, 2011
12. Ruby - classe Tarefa
class Tarefa
def getId()
return @id
end
def setId(id)
@id = id
end
def getDescricao()
return @descricao
end
def setDescricao(descricao)
@descricao = descricao
end
def getDataFinalizacao()
return @dataFinalizacao
end
def setDataFinalizacao(novaData)
@dataFinalizacao = novaData;
end
end
Saturday, July 2, 2011
13. Ruby - classe Tarefa
class Tarefa
def getId()
return @id A grande vantagem então é não
end
declarar os tipos das variaveis e
def setId(id)
@id = id niveis de acesso?
end
def getDescricao()
return @descricao
end
def setDescricao(descricao)
@descricao = descricao
end
def getDataFinalizacao()
return @dataFinalizacao
end
def setDataFinalizacao(novaData)
@dataFinalizacao = novaData;
end
end
Saturday, July 2, 2011
14. Ruby - classe Tarefa
class Tarefa
def getId()
return @id
end Existem vantagens como
def setId(id) expressividade
@id = id
end
def getDescricao()
return @descricao
end
def setDescricao(descricao)
@descricao = descricao
end
def getDataFinalizacao()
return @dataFinalizacao
end
def setDataFinalizacao(novaData)
@dataFinalizacao = novaData;
end
end
Saturday, July 2, 2011
15. Ruby - classe Tarefa
class Tarefa
def getId()
return @id
end Existem vantagens como
def setId(id) expressividade
@id = id
end
def getDescricao()
return @descricao
end
def setDescricao(descricao)
@descricao = descricao
end
def getDataFinalizacao()
return @dataFinalizacao
end
def setDataFinalizacao(novaData)
@dataFinalizacao = novaData;
end
end
Saturday, July 2, 2011
16. Ruby - classe Tarefa
class Tarefa
def id
return @id
end
def id=(id)
@id = id
end
def descricao
return @descricao
end
def descricao=(descricao)
@descricao = descricao
end
def data_finalizacao
return @data_finalizacao
end
def data_finalizacao=(novaData)
@data_finalizacao = novaData;
end
end
Saturday, July 2, 2011
17. Ruby - classe Tarefa
class Tarefa
def id
return @id
end
def id=(id)
@id = id
end
def descricao
return @descricao
end
def descricao=(descricao)
@descricao = descricao
end
def data_finalizacao
return @data_finalizacao
end
def data_finalizacao=(novaData)
@data_finalizacao = novaData;
end
end
Saturday, July 2, 2011
18. Ruby - Usando a classe Tarefa
tarefa = Tarefa.new
tarefa.id = 10
tarefa.descricao = "Criar gerenciador de tarefa"
puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"
Saturday, July 2, 2011
19. Ruby - Usando a classe Tarefa
r’s
tarefa = Tarefa.new
Se tte
tarefa.id = 10
tarefa.descricao = "Criar gerenciador de tarefa"
puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"
Saturday, July 2, 2011
20. Ruby - Usando a classe Tarefa
r’s
tarefa = Tarefa.new
Se tte
tarefa.id = 10
tarefa.descricao = "Criar gerenciador de tarefa"
puts "tarefa: #{tarefa.id} - #{tarefa.descricao}"
’s
et ter
G
Parênteses opcionais + Syntax Sugar
= código mais expressivo.
Saturday, July 2, 2011
21. Ruby - classe Tarefa
class Tarefa
def id
return @id
end
def id=(id)
@id = id
end
def descricao
return @descricao
end
def descricao=(descricao)
@descricao = descricao
end
def data_finalizacao
return @data_finalizacao
end
def data_finalizacao=(novaData)
@data_finalizacao = novaData;
end
end
Saturday, July 2, 2011
22. Ruby - classe Tarefa
class Tarefa
def id
return @id
end
def id=(id)
@id = id
end
def descricao
return @descricao
end
def descricao=(descricao)
@descricao = descricao
end
def data_finalizacao
return @data_finalizacao
end
def data_finalizacao=(novaData)
@data_finalizacao = novaData;
end
end
Saturday, July 2, 2011
23. Ruby - classe Tarefa
class Tarefa
def id
return @id
end
Com metaprogramação diga
def id=(id)
@id = id
adeus aos repetidos “get’s/set’s”
end
def descricao
return @descricao
end
def descricao=(descricao)
@descricao = descricao
end
def data_finalizacao
return @data_finalizacao
end
def data_finalizacao=(novaData)
@data_finalizacao = novaData;
end
end
Saturday, July 2, 2011
24. Ruby - classe Tarefa
class Tarefa
attr_accessor :id, :descricao, :data_finalizacao
end
hahahahaha. Hum....
Saturday, July 2, 2011
30. Vamos largar o Java
e migrar para
Ruby e Rails ?!
Saturday, July 2, 2011
31. Mas antes,
Tem coisas que
precisamos saber.
Saturday, July 2, 2011
32. 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
33. Ruby - Desvantagens
‣ Garbage Collection
‣ Não eficiente para aplicações Server Side.
“ 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
ref: http://www.ruby-forum.com/topic/215163#934681
ref: http://jabberwocky.eu/2010/09/03/ruby-garbage-collection/
Saturday, July 2, 2011
36. Ruby/Rails - Desvantagens
Deploy
o é gem
Nã ta
‣ Heroku van
des
‣ https://github.com/heroku/heroku
Saturday, July 2, 2011
37. Ruby/Rails - Desvantagens
Deploy
o é gem
Nã ta
‣ Heroku van
des
‣ https://github.com/heroku/heroku
‣ Engine Yard
‣ https://github.com/engineyard/engineyard
Saturday, July 2, 2011
38. Ruby/Rails - Desvantagens
Deploy
o é gem
Nã ta
‣ Heroku van
des
‣ https://github.com/heroku/heroku
‣ Engine Yard não m
ém age
amb ant
‣ https://github.com/engineyard/engineyard
T
esv
é d
Saturday, July 2, 2011
39. Ruby/Rails - Desvantagens
Deploy
o é gem
Nã ta
‣ Heroku van
des
‣ https://github.com/heroku/heroku
‣ Engine Yard não m
ém age
amb ant
‣ https://github.com/engineyard/engineyard
T
esv
é d
‣ Outros
‣ capistrano?
‣ rpm?
‣ deb?
Saturday, July 2, 2011
40. Ruby/Rails - Desvantagens
Deploy
o é gem
Nã ta
‣ Heroku van
des
‣ https://github.com/heroku/heroku
‣ Engine Yard não m
ém age
amb ant
‣ https://github.com/engineyard/engineyard
T
esv
é d
‣ Outros
‣ capistrano?
sim
‣ rpm? A qui pode a
cê blem
vo ro
‣ deb? r p
te
Saturday, July 2, 2011
47. JRuby - Features
‣ Roda na JVM
‣ Threads Nativas
‣ JIT ( Just In Time compiler )
‣ O melhor GC do mundo
Saturday, July 2, 2011
48. 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
49. 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
50. 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
51. 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
52. Legal!
Mas e aquele
papo de Ruby no
Java?
Saturday, July 2, 2011
53. Vejamos algumas
situações do
dia a dia
Saturday, July 2, 2011
54. 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
55. Uma solução
comum seria usar
Java + Apache POI
ref: http://poi.apache.org
Saturday, July 2, 2011
56. Importar Planilha - Java + Apache POI
import org.apache.poi.hssf.usermodel.*;
//mais imports
public 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
Saturday, July 2, 2011
57. Importar Planilha - Java + Apache POI
import org.apache.poi.hssf.usermodel.*;
//mais imports
public 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
Saturday, July 2, 2011
58. JRuby pode
desburocratizar
este código
Saturday, July 2, 2011
59. Importar Planilha - JRuby + Apache POI
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
end
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
60. Importar Planilha - JRuby + Apache POI
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
end
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
61. Importar Planilha - JRuby + Apache POI
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
end
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
62. Importar Planilha - JRuby + Apache POI
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
end
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
63. Importar Planilha - JRuby + Apache POI
require 'java'
require "lib/dom4j-1.6.1"
require "lib/poi-3.7-20101029"
require "lib/poi-ooxml-3.7-20101029"
require
Melhorou mas não se esqueça:
"lib/poi-ooxml-schemas-3.7-20101029"
require "lib/xmlbeans-2.3.0" Com JRuby você pode usar gems
//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
end
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
64. jruby-poi
ref: http://github.com/kameeoze/jruby-poi
Saturday, July 2, 2011
65. Importar Planilha - JRuby + jruby-poi
require 'rubygems'
require 'poi'
workbook = POI::Workbook.open('./dados.xlsx')
rows = workbook.worksheets.first.rows
nomes = []
rows.each do |row|
nomes << row[0].value unless row.index == 0
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
66. Importar Planilha - JRuby + jruby-poi
require 'rubygems'
require 'poi'
workbook = POI::Workbook.open('./dados.xlsx')
rows = workbook.worksheets.first.rows
nomes = []
rows.each do |row|
nomes << row[0].value unless row.index == 0
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
67. Importar Planilha - JRuby + jruby-poi
require 'rubygems'
require 'poi'
workbook = POI::Workbook.open('./dados.xlsx')
rows = workbook.worksheets.first.rows
nomes = []
rows.each do |row|
nomes << row[0].value unless row.index == 0
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
68. Importar Planilha - JRuby + jruby-poi
require 'rubygems'
require 'poi'
workbook = POI::Workbook.open('./dados.xlsx')
rows = workbook.worksheets.first.rows
nomes = []
rows.each do |row|
nomes << row[0].value unless row.index == 0
end
nomes.each{ |nome| puts nome }
Saturday, July 2, 2011
69. Importar Planilha - JRuby + jruby-poi
require 'rubygems'
require 'poi'
workbook = POI::Workbook.open('./dados.xlsx')
rows = workbook.worksheets.first.rows
nomes = []
rows.each do |row|
nomes << row[0].value unless row.index == 0
end
nomes.each{ |nome| puts nome }
Gem Wins!!!
Saturday, July 2, 2011
70. 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
71. Uma solução
sofisticada seria
usar:
Java + JAX-RS
http://jsr311.java.net/nonav/releases/1.1/index.html
Saturday, July 2, 2011
72. Web Service- Java + JAX-RS
//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;
}
//...
}
Saturday, July 2, 2011
74. JRuby - Sinatra
Sinatra é uma DSL para criação de aplicações web.
ref: http://www.sinatrarb.com/
ref: https://github.com/sinatra/sinatra/
Saturday, July 2, 2011
76. Web Service- JRuby + Sinatra
require 'rubygems'
require 'sinatra'
require 'java' config.ru
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
Saturday, July 2, 2011
77. Web Service- JRuby + Sinatra
require 'rubygems'
require 'sinatra'
require 'java' config.ru
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
Saturday, July 2, 2011
78. JRuby - Sinatra
para executar o projeto basta fazer um:
rackup
e um servidor será iniciado na porta
9292 de localhost
ref: http://www.sinatrarb.com/
ref: https://github.com/sinatra/sinatra/
Saturday, July 2, 2011
79. JRuby - Sinatra
Ao fazer a requisição:
curl localhost:9292/tarefas
obteremos a seguinte resposta:
Saturday, July 2, 2011
80. Muito Bom!
Mas como eu faço
deploy no Tomcat?
Saturday, July 2, 2011
81. warbler
ref: https://github.com/nicksieger/warbler
Saturday, July 2, 2011
90. Conclusão - Java como Plataforma
Você não precisa mudar de emprego
para programar com Ruby
ref: http://www.slideshare.net/sifra/jruby-enterprise-20
Saturday, July 2, 2011
91. Conclusão - Java como Plataforma
Aceite o Java como Plataforma.
ref: http://www.slideshare.net/sifra/jruby-enterprise-20
Saturday, July 2, 2011