connecting the worlds of java and ruby with jruby

91
Connecting Java and Ruby Nick Sieger :: December 14, 2010 To begin at 10 AM Pacific. Audio or visual issues? Call 24/7 WebEx Tech Support (866) 229-3239 Slides: http://j.mp/ey-jruby-connecting

Upload: nick-sieger

Post on 10-May-2015

5.196 views

Category:

Technology


3 download

DESCRIPTION

Slides from Engine Yard/Terremark sponsored webinar "Connecting the worlds of Java and Ruby with JRuby".

TRANSCRIPT

Page 1: Connecting the Worlds of Java and Ruby with JRuby

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

Page 2: Connecting the Worlds of Java and Ruby with JRuby

ConnectingJava and RubyNick Sieger :: December 14, 2010

Page 3: Connecting the Worlds of Java and Ruby with JRuby

http://www.flickr.com/photos/hb2/288721287/

JRuby: Bridge Between Two Worlds

Page 4: Connecting the Worlds of Java and Ruby with JRuby

Bridges facilitate...

Movement Cross-pollination Collaboration Trading

Page 5: Connecting the Worlds of Java and Ruby with JRuby

Bridge from Ruby to Java

http://www.flickr.com/photos/the_rev/2295096211/http://www.flickr.com/photos/orbitaljoe/4038901965/

Page 6: Connecting the Worlds of Java and Ruby with JRuby

Bridge from Java to Ruby

http://www.flickr.com/photos/design-dog/1268749868/

Page 7: Connecting the Worlds of Java and Ruby with JRuby

Bridge from Enterprise to Cloud

http://www.flickr.com/photos/nzdave/347532488/ http://www.flickr.com/photos/ancawonka/65927497/

Page 8: Connecting the Worlds of Java and Ruby with JRuby

Bridge from Legacy to Greenfield

http://www.flickr.com/photos/cobalt/318394059/ http://www.flickr.com/photos/13010608@N02/2441101211/

Page 9: Connecting the Worlds of Java and Ruby with JRuby

RubyDynamic language of the cloud

Page 10: Connecting the Worlds of Java and Ruby with JRuby

A word aboutscripting...

It’s for kiddies.

Page 11: Connecting the Worlds of Java and Ruby with JRuby

http://www.flickr.com/photos/listenmissy/4869202176/

Ruby: Dynamic, Object-Oriented

Page 12: Connecting the Worlds of Java and Ruby with JRuby

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 # => ?

Page 13: Connecting the Worlds of Java and Ruby with JRuby

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

Page 14: Connecting the Worlds of Java and Ruby with JRuby

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"

Page 15: Connecting the Worlds of Java and Ruby with JRuby

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);}

Page 16: Connecting the Worlds of Java and Ruby with JRuby

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);

Page 17: Connecting the Worlds of Java and Ruby with JRuby

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();}

Page 18: Connecting the Worlds of Java and Ruby with JRuby

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

Page 19: Connecting the Worlds of Java and Ruby with JRuby

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

Page 20: Connecting the Worlds of Java and Ruby with JRuby

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!"

Page 21: Connecting the Worlds of Java and Ruby with JRuby

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]

Page 22: Connecting the Worlds of Java and Ruby with JRuby

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

Page 23: Connecting the Worlds of Java and Ruby with JRuby

Ruby: Developer Happiness

=

Page 24: Connecting the Worlds of Java and Ruby with JRuby

RubyGems

Page 25: Connecting the Worlds of Java and Ruby with JRuby

Testing in Ruby

RSpechttp://cukes.info/http://rspec.info/

Page 26: Connecting the Worlds of Java and Ruby with JRuby

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

Page 27: Connecting the Worlds of Java and Ruby with JRuby

RailsDynamic framework of the cloud

Page 28: Connecting the Worlds of Java and Ruby with JRuby

Rails: Opinionated Framework

Place foreverything

Request-basedMVC

Conventionover

Configuration

Defaultswith

Choices

Page 29: Connecting the Worlds of Java and Ruby with JRuby

Rails: Place for All Your Code

application code

configuration & environments

routes (URL structure)

database migrations

static assets(images, stylesheets, javascript)

tests

Page 30: Connecting the Worlds of Java and Ruby with JRuby

Rails: Request-based MVC

View

ActionView

Controller

ActionController

Model

ActiveRecord

Request

Database

Response

Routing

ActionDispatch

Page 31: Connecting the Worlds of Java and Ruby with JRuby

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

Page 32: Connecting the Worlds of Java and Ruby with JRuby

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

Page 33: Connecting the Worlds of Java and Ruby with JRuby

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

Page 34: Connecting the Worlds of Java and Ruby with JRuby

Why Rails?

Projectmaturity

InformationBooks,Docs

Developmentspeed

Availableskilled

developers

Consider...

Page 35: Connecting the Worlds of Java and Ruby with JRuby

Installing RailsINSTALL gem install rails

Page 36: Connecting the Worlds of Java and Ruby with JRuby

Rails: New Application

$ rails new coolapp -m http://jruby.org create create README create Rakefile ...

Page 37: Connecting the Worlds of Java and Ruby with JRuby

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!

Page 38: Connecting the Worlds of Java and Ruby with JRuby

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 ...

Page 39: Connecting the Worlds of Java and Ruby with JRuby

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) ==================

Page 40: Connecting the Worlds of Java and Ruby with JRuby

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

Page 41: Connecting the Worlds of Java and Ruby with JRuby

Rails: First Page

Page 42: Connecting the Worlds of Java and Ruby with JRuby

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">

