KEMBAR78
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011 | PDF
JRuby
+ Rails =
Awesome Java Web Framework!
Nick Sieger
nsieger@engineyard.com
Jfokus 2011
Ruby: Developer
  Happiness


   =
“Ruby is the glue
     that doesn't set”
                     – Dave Thomas

http://pragdave.pragprog.com/pragdave/2006/06/glue_that_doesn.html
Ruby =
                     innovation

http://www.flickr.com/photos/vermininc/2777441779/
Testing


 RSpec
http://rspec.info/             http://cukes.info/
Ruby
Dynamic language of the cloud
Ruby: Dynamic,
Object-Oriented




http://www.flickr.com/photos/listenmissy/4869202176/
Duck-Typing
def area(width = 10, height = 2 * width)
  width * height
end

p   area           #   =>   200
p   area 5         #   =>   50
p   area 5, 20     #   =>   100
p   area "10", 4   #   =>   ?
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
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"
Blocks
       list = [1, 2, 3, 4]

       list.each {|n| puts n }
Ruby
       list.each do |n|
         puts n
       end



       List<Integer> list = Arrays.asList(1, 2, 3, 4);

Java   for (Integer n : list) {
           System.out.println(n);
       }
Blocks
       File.open(__FILE__) do |file|
         file.each_line do |line|
Ruby       puts line
         end
       end



       BufferedReader file =
           new BufferedReader(new FileReader("Blocks.java"));
       try {
           String line;
           while ((line = buf.readLine()) != null) {
Java           System.out.println(line);
           }
       } finally {
           file.close();
       }
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
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
  end
end
Open Classes

puts msg.rot13!
  # => "Fpenzoyr guvf fb lbh pna'g ernq vg!"
puts msg.rot13!
  # => "Scramble this so you can't read it!"
Rails 3
Dynamic framework of the cloud
Opinionated
             Framework

              Request-    Convention    Defaults
 Place for
               based         over        with
everything               Configuration
                MVC                     Choices
Place for everything
            application code
            configuration &
             environments
                routes
            (URL structure)
          database migrations
             static assets
           (images, js, css)
                 tests
Request-based MVC
Request    Routing    Controller
                                      Model
            Action     Action
                                   ActiveRecord
           Dispatch   Controller



                        View
                                    Database
Response              ActionView
Convention over Configuration
URL          GET /people

             resources :people
Routing        #=> people#index

             # app/controllers/people_controller.rb
             class PeopleController < ApplicationController
               def index
Controller       @people = Person.all
               end
             end

             # app/models/person.rb
Model        class Person < ActiveRecord::Base
             end

View         app/views/people/index.html.erb
Defaults with Choices
                 Default        Alternatives

                                DataMapper, MongoMapper,
ORM              ActiveRecord   Sequel, Any object with
                                ActiveModel
                                HAML, XML Builder,
View Templates   ERb            Markaby, RedCloth (Textile),
                                BlueCloth (Markdown)
JavaScript
                 Prototype      jQuery
Framework
                                MySQL, PostgreSQL,
Database         SQLite3        Oracle, more via JRuby +
                                JDBC

Test Framework   Test::Unit     RSpec, Cucumber
Why Rails?

    COMPARING JVM WEB
       FRAMEWORKS
                      Matt Raible
                http://raibledesigns.com




      Images by Stuck in Customs - http://www.flickr.com/photos/stuckincustoms
                                                                                © 2010, Raible Designs
                                 © 2010 Raible Designs



http://j.mp/raible-jvm-frameworks
Why Rails?
Consider...


              Information                  Available
Project                     Development
                 Books,                     skilled
maturity          Docs
                               speed
                                          developers
Installing Rails

 INSTALL   gem install rails
New Application

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

$ cd coolapp

$ bundle install
Fetching 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!
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
         ...
Migrate Database

$ rake db:migrate
(in /Users/nicksieger/Projects/rails/coolapp)
== CreatePeople: migrating ===========================
-- create_table(:people)
   -> 0.0040s
   -> 0 rows
== CreatePeople: migrated (0.0040s) ==================
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
First Page
Controller
class PeopleController < ApplicationController
  # GET /people
  # GET /people.xml
  def index
    @people = Person.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml { render :xml => @people }
    end
  end

  def   show; end
  def   new; end
  def   edit; end
  def   create; end
  def   update; end
  def   destroy; end
end
Model

class Person < ActiveRecord::Base
end
Console

$ rails console
Loading development environment (Rails 3.0.3)
irb(main):001:0> Person.create :email => "nsieger@engineyard.com", ...
=> #<Person id: 1, email: "nsieger@engineyard.com", ...>
Rails 3 and JRuby




http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done
http://ci.jruby.org/
JRuby
Dynamic toolkit of the cloud
Getting JRuby
http://jruby.org/download
JRuby via Maven
        Group ID: org.jruby
Artifact IDs: jruby, jruby-complete
JRuby
drive java • embed • compile
Drive Java
       synth = javax.sound.midi.MidiSystem.synthesizer
Ruby   synth.open
       channel = synth.channels[0]




       import javax.sound.midi.*;

Java   Synthesizer synth = MidiSystem.getSynthesizer();
       synth.open();
       final MidiChannel channel = synth.getChannels()[0];
