Upload
nick-sieger
View
5.196
Download
3
Embed Size (px)
DESCRIPTION
Slides from Engine Yard/Terremark sponsored webinar "Connecting the worlds of Java and Ruby with JRuby".
Citation preview
ConnectingJava and RubyNick Sieger :: December 14, 2010
To begin at 10 AM Pacific.Audio or visual issues?Call 24/7 WebEx Tech Support (866) 229-3239Slides: http://j.mp/ey-jruby-connecting
ConnectingJava and RubyNick Sieger :: December 14, 2010
http://www.flickr.com/photos/hb2/288721287/
JRuby: Bridge Between Two Worlds
Bridges facilitate...
Movement Cross-pollination Collaboration Trading
Bridge from Ruby to Java
http://www.flickr.com/photos/the_rev/2295096211/http://www.flickr.com/photos/orbitaljoe/4038901965/
Bridge from Java to Ruby
http://www.flickr.com/photos/design-dog/1268749868/
Bridge from Enterprise to Cloud
http://www.flickr.com/photos/nzdave/347532488/ http://www.flickr.com/photos/ancawonka/65927497/
Bridge from Legacy to Greenfield
http://www.flickr.com/photos/cobalt/318394059/ http://www.flickr.com/photos/13010608@N02/2441101211/
RubyDynamic language of the cloud
A word aboutscripting...
It’s for kiddies.
http://www.flickr.com/photos/listenmissy/4869202176/
Ruby: Dynamic, Object-Oriented
Ruby: Duck-Typing
def area(width = 10, height = 2 * width) width * heightend
p area # => 200p area 5 # => 50p area 5, 20 # => 100p area "10", 4 # => ?
Ruby: Duck-Typing
p area "10", 4 # => "10101010"
# From Ruby API docs:
# String#*(num)## Returns a new String containing num copies of# the receiver.## "Ho! " * 3 #=> "Ho! Ho! Ho! "
area true, false # => NoMethodError: undefined method `*' for # true:TrueClass
Ruby: Flexible Syntax
def set_options(env, opts)end
set_options(:production, {"caching" => "on", "debug" => "false"})
set_options(:production, "caching" => "on", "debug" => "false")
set_options :production, {"caching" => "on", "debug" => "false"}
set_options :production, "caching" => "on", "debug" => "false"
Ruby: Blocks
Ruby
Java
list = [1, 2, 3, 4]
list.each {|n| puts n }
list.each do |n| puts nend
List<Integer> list = Arrays.asList(1, 2, 3, 4);
for (Integer n : list) { System.out.println(n);}
Ruby: Blocks
Ruby
Java
list.shuffle! # => [3, 1, 4, 2]
p list.sort {|a, b| b <=> a } # => [4, 3, 2, 1]
Collections.shuffle(list);
Collections.sort(list, new Comparator<Integer>() { public int compare(Integer a, Integer b) { return b > a ? 1 : (b < a ? -1 : 0); } });
System.out.println(list);
Ruby: Blocks
Ruby
Java
File.open(__FILE__) do |file| file.each_line do |line| puts line endend
BufferedReader file = new BufferedReader(new FileReader("Blocks.java"));try { String line; while ((line = buf.readLine()) != null) { System.out.println(line); }} finally { file.close();}
Ruby: Open Classes
msg = "Scramble this so you can't read it!"msg.rot13!
# => NoMethodError: undefined method `rot13!' for # "Scramble this so you can't read it!":String
Ruby: Open Classes
class String def rot13! 0.upto(length - 1) do |i| case self[i] when ?a..?z self[i] = ?a + ((self[i] - ?a) + 13) % 26 when ?A..?Z self[i] = ?A + ((self[i] - ?A) + 13) % 26 end end self endend
Ruby: Open Classes
puts msg.rot13! # => "Fpenzoyr guvf fb lbh pna'g ernq vg!"puts msg.rot13! # => "Scramble this so you can't read it!"
Ruby: Interactive
$ irbirb(main):001:0> list = [1, 2, 3, 4]=> [1, 2, 3, 4]irb(main):002:0> list.shuffle.map {|x| x + rand(10)}.sort=> [6, 7, 11, 13]irb(main):003:0> list=> [1, 2, 3, 4]
Ruby: Interactive
irb(main):004:0> require 'irb/completion'=> trueirb(main):005:0> list.<TAB>Display all 138 possibilities? (y or n) irb(main):005:0> list.d<TAB>list.delete list.delete_at list.delete_if list.detect list.display list.drop list.drop_while list.dup
Ruby: Developer Happiness
=
RubyGems
Testing in Ruby
RSpechttp://cukes.info/http://rspec.info/
Ruby: Summary
Dynamic and Open• Organize code the way you want• Associate behavior with the correct class• No more “Util” classes
Flexible • Express code intent succinctly• Strip away unnecessary ceremony
Interactive • Try out code and get instant feedback• Learn by doing
Happy • Productivity gains lead to increased pleasure• Enjoy crafting clean code
RailsDynamic framework of the cloud
Rails: Opinionated Framework
Place foreverything
Request-basedMVC
Conventionover
Configuration
Defaultswith
Choices
Rails: Place for All Your Code
application code
configuration & environments
routes (URL structure)
database migrations
static assets(images, stylesheets, javascript)
tests
Rails: Request-based MVC
View
ActionView
Controller
ActionController
Model
ActiveRecord
Request
Database
Response
Routing
ActionDispatch
URL GET /people
Routingresources :people #=> people#index
Controller
# app/controllers/people_controller.rbclass PeopleController < ApplicationController def index @people = Person.all endend
Model# app/models/person.rbclass Person < ActiveRecord::Baseend
View app/views/people/index.html.erb
Rails: Convention over Configuration
Rails: Defaults with Choices
Default Alternatives
ORM
View Templates
JavaScript Framework
Database
Test Framework
ActiveRecordDataMapper, MongoMapper, Sequel, Any object with ActiveModel
ERbHAML, Builder XML, Markaby, RedCloth (Textile), BlueCloth (Markdown)
Prototype jQuery
SQLite3MySQL, PostgreSQL, Oracle, more via JRuby + JDBC
Test::Unit RSpec, Cucumber
Why Rails?
http://j.mp/raible-jvm-frameworks
© 2010, Raible DesignsImages by Stuck in Customs - http://www.flickr.com/photos/stuckincustoms
© 2010 Raible Designs
COMPARING JVM WEB FRAMEWORKS
Matt Raiblehttp://raibledesigns.com
Why Rails?
Projectmaturity
InformationBooks,Docs
Developmentspeed
Availableskilled
developers
Consider...
Installing RailsINSTALL gem install rails
Rails: New Application
$ rails new coolapp -m http://jruby.org create create README create Rakefile ...
Rails: Dependencies with Bundler
$ cd coolapp
$ bundle installFetching source index for http://rubygems.org/Using rake (0.8.7) Using abstract (1.0.0) ...Using rails (3.0.3) Your bundle is complete!
Rails: Generate Scaffolding
$ rails generate scaffold person email:string password:string invoke active_record create db/migrate/20101214020707_create_people.rb create app/models/person.rb invoke test_unit create test/unit/person_test.rb create test/fixtures/people.yml route resources :people ...
Rails: Migrate Database
$ rake db:migrate(in /Users/nicksieger/Projects/rails/coolapp)== CreatePeople: migrating ===========================-- create_table(:people) -> 0.0040s -> 0 rows== CreatePeople: migrated (0.0040s) ==================
Rails: Start Dev Server
$ rails server=> Booting WEBrick=> Rails 3.0.3 application starting in development on http://0.0.0.0:3000=> Call with -d to detach=> Ctrl-C to shutdown server[2010-12-13 20:11:28] INFO WEBrick 1.3.1[2010-12-13 20:11:28] INFO ruby 1.8.7 (2010-12-10) [java][2010-12-13 20:11:28] INFO WEBrick::HTTPServer#start: pid=21022 port=3000
Rails: First Page
Rails: Console
$ rails consoleLoading development environment (Rails 3.0.3)irb(main):001:0> Person.create :email => "[email protected]", :password => "rails" => #<Person id: 1, email: "[email protected]", password: "rails", created_at: "2010-12-14 02:21:11", updated_at: "2010-12-14 02:21:11">
Real-world Rails
https://github.com/diaspora/diaspora
https://joindiaspora.com/
Routes
# config/routes.rb (abbreviated)Diaspora::Application.routes.draw do # ... resources :photos, :except => [:index]
#... root :to => 'home#show'end
Verb Path Action Used for
GET /photos indexdisplay a list of all photos
GET /photos/new newreturn an HTML form for creating a new photo
POST /photos create create a new photo
GET /photos/:id show display a specific photo
GET /photos/:id/edit editreturn an HTML form for editing a photo
PUT /photos/:id update update a specific photo
DELETE /photos/:id destroy delete a specific photo
Rails: RESTful Routes
Verb Path Action Used for
GET /photos indexdisplay a list of all photos
GET /photos/new newreturn an HTML form for creating a new photo
POST /photos create create a new photo
GET /photos/:id show display a specific photo
GET /photos/:id/edit editreturn an HTML form for editing a photo
PUT /photos/:id update update a specific photo
DELETE /photos/:id destroy delete a specific photo
Rails: RESTful Routes
:except => [:index]
Controller
# app/controllers/photos_controller.rb (abbr.)class PhotosController < ApplicationController respond_to :html respond_to :json, :only => :show
def show @photo = current_user.find_visible_post_by_id params[:id] # ... respond_with @photo endend
Model
# app/models/photo.rb (abbreviated)class Photo < Post include MongoMapper::Document
require 'carrierwave/orm/mongomapper' mount_uploader :image, ImageUploader
key :caption, String key :status_message_id, ObjectId
belongs_to :status_message
validate :ownership_of_status_message
before_destroy :ensure_user_pictureend
View
Rendering photo list
HAML View
-# app/views/people/show.html.haml (abbr.).span-15.last %h4 = t('_photos') = render 'photos/index', :photos => @posts
-# app/views/photos/_index.html.haml (abbr.)#thumbnails.span-15.last - for photo in photos = link_to photo.url(:thumb_medium), photo_path(photo)
Rendered HTML View
<div class='span-15 last'> <h4> photos </h4> <div class='span-15 last' id='thumbnails'> <a href="/photos/4d0694d..."><img src="/uploads/images/..." /></a> <a href="/photos/4d06949..."><img src="/uploads/images/..." /></a> <a href="/photos/4d068b2..."><img src="/uploads/images/..." /></a> </div></div>
Rails: Summary
Place for Everything &Conventions
• No wasting time deciding where to put something• Shared conventions get team members up to speed quickly
Defaults with Choices • No wasted effort getting started• Easy to add/change components later
Environments• Development: “code and reload”• Test: disposable data• Production: cache and optimize
Community• Mature framework, frequent updates• Rich catalog of plugins• Rails programmers are in-demand
Dynamic toolkit of the cloud
Getting JRuby
OS How to get
All•http://jruby.org/download•Ruby Version Manager (RVM) http://rvm.beginrescueend.com/
Windows •Installer from http://jruby.org/download
Mac OS X •Homebrew - brew install jruby•MacPorts - port install jruby
Ubuntu/Debian •apt-get install jruby (may not be up-to-date, may need multiverse)
Fedora/RHEL/Centos •yum install jruby (may not be up-to-date)
Gentoo •emerge dev-java/jruby (may be old)
http://wiki.jruby.org/JRubyDistributions
Using JRuby
$ jruby script.rb
$ jruby -S gem ...
$ jruby -J-Xmx1G ...
$ jruby --help$ jruby --properties
Run a standalone script
Run Rubygems, IRB, or an installed gem (e.g, rake or rails)
Pass arguments to the JVM
Get help
Access Java from JRuby
Tip: jruby -S gem install flying_saucer to try this example.
require 'java'require 'rubygems'require 'flying_saucer'
java_import org.xhtmlrenderer.pdf.ITextRenderer
document = <<-HTML<html><body><h1>Hello Flying Saucer!</h1></body></html>HTML
File.open("doc.pdf", "wb") do |out| renderer = ITextRenderer.new renderer.set_document_from_string document renderer.layout renderer.create_pdf out.to_outputstreamend
system("open doc.pdf")
Access Java from JRuby
$ jruby saucer.rb
Access Java from JRuby
require 'java'
Loads Java Integration
Access Java from JRuby
require 'rubygems'require 'flying_saucer'
Loads Flying Saucer classes from Rubygems
Access Java from JRuby
Imports ITextRenderer class
java_import org.xhtmlrenderer.pdf.ITextRenderer
Access Java from JRuby
Create new ITextRenderer
Ruby
Java
renderer = ITextRenderer.new
ITextRenderer renderer = new ITextRenderer();
Access Java from JRuby
Set up the document
Ruby
Java
renderer.set_document_from_string document
renderer.setDocumentFromString(document);
Access Java from JRuby
Create PDF with explicit conversion from Ruby IO to Java OutputStream
File.open("doc.pdf", "wb") do |out| ... renderer.create_pdf out.to_outputstreamend
Integrating into Rails
Mime::Type.register 'application/pdf', :pdf
Register PDF mime type in Rails
Integrating into Rails
class PhotosController private def pdf_to_string io = StringIO.new content = render_to_string renderer = ITextRenderer.new renderer.set_document_from_string(content) renderer.layout renderer.create_pdf(io.to_outputstream) io.string endend
Integrating into Rails
class PhotosController def index @photos = Photos.all respond_to do |format| format.html format.pdf do send_data pdf_to_string, :filename => pdf_name + ".pdf", :type => 'application/pdf', :disposition => 'inline' end end endend
Integrating into Rails
http://example.com/photos
http://example.com/photos.pdf
HTML view of photo listing
Inline PDF of photo listing
Rails 3 and JRuby
http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done
Rails Performance
0
2500
5000
7500
10000
12500
15000
over
head
index
tem
plate_
1
partia
l
partia
l_10
coll_
10
rails-simple N = 10,000
ruby 1.9.2jruby-head clientjruby-head server
0
20000
40000
60000
80000
100000
120000
partial_100 coll_100 uniq_100 diff_100
rails-simple N = 10,000
ruby 1.9.2jruby-head clientjruby-head server
http://github.com/wycats/rails-simple-benches
JRuby Deployment
Ruby servers
WEBrick
GF Gem
Trinidad
WAR files
GlassFish
Tomcat
JBoss
PaaS
EY AppCloud
AppEngine
SteamCannon
Warbler
Railsapp warble app.war
deployto java
appserver
•Create a Java EE .war file from a Rails application• “Looks like Java” to the ops staff
INSTALL gem install warbler
JRuby-Rack Servlet Filter
JRuby-RackRackFilterdoFilter
Servlet dispatchpass-thru
On 404:Rails or anyRack-basedapplication
/home.jsp
/home/index
/home.jsp:JSP
/home/index:Rails
Home-Controller
/home/index:404
Hybrid Rails/Java Webapp
RailsMVC
ActionDispatchActionDispatchActionDispatch
RailsMVC ActionController/ActionViewActionController/ActionViewActionController/ActionViewRailsMVC
ActiveModelActiveModelActiveModel
JavaPOJOs
JDBCDataSource
SOAPinterface
Tools
http://redcareditor.com/
http://www.jetbrains.com/ruby/
http://netbeans.org/
Enterprise Software
Evolving and adapting long-running projects with legacy codebases
http://en.wikipedia.org/wiki/File:Sagrada_Familia_01.jpg
Sagrada Família, Barcelona, Spain
http://www.flickr.com
/photos/gonzalvo/4257293127/
http://www.flickr.com/photos/mgrenner57/263392884/
1970s early 2000s
http://www.flickr.com/photos/koocheekoo/38407225/http://w
ww.flickr.com
/photos/27649557@N07/5000528445/
http://www.flickr.com/photos/gpaumier/446059442/ http://www.flickr.com/photos/ilm/12831049/
nativityfacade
passionfacade
scaffolded interior
http://en.wikipedia.org/w
iki/F
ile:Ryugyong_Ho
tel_-_May_2005.JPG
http://en.wikipedia.org/w
iki/File:Ryugyong_Hotel_October_2010.jpg
Ryugyuong Hotel,North Korea2005 2010
http://en.wikipedia.org/w
iki/F
ile:ExteiorSh
earTruss.jpg
http://en.wikipedia.org/w
iki/File:ExtReenfDetail.jpg
seismic retrofit
http://www.flickr.com
/photos/bazylek/3194294047/http://en.wikipedia.org/w
iki/F
ile:Szkieleteor_in_krakow
.JPG
Szkieletor,Kraków, Poland
Built Environment Metaphor
Metaphor Use Ruby, JRuby, and Rails to...
Sagrada Familia • Build a new facade faster with modern technology• Scaffold portions of the application during refactoring
Ryugyong Hotel • Revive a languishing project by putting a new face on it
Seismic retrofit• Reinforce business rules with a DSL• Harden security around an existing application
Szkieletor • Find novel uses for otherwise abandoned code
JRuby Stories: LinkedIn Signal
•High-volume social networking application•http://www.infoq.com/articles/linkedin-scala-jruby-voldemort•http://blog.linkedin.com/2010/09/29/linkedin-signal/
JRuby Stories: Tracker
•Protecting the world from terrorists!•Export Control workflow system•Used by US State dept. and other countries•JRuby, Rails and legacy Java•http://trackernet.org•Making the World Safe For Democracy•David Bock, Arild Shirazi•http://vimeo.com/16270284
JRuby Events
•JRubyConf 2009• free event following RubyConf•~200 attendees
•JRubyConf 2010•standalone conference•150 attendees
•JRuby meetups in SF Bay Area•http://www.meetup.com/SF-Bay-Area-JRuby-Meetup/
Using JRuby
JRuby on AppCloud
JRuby +AppCloud
Resources
•Contact me: Nick Sieger – [email protected]•These slides: http://j.mp/ey-jruby-connecting•JRuby.org – http://jruby.org/•JRubyConf 2010 videos•http://j.mp/jrubyconf-2010-videos
•EY Blog: Resources for Getting Started with Ruby on Rails•http://j.mp/ey-getting-started-rails
•Rails for Zombies•http://railsforzombies.org/
Zero to Rails 3Virtual TrainingJanuary 24-27, 2011 http://www.eventbee.com/view/zero-to-rails-3
Immediately following (optional):Engine Yard AppCloud Demowith Danish Khan15-20 minute overview of AppCloud