Page 43: Connecting the Worlds of Java and Ruby with JRuby

Real-world Rails

Page 45: Connecting the Worlds of Java and Ruby with JRuby

Routes

# config/routes.rb (abbreviated)Diaspora::Application.routes.draw do # ... resources :photos, :except => [:index]

#... root :to => 'home#show'end

Page 46: Connecting the Worlds of Java and Ruby with JRuby

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

Page 47: Connecting the Worlds of Java and Ruby with JRuby

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]

Page 48: Connecting the Worlds of Java and Ruby with JRuby

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

Page 49: Connecting the Worlds of Java and Ruby with JRuby

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

Page 50: Connecting the Worlds of Java and Ruby with JRuby

View

Rendering photo list

Page 51: Connecting the Worlds of Java and Ruby with JRuby

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)

Page 52: Connecting the Worlds of Java and Ruby with JRuby

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>

Page 53: Connecting the Worlds of Java and Ruby with JRuby

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

Page 54: Connecting the Worlds of Java and Ruby with JRuby

Dynamic toolkit of the cloud

Page 55: Connecting the Worlds of Java and Ruby with JRuby

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

Page 56: Connecting the Worlds of Java and Ruby with JRuby

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

Page 57: Connecting the Worlds of Java and Ruby with JRuby

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")

Page 58: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

$ jruby saucer.rb

Page 59: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

require 'java'

Loads Java Integration

Page 60: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

require 'rubygems'require 'flying_saucer'

Loads Flying Saucer classes from Rubygems

Page 61: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

Imports ITextRenderer class

java_import org.xhtmlrenderer.pdf.ITextRenderer

Page 62: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

Create new ITextRenderer

Ruby

Java

renderer = ITextRenderer.new

ITextRenderer renderer = new ITextRenderer();

Page 63: Connecting the Worlds of Java and Ruby with JRuby

Access Java from JRuby

Set up the document

Ruby

Java

renderer.set_document_from_string document

renderer.setDocumentFromString(document);

Page 64: Connecting the Worlds of Java and Ruby with JRuby

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

Page 65: Connecting the Worlds of Java and Ruby with JRuby

Integrating into Rails

Mime::Type.register 'application/pdf', :pdf

Register PDF mime type in Rails

Page 66: Connecting the Worlds of Java and Ruby with JRuby

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

Page 67: Connecting the Worlds of Java and Ruby with JRuby

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

Page 68: Connecting the Worlds of Java and Ruby with JRuby

Integrating into Rails

http://example.com/photos

http://example.com/photos.pdf

HTML view of photo listing

Inline PDF of photo listing

Page 69: Connecting the Worlds of Java and Ruby with JRuby

Rails 3 and JRuby

http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done

Page 70: Connecting the Worlds of Java and Ruby with JRuby

http://ci.jruby.org/

Page 71: Connecting the Worlds of Java and Ruby with JRuby

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

Page 72: Connecting the Worlds of Java and Ruby with JRuby

JRuby Deployment

Ruby servers

WEBrick

GF Gem

Trinidad

WAR files

GlassFish

Tomcat

JBoss

PaaS

EY AppCloud

AppEngine

SteamCannon

Page 73: Connecting the Worlds of Java and Ruby with JRuby

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

Page 74: Connecting the Worlds of Java and Ruby with JRuby

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

Page 75: Connecting the Worlds of Java and Ruby with JRuby

Hybrid Rails/Java Webapp

RailsMVC

ActionDispatchActionDispatchActionDispatch

RailsMVC ActionController/ActionViewActionController/ActionViewActionController/ActionViewRailsMVC

ActiveModelActiveModelActiveModel

JavaPOJOs

JDBCDataSource

SOAPinterface

Page 76: Connecting the Worlds of Java and Ruby with JRuby

Tools

http://redcareditor.com/

http://www.jetbrains.com/ruby/

http://netbeans.org/

Page 77: Connecting the Worlds of Java and Ruby with JRuby

Enterprise Software

Evolving and adapting long-running projects with legacy codebases

Page 78: Connecting the Worlds of Java and Ruby with JRuby

http://en.wikipedia.org/wiki/File:Sagrada_Familia_01.jpg

Sagrada Família, Barcelona, Spain

Page 80: Connecting the Worlds of Java and Ruby with JRuby

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

Page 81: Connecting the Worlds of Java and Ruby with JRuby

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

Page 83: Connecting the Worlds of Java and Ruby with JRuby

http://www.flickr.com

/photos/bazylek/3194294047/http://en.wikipedia.org/w

iki/F

ile:Szkieleteor_in_krakow

.JPG

Szkieletor,Kraków, Poland

Page 84: Connecting the Worlds of Java and Ruby with JRuby

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

Page 85: Connecting the Worlds of Java and Ruby with JRuby

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/

Page 86: Connecting the Worlds of Java and Ruby with JRuby

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

Page 87: Connecting the Worlds of Java and Ruby with JRuby

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/

Page 88: Connecting the Worlds of Java and Ruby with JRuby

Using JRuby

Page 89: Connecting the Worlds of Java and Ruby with JRuby

JRuby on AppCloud

JRuby +AppCloud

Page 90: Connecting the Worlds of Java and Ruby with JRuby

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/

Page 91: Connecting the Worlds of Java and Ruby with JRuby

Zero to Rails 3Virtual TrainingJanuary 24-27, 2011 http://www.eventbee.com/view/zero-to-rails-3

[email protected]

Immediately following (optional):Engine Yard AppCloud Demowith Danish Khan15-20 minute overview of AppCloud