Drive Java
       frame = javax.swing.JFrame.new "Music Frame"
Ruby   frame.set_size 600, 100
       frame.layout = java.awt.FlowLayout.new




       import java.awt.*;

Java   JFrame frame = new JFrame("Music Frame");
       frame.setSize(600, 100);
       frame.setLayout(new java.awt.FlowLayout());
Drive Java
       KEYS.each do |value, char|
         button = javax.swing.JButton.new char
         button.add_action_listener do |e|
Ruby       channel.note_on value, 99
         end
         frame.add button
       end

       for (Iterator i = keys.entrySet().iterator(); i.hasNext(); ) {
           Map.Entry entry = (Map.Entry) i.next();
           final Integer value = (Integer) entry.getKey();
           String name = (String) entry.getValue();
           JButton button = new JButton(name);

Java       button.addActionListener(new java.awt.event.ActionListener() {
               public void actionPerformed(java.awt.event.ActionEvent e) {
                   channel.noteOn(value, 99);
               }
           });
           frame.add(button);
       }
MIDI Swing
Embed
import org.jruby.embed.ScriptingContainer;

public class EmbedJRuby {
    public static void main(String[] args) {
        ScriptingContainer container = new ScriptingContainer();
        container.runScriptlet("puts 'Hello from Ruby'");
    }
}
http://wiki.jruby.org/
      RedBridge
Compile
# engine.rb
require 'java'
java_package 'demo'

class Engine
  java_implements 'java.lang.Runnable'

  java_signature 'void run()'
  def run
    puts "The #{self.inspect} is running."
  end
end
Compile
// Starter.java
import demo.Engine;

public class Starter {
    public static void main(String[] args) {
        Runnable engine = new Engine();
        engine.run();
    }
}
Compile

$ jrubyc --javac engine.rb Starter.java
Generating Java class Engine to demo/Engine.java
javac -d . -cp jruby.jar:. demo/Engine.java Starter.java
Compile
// Engine.java
package demo;

public class Engine implements Runnable {
    public void run() { ... }
}
Compile

$ java -cp jruby.jar:. Starter
The #<Engine:0x59c958af> is running.
JRuby 1.6
             Release soon!
ruby 1.9.2 • c-ext • perf • dynopt • java
activerecord-jdbc
 ActiveRecord with JDBC databases

INSTALL   gem install activerecord-jdbc-adapter
Warbler
              INSTALL    gem install warbler




• Create a Java EE .war file from a Rails application
• “Looks like Java” to the ops staff


                                                         deploy
   Rails
                    warble           app.war             to java
   app
                                                       appserver
JRuby Deployment
Ruby servers   WAR files     Cloud

  WEBrick      GlassFish   EY AppCloud

  Trinidad      Tomcat     AppEngine

 TorqueBox       JBoss       AWS EB
Enterprise Software
 Evolving and adapting long-running
   projects with legacy codebases
Sagrada Família,
Barcelona, Spain
passion
                       facade


   nativity
   facade


scaffolded interior
Ryugyuong Hotel,
2005     North Korea      2010
seismic retrofit
Szkieletor,
Kraków, Poland
Hybrid Rails/Java App
                    ActionDispatch

  Rails       ActionController/ActionView
  MVC

                     ActiveModel

   Java     Java       JDBC            SOAP
 Backend   POJOs    DataSource       interface
https://github.com/nicksieger/
        spring-petclinic
Metaphor     Use Ruby, JRuby, and Rails to...

Sagrada      • Build new facade faster
Familia      • Scaffolding during refactoring

Ryugyong
             • Revive a project with a new face
  Hotel

 Seismic     • Reinforce business rules with a DSL
 retrofit    • Harden security


Szkieletor   • Find novel uses for abandoned code
engineyard.com/services
Resources
                    Resources for
                 Getting Started with
  JRuby.org         Ruby on Rails



JRubyConf 2010   Rails for
    Videos       Zombies
Nick Sieger
nsieger@engineyard.com
Slides: http://j.mp/sieger-jfokus
Images
http://en.wikipedia.org/wiki/File:Sagrada_Familia_01.jpg
http://www.flickr.com/photos/gonzalvo/4257293127/
http://www.flickr.com/photos/mgrenner57/263392884/
http://www.flickr.com/photos/koocheekoo/38407225/
http://www.flickr.com/photos/27649557@N07/5000528445/
http://www.flickr.com/photos/gpaumier/446059442/
http://www.flickr.com/photos/ilm/12831049/
http://en.wikipedia.org/wiki/File:Ryugyong_Hotel_-_May_2005.JPG
http://en.wikipedia.org/wiki/File:Ryugyong_Hotel_October_2010.jpg
http://en.wikipedia.org/wiki/File:ExteiorShearTruss.jpg
http://en.wikipedia.org/wiki/File:ExtReenfDetail.jpg
http://en.wikipedia.org/wiki/File:Szkieleteor_in_krakow.JPG
http://www.flickr.com/photos/bazylek/3194294047/
JRuby + Rails = Awesome Java Web Framework at Jfokus 2011

JRuby + Rails = Awesome Java Web Framework at Jfokus 2011