Using Java from Ruby with JRuby IRB Hiro Asari Engine Yard Tuesday, June 14, 2011 1
Why JRuby? • Interactive shell for looking around (without writing lots of code) • Testing frameworks • Ruby on Rails Tuesday, June 14, 2011 2
Assumptions • JRuby 1.6.2 (or 1.7.0.dev) • Java 6 (5 or later; 7 support in the works) • Ruby 1.8 Tuesday, June 14, 2011 3 Ruby syntax will be introduced as we go along. We do not use tricky syntax for this presentation
Starting IRB jruby -S irb http://jruby.org/tryjruby Tuesday, June 14, 2011 4 '-S' tells jruby to look for a script thus named in certain locations (in predefined order) and execute it. (of course, the usual semantics re: scripts hold here.) "tryjruby" has some limitations w.r.t. Java integration (obviously)
Loading Java support require 'java' Tuesday, June 14, 2011 5 Like Java's "import"
Finding Java libraries # shell export CLASSPATH=… jruby -J-cp <classpath> … jruby -I lib … # in ruby $: << File.join(File.dirname(__FILE__), 'lib') Tuesday, June 14, 2011 6 Java way, or Ruby way $: is the global for load paths where Ruby looks for libraries __FILE__ is a shorthand for "this file"
Loading Java Library require 'foo.jar' $CLASSPATH << 'foo.jar' Tuesday, June 14, 2011 7
Importing Java class Bazz = Java::foo.bar.Bazz java_import 'foo.bar.Bazz' java_import java.lang.System Tuesday, June 14, 2011 8 Ruby Class names are separated by namespaces, which is delimited by double colons. Java's built-in classes don't need to be referred to via a String Ruby class names are constants, the name of which must start with a capital letter.
Referring to Java class bazz = Java::foo.bar.Bazz.new bazz = Bazz.new # Bazz is already imported Tuesday, June 14, 2011 9 No parentheses are necessary for Ruby methods, unless ambiguous otherwise
Implementing Java interface class Foo include java.lang.Runnable def run puts "foo" end end Tuesday, June 14, 2011 10 JRuby works hard to make this simpler, but you get the idea
Calling static methods Bazz.method(arg1, arg2) java.lang.System.currentTimeMillis Tuesday, June 14, 2011 11 This is similar to calling Ruby's class methods
Accessing static fields java.lang.System.out java.util.logging.Level::INFO Tuesday, June 14, 2011 12 Here, "." and "::" are interchangeable
Type conversion object.to_java(foo.bar.Bazz) "Hello, Richmond!".to_java 5.to_java(java.lang.Double) Tuesday, June 14, 2011 13 For the most part, JRuby converts types for you behind the scenes, so you don’t need to worry about this; but when you do, you can use this. Cannot be used for casting to primitives. Sorry.
Invoking overloaded method // you need a cast in Java… java.lang.System.out.println((char)70) java.lang.System.out.java_send :println, [Java::char], 70 Tuesday, June 14, 2011 14 :println is an example of a Ruby symbol. It is a uniquely identifiable object within the Ruby runtime. "abc" and "abc" maybe two different Strings, but :abc is always unique. Notice how we specify the Java primitive "char"
Complex example with Akka http://akka.io “ Akka is the event-driven, the nextand generation platform for scalable fault-tolerant architectures on the JVM ” Tuesday, June 14, 2011 15
Akka tutorial Compute π using the Madhava-Leibniz series Tuesday, June 14, 2011 16 http://akka.io/docs/akka/1.1.2/intro/getting-started-first-java.html
π = 4(1-1/3+1/5-1/7+1/9-1/11+1/13+…) = 4(1-1/3+1/5-1/7) + 4(1/9-1/11+1/13-1/15) + 4(1/17-1/19+1/21-1/23) +… Tuesday, June 14, 2011 17 http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 Does not converge very fast
How does it work? Pi Calculate Work Work Master PiRouter Worker Result Result Tuesday, June 14, 2011 18 Red: Actors Green: Messages (POJO) Akka actors invoke onReceive(Object) method when a message is sent. A router routes messages between actors.
Akka tutorial Code reading and demo Java source: http://bit.ly/lTClmr Ruby source: https://gist.github.com/1013227 (Without comments) (See also) https://gist.github.com/1013217 Tuesday, June 14, 2011 19 See handout
Directory layout akka-tutorial-first ├── akka-reference.conf ├── akka.conf ├── lib/ │ ├── akka/ │ │ ├── akka-actor-1.1.2.jar │ │ ├── akka-actor-tests-1.1.2.jar │ │ ├── akka-http-1.1.2.jar │ │ ├── akka-remote-1.1.2.jar │ │ ├── akka-slf4j-1.1.2.jar │ │ ├── akka-stm-1.1.2.jar │ │ ├── akka-testkit-1.1.2.jar │ │ ├── akka-typed-actor-1.1.2.jar │ │ ├── aopalliance-1.0.jar │ │ ├── aspectwerkz-2.2.3.jar │ │ ├── commons-codec-1.4.jar │ │ ├── commons-io-2.0.1.jar │ │ ├── dispatch-json_2.9.0-0.8.1.jar │ │ ├── guice-all-2.0.jar │ │ ├── h2-lzf-1.0.jar │ │ ├── jackson-core-asl-1.7.1.jar │ │ ├── jackson-mapper-asl-1.7.1.jar │ │ ├── jsr250-api-1.0.jar │ │ ├── jsr311-api-1.1.jar │ │ ├── multiverse-alpha-0.6.2.jar │ │ ├── netty-3.2.3.Final.jar │ │ ├── objenesis-1.2.jar │ │ ├── protobuf-java-2.3.0.jar │ │ ├── sjson_2.9.0-0.11.jar │ │ └── slf4j-api-1.6.0.jar │ └── scala-library.jar ├── pi.pdf ├── pi.rb └── pi2.rb 2 directories, 31 files Tuesday, June 14, 2011 20 http://akka.io/downloads/ http://akka.io/downloads/akka-actors-1.1.2.zip Move config/* up 1 directory level
Maven integration $ jruby -S gem install mvn:org.clojure:clojure -v 1.2.1 Successfully installed mvn:org.clojure:clojure-1.2.1-java 1 gem installed Tuesday, June 14, 2011 21 n.b.: artifacts with uncommon versions may not be found
Maven integration require 'rubygems' require 'java' require 'maven/org.clojure/clojure' java_import 'clojure.lang.Atom' Atom.new(nil) Tuesday, June 14, 2011 22 https://gist.github.com/660804 "require 'maven/foo.bar/bazz.jar'" doesn't work the first time.
Testing frameworks in Ruby • RSpec • Cucumber Tuesday, June 14, 2011 23
RSpec describe Game do describe "#score" do it "returns 0 for all gutter game" do game = Game.new 20.times { game.roll(0) } game.score.should == 0 end end end Tuesday, June 14, 2011 24 http://relishapp.com/rspec
Cucumber # language: en Feature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two numbers Scenario Outline: Add two numbers Given I have entered <input_1> into the calculator And I have entered <input_2> into the calculator When I press <button> Then the result should be <output> on the screen Examples: | input_1 | input_2 | button | output | | 20 | 30 | add | 50 | | 2 | 5 | add | 7 | | 0 | 40 | add | 40 | Tuesday, June 14, 2011 25 http://cukes.info https://github.com/cucumber/cucumber/blob/master/examples/i18n/en/features/ addition.feature
IDE • RubyMine • NetBeans (separate Ruby plugin for 7.0) • Eclipse Tuesday, June 14, 2011 26
Other stuff • Ant integration • warbler (generate WAR files) • Ruboto (JRuby on Android) Tuesday, June 14, 2011 27
Sponsored plug • JRuby on Rails hosting now available on Engine Yard's AppCloud Tuesday, June 14, 2011 28
JRubyConf 2011 Washington, DC August 3-5 http://jrubyconf.com Tuesday, June 14, 2011 29
Thank you! @hiro_asari hasari@engineyard.com asari.ruby@gmail.com http://github.com/banzaiman Tuesday, June 14, 2011 30
Door prizes! Tuesday, June 14, 2011 31
Door prizes! Tuesday, June 14, 2011 32

Using Java from Ruby with JRuby IRB

  • 1.
    Using Java fromRuby with JRuby IRB Hiro Asari Engine Yard Tuesday, June 14, 2011 1
  • 2.
    Why JRuby? • Interactive shell for looking around (without writing lots of code) • Testing frameworks • Ruby on Rails Tuesday, June 14, 2011 2
  • 3.
    Assumptions • JRuby 1.6.2 (or 1.7.0.dev) • Java 6 (5 or later; 7 support in the works) • Ruby 1.8 Tuesday, June 14, 2011 3 Ruby syntax will be introduced as we go along. We do not use tricky syntax for this presentation
  • 4.
    Starting IRB jruby -S irb http://jruby.org/tryjruby Tuesday, June 14, 2011 4 '-S' tells jruby to look for a script thus named in certain locations (in predefined order) and execute it. (of course, the usual semantics re: scripts hold here.) "tryjruby" has some limitations w.r.t. Java integration (obviously)
  • 5.
    Loading Java support require 'java' Tuesday, June 14, 2011 5 Like Java's "import"
  • 6.
    Finding Java libraries # shell export CLASSPATH=… jruby -J-cp <classpath> … jruby -I lib … # in ruby $: << File.join(File.dirname(__FILE__), 'lib') Tuesday, June 14, 2011 6 Java way, or Ruby way $: is the global for load paths where Ruby looks for libraries __FILE__ is a shorthand for "this file"
  • 7.
    Loading Java Library require 'foo.jar' $CLASSPATH << 'foo.jar' Tuesday, June 14, 2011 7
  • 8.
    Importing Java class Bazz = Java::foo.bar.Bazz java_import 'foo.bar.Bazz' java_import java.lang.System Tuesday, June 14, 2011 8 Ruby Class names are separated by namespaces, which is delimited by double colons. Java's built-in classes don't need to be referred to via a String Ruby class names are constants, the name of which must start with a capital letter.
  • 9.
    Referring to Javaclass bazz = Java::foo.bar.Bazz.new bazz = Bazz.new # Bazz is already imported Tuesday, June 14, 2011 9 No parentheses are necessary for Ruby methods, unless ambiguous otherwise
  • 10.
    Implementing Java interface class Foo include java.lang.Runnable def run puts "foo" end end Tuesday, June 14, 2011 10 JRuby works hard to make this simpler, but you get the idea
  • 11.
    Calling static methods Bazz.method(arg1, arg2) java.lang.System.currentTimeMillis Tuesday, June 14, 2011 11 This is similar to calling Ruby's class methods
  • 12.
    Accessing static fields java.lang.System.out java.util.logging.Level::INFO Tuesday, June 14, 2011 12 Here, "." and "::" are interchangeable
  • 13.
    Type conversion object.to_java(foo.bar.Bazz) "Hello, Richmond!".to_java 5.to_java(java.lang.Double) Tuesday, June 14, 2011 13 For the most part, JRuby converts types for you behind the scenes, so you don’t need to worry about this; but when you do, you can use this. Cannot be used for casting to primitives. Sorry.
  • 14.
    Invoking overloaded method // you need a cast in Java… java.lang.System.out.println((char)70) java.lang.System.out.java_send :println, [Java::char], 70 Tuesday, June 14, 2011 14 :println is an example of a Ruby symbol. It is a uniquely identifiable object within the Ruby runtime. "abc" and "abc" maybe two different Strings, but :abc is always unique. Notice how we specify the Java primitive "char"
  • 15.
    Complex example withAkka http://akka.io “ Akka is the event-driven, the nextand generation platform for scalable fault-tolerant architectures on the JVM ” Tuesday, June 14, 2011 15
  • 16.
    Akka tutorial Compute π using the Madhava-Leibniz series Tuesday, June 14, 2011 16 http://akka.io/docs/akka/1.1.2/intro/getting-started-first-java.html
  • 17.
    π = 4(1-1/3+1/5-1/7+1/9-1/11+1/13+…) = 4(1-1/3+1/5-1/7) + 4(1/9-1/11+1/13-1/15) + 4(1/17-1/19+1/21-1/23) +… Tuesday, June 14, 2011 17 http://en.wikipedia.org/wiki/Leibniz_formula_for_%CF%80 Does not converge very fast
  • 18.
    How does itwork? Pi Calculate Work Work Master PiRouter Worker Result Result Tuesday, June 14, 2011 18 Red: Actors Green: Messages (POJO) Akka actors invoke onReceive(Object) method when a message is sent. A router routes messages between actors.
  • 19.
    Akka tutorial Code reading and demo Java source: http://bit.ly/lTClmr Ruby source: https://gist.github.com/1013227 (Without comments) (See also) https://gist.github.com/1013217 Tuesday, June 14, 2011 19 See handout
  • 20.
    Directory layout akka-tutorial-first ├── akka-reference.conf ├── akka.conf ├── lib/ │ ├── akka/ │ │ ├── akka-actor-1.1.2.jar │ │ ├── akka-actor-tests-1.1.2.jar │ │ ├── akka-http-1.1.2.jar │ │ ├── akka-remote-1.1.2.jar │ │ ├── akka-slf4j-1.1.2.jar │ │ ├── akka-stm-1.1.2.jar │ │ ├── akka-testkit-1.1.2.jar │ │ ├── akka-typed-actor-1.1.2.jar │ │ ├── aopalliance-1.0.jar │ │ ├── aspectwerkz-2.2.3.jar │ │ ├── commons-codec-1.4.jar │ │ ├── commons-io-2.0.1.jar │ │ ├── dispatch-json_2.9.0-0.8.1.jar │ │ ├── guice-all-2.0.jar │ │ ├── h2-lzf-1.0.jar │ │ ├── jackson-core-asl-1.7.1.jar │ │ ├── jackson-mapper-asl-1.7.1.jar │ │ ├── jsr250-api-1.0.jar │ │ ├── jsr311-api-1.1.jar │ │ ├── multiverse-alpha-0.6.2.jar │ │ ├── netty-3.2.3.Final.jar │ │ ├── objenesis-1.2.jar │ │ ├── protobuf-java-2.3.0.jar │ │ ├── sjson_2.9.0-0.11.jar │ │ └── slf4j-api-1.6.0.jar │ └── scala-library.jar ├── pi.pdf ├── pi.rb └── pi2.rb 2 directories, 31 files Tuesday, June 14, 2011 20 http://akka.io/downloads/ http://akka.io/downloads/akka-actors-1.1.2.zip Move config/* up 1 directory level
  • 21.
    Maven integration $ jruby -S gem install mvn:org.clojure:clojure -v 1.2.1 Successfully installed mvn:org.clojure:clojure-1.2.1-java 1 gem installed Tuesday, June 14, 2011 21 n.b.: artifacts with uncommon versions may not be found
  • 22.
    Maven integration require 'rubygems' require 'java' require 'maven/org.clojure/clojure' java_import 'clojure.lang.Atom' Atom.new(nil) Tuesday, June 14, 2011 22 https://gist.github.com/660804 "require 'maven/foo.bar/bazz.jar'" doesn't work the first time.
  • 23.
    Testing frameworks inRuby • RSpec • Cucumber Tuesday, June 14, 2011 23
  • 24.
    RSpec describe Game do describe "#score" do it "returns 0 for all gutter game" do game = Game.new 20.times { game.roll(0) } game.score.should == 0 end end end Tuesday, June 14, 2011 24 http://relishapp.com/rspec
  • 25.
    Cucumber # language: en Feature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two numbers Scenario Outline: Add two numbers Given I have entered <input_1> into the calculator And I have entered <input_2> into the calculator When I press <button> Then the result should be <output> on the screen Examples: | input_1 | input_2 | button | output | | 20 | 30 | add | 50 | | 2 | 5 | add | 7 | | 0 | 40 | add | 40 | Tuesday, June 14, 2011 25 http://cukes.info https://github.com/cucumber/cucumber/blob/master/examples/i18n/en/features/ addition.feature
  • 26.
    IDE • RubyMine • NetBeans (separate Ruby plugin for 7.0) • Eclipse Tuesday, June 14, 2011 26
  • 27.
    Other stuff • Ant integration • warbler (generate WAR files) • Ruboto (JRuby on Android) Tuesday, June 14, 2011 27
  • 28.
    Sponsored plug • JRuby on Rails hosting now available on Engine Yard's AppCloud Tuesday, June 14, 2011 28
  • 29.
    JRubyConf 2011 Washington, DC August 3-5 http://jrubyconf.com Tuesday, June 14, 2011 29
  • 30.
    Thank you! @hiro_asari hasari@engineyard.com asari.ruby@gmail.com http://github.com/banzaiman Tuesday, June 14, 2011 30
  • 31.
  • 32.