What's new,what's cool by ChrisCaflish

VIEWS: 7 PAGES: 256

									          JRuby
What’s new, what’s cool?
             Ola Bini
      JRuby Core Developer
         ThoughtWorks
Vanity slide
 Ola Bini
 From Stockholm, Sweden
 Programming language nerd (Lisp, Ruby, Java, Smalltalk, Io,
 Erlang, ML, C/C++/C#, etc)
 Java +10 years
 Ruby +4 years
 JRuby +2 years
 Author of Practical JRuby on Rails (APress)
Agenda
 What is JRuby
 How to get started
 The implementation
 Cool things
 Some Rails
 Q&A
  DEMO
Java vs. Ruby
Why Ruby instead of Java?
Why Ruby instead of Java?
 Language verbosity
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
    Support for writing domain specific languages
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
    Support for writing domain specific languages

 Sources of innovation
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
    Support for writing domain specific languages

 Sources of innovation
    Rails
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
    Support for writing domain specific languages

 Sources of innovation
    Rails
    Testing
Why Ruby instead of Java?
 Language verbosity
 Malleability of language
    Agile way of working
    Quick turnaround
    Support for writing domain specific languages

 Sources of innovation
    Rails
    Testing

 Language power
What is JRuby
What is JRuby
 Implementation of the Ruby language
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
 Open source
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
 Open source
 “It’s just Ruby”
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
 Open source
 “It’s just Ruby”
 Compatible with Ruby 1.8.6
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
 Open source
 “It’s just Ruby”
 Compatible with Ruby 1.8.6
 JRuby 1.0.3 and 1.1 current releases
What is JRuby
 Implementation of the Ruby language
 Java 1.5+ (1.4 for JRuby 1.0)
 Open source
 “It’s just Ruby”
 Compatible with Ruby 1.8.6
 JRuby 1.0.3 and 1.1 current releases
    1.0-branch rapidly falling behind
Community
Community
 Project started in 2001
Community
 Project started in 2001
 Lots of different developers during the years
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
 8 Core developers
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
 8 Core developers
 40-50 contributors
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
 8 Core developers
 40-50 contributors
 Outstanding contributions
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
 8 Core developers
 40-50 contributors
 Outstanding contributions
    Like Marcin’s Oniguruma port (12000 lines of C code)
Community
 Project started in 2001
 Lots of different developers during the years
 Currently:
 8 Core developers
 40-50 contributors
 Outstanding contributions
    Like Marcin’s Oniguruma port (12000 lines of C code)
       Joni is probably the fastest Regexp engine for Java right now
Compatibility
Compatibility
 Using Rubinius specs
Compatibility
 Using Rubinius specs
 Applications are king:
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec

 Testing is cool: (~42,000 expectations/assertions)
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec

 Testing is cool: (~42,000 expectations/assertions)
    Prevents regressions
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec

 Testing is cool: (~42,000 expectations/assertions)
    Prevents regressions
    Helps to define Ruby better
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec

 Testing is cool: (~42,000 expectations/assertions)
    Prevents regressions
    Helps to define Ruby better

 Might prevent community fragmenting
Compatibility
 Using Rubinius specs
 Applications are king:
    Rails, RubyGems, Rake, RSpec

 Testing is cool: (~42,000 expectations/assertions)
    Prevents regressions
    Helps to define Ruby better

 Might prevent community fragmenting
    Like Sapphire
Ruby Issues - Threading
Ruby Issues - Threading
 Ruby 1.8: Green threading
   No scaling across processors/cores
   C libraries won’t/can’t yield
   One-size-fits-all scheduler
Ruby Issues - Threading
 Ruby 1.8: Green threading
    No scaling across processors/cores
    C libraries won’t/can’t yield
    One-size-fits-all scheduler

 Ruby 1.9: Native, non-parallel execution
Ruby Issues - Threading
 Ruby 1.8: Green threading
    No scaling across processors/cores
    C libraries won’t/can’t yield
    One-size-fits-all scheduler

 Ruby 1.9: Native, non-parallel execution
 JRuby:
    Ruby threads are Java threads
    World class scheduler with tunable algorithms
Ruby Issues - Unicode
Ruby Issues - Unicode
 Ruby 1.8: Partial Unicode
    Internet connection applications MUST have solid Unicode
    Ruby 1.8 provides very partial support
    App devs roll their own: Rails Multi-byte
Ruby Issues - Unicode
 Ruby 1.8: Partial Unicode
    Internet connection applications MUST have solid Unicode
    Ruby 1.8 provides very partial support
    App devs roll their own: Rails Multi-byte

 Ruby 1.9: Full encoding support
    Drastic changes to interface and implementation
    Performance issues
    Each string can have its own encoding
Ruby Issues - Unicode
 Ruby 1.8: Partial Unicode
    Internet connection applications MUST have solid Unicode
    Ruby 1.8 provides very partial support
    App devs roll their own: Rails Multi-byte

 Ruby 1.9: Full encoding support
    Drastic changes to interface and implementation
    Performance issues
    Each string can have its own encoding

 JRuby: Java Unicode
Ruby Issues - Performance
Ruby Issues - Performance
 Ruby 1.8: Slower than most languages
   1.8 is usually called “fast enough”
   ...but routinely finishes last
   ...and no plans to improve in 1.8
Ruby Issues - Performance
 Ruby 1.8: Slower than most languages
    1.8 is usually called “fast enough”
    ...but routinely finishes last
    ...and no plans to improve in 1.8

 Ruby 1.9: Improvement, but not scalable
    New engine about 1.5x for general appliciations
    Only implicit AOT compilation
    No JIT, no GC or threading changes
Ruby Issues - Performance
 Ruby 1.8: Slower than most languages
    1.8 is usually called “fast enough”
    ...but routinely finishes last
    ...and no plans to improve in 1.8

 Ruby 1.9: Improvement, but not scalable
    New engine about 1.5x for general appliciations
    Only implicit AOT compilation
    No JIT, no GC or threading changes

 JRuby: Compiler provides better performance
Ruby Issues - Memory
Ruby Issues - Memory
 Ruby 1.8: Memory management
   Simple design
   Good for many apps, but not scalable
   Stop-the-world GC
Ruby Issues - Memory
 Ruby 1.8: Memory management
   Simple design
   Good for many apps, but not scalable
   Stop-the-world GC

 Ruby 1.9: No change
   Improved performance => more garbage
   GC problems could multiply
Ruby Issues - Memory
 Ruby 1.8: Memory management
    Simple design
    Good for many apps, but not scalable
    Stop-the-world GC

 Ruby 1.9: No change
    Improved performance => more garbage
    GC problems could multiply

 JRuby: World class Java GC’s
Ruby Issues - C
Ruby Issues - C
 Ruby 1.8 & 1.9: C language extensions
    C is difficult to write well
    Badly-behaved extensions can cause large problems
    Threading and GC issues relating to extensions
    Portable, but often with recompilation
    No security restrictions in the system
Ruby Issues - C
 Ruby 1.8 & 1.9: C language extensions
    C is difficult to write well
    Badly-behaved extensions can cause large problems
    Threading and GC issues relating to extensions
    Portable, but often with recompilation
    No security restrictions in the system

 JRuby
    Java extensions
    GC and threading no problem
Ruby Issues - Politics
Ruby Issues - Politics
 Politics
    “You want me to switch to what?”
    “... and it needs servers/software/training?”
    Potentially better with time (e.g. 1.9)
Ruby Issues - Politics
 Politics
    “You want me to switch to what?”
    “... and it needs servers/software/training?”
    Potentially better with time (e.g. 1.9)

 Legacy
    Lots of Java apps in the world
    Extensive amount of Java frameworks
Ruby Issues - Politics
 Politics
    “You want me to switch to what?”
    “... and it needs servers/software/training?”
    Potentially better with time (e.g. 1.9)

 Legacy
    Lots of Java apps in the world
    Extensive amount of Java frameworks

 JRuby solves both of these by running on top of Java
    “Credibility by association”
C libraries
C libraries
 JRuby can’t support native extensions
    Designed around single-threaded execution
       (i.e. one app, one request per process at a time

    Stability, security problems
    Too permissive Ruby extension API
C libraries
 JRuby can’t support native extensions
    Designed around single-threaded execution
       (i.e. one app, one request per process at a time

    Stability, security problems
    Too permissive Ruby extension API

 But who cares?
    If you want to do it, there’s a Java library
    If no, we support natives access through JNA
    And even porting is not that hard
Getting started
Getting started
 Java installation
Getting started
 Java installation
 Download JRuby binary distro
Getting started
 Java installation
 Download JRuby binary distro
    Includes JRuby, Ruby stdlib, RubyGems and rake
Getting started
 Java installation
 Download JRuby binary distro
    Includes JRuby, Ruby stdlib, RubyGems and rake

 Unpack
Getting started
 Java installation
 Download JRuby binary distro
    Includes JRuby, Ruby stdlib, RubyGems and rake

 Unpack
    Multiple copies on the system is fine
Getting started
 Java installation
 Download JRuby binary distro
    Includes JRuby, Ruby stdlib, RubyGems and rake

 Unpack
    Multiple copies on the system is fine

 Add <jruby-dir>/bin to PATH
Getting started
 Java installation
 Download JRuby binary distro
    Includes JRuby, Ruby stdlib, RubyGems and rake

 Unpack
    Multiple copies on the system is fine

 Add <jruby-dir>/bin to PATH
 Install gems (gem install or jruby -S gem install)
Calling Ruby from Java
 // One-time load Ruby runtime
 ScriptEngineManager factory =
     new ScriptEngineManager();

 ScriptEngine engine =
     factory.getEngineByName("jruby");

 // Evaluate JRuby code from string.
 try {
     engine.eval("puts('Hello')");
 } catch (ScriptException exception) {
     exception.printStackTrace();
 }
    DEMO
Interactive Ruby
Implementation: Lexing, parsing
Implementation: Lexing, parsing
 Hand written lexer
   Originally ported from MRI
   Many changes since then
Implementation: Lexing, parsing
 Hand written lexer
   Originally ported from MRI
   Many changes since then

 LALR parser
   Port of MRI’s YACC/Bison-based parser
Implementation: Lexing, parsing
 Hand written lexer
    Originally ported from MRI
    Many changes since then

 LALR parser
    Port of MRI’s YACC/Bison-based parser

 Abstract Syntax Tree quite similar to MRI
    We’ve made a few changes and additions
Implementation: Core classes
Implementation: Core classes
 Mostly 1:1 core classes map to Java types
    String is RubyString, Array is RubyArray, etc
Implementation: Core classes
 Mostly 1:1 core classes map to Java types
    String is RubyString, Array is RubyArray, etc

 Annotation based method binding
 public @interface JRubyMethod {
     String[] name() default {};
     int required() default 0;
     int optional() default 0;
     boolean rest() default false;
     String[] alias() default {};
     boolean meta() default false;
     boolean module() default false;
     boolean frame() default false;
     boolean scope() default false;
     boolean rite() default false;
     Visibility visibility() default Visibility.PUBLIC;
 }
 ...
 @JRubyMethod(name = "open", required = 1, frame = true)
Implementation: Interpreter
Implementation: Interpreter
 Simple switch based AST walker
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
 Most code start out interpreted
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
 Most code start out interpreted
    Command line scripts compiled immediately
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
 Most code start out interpreted
    Command line scripts compiled immediately
    Precompiled script (.class) instead of .rb
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
 Most code start out interpreted
    Command line scripts compiled immediately
    Precompiled script (.class) instead of .rb
    Eval’ed code is always interpreted (for now)
Implementation: Interpreter
 Simple switch based AST walker
 Recurses for nested structures
 Most code start out interpreted
    Command line scripts compiled immediately
    Precompiled script (.class) instead of .rb
    Eval’ed code is always interpreted (for now)

 Reasonably straight forward code
Implementation: Compilation
Implementation: Compilation
 Full Bytecode compilation
   1.0 had partial JIT compiler (25%)
Implementation: Compilation
 Full Bytecode compilation
   1.0 had partial JIT compiler (25%)

 AST walker emits code structure
Implementation: Compilation
 Full Bytecode compilation
   1.0 had partial JIT compiler (25%)

 AST walker emits code structure
 Bytecode emitter generates Java class + methods
   Real Java bytecode
   AOT mode: 1:1 mapping .rb file to .class file
      Not a “real” Java class, more a bunch of methods

      ... but has a “main” for CLI execution

   JIT mode: 1:1 mapping method to in-memory class
   DEMO
Precompilation
Compiler problems
Compiler problems
 AOT pain
Compiler problems
 AOT pain
   Code bodies as Java methods need method handles
Compiler problems
 AOT pain
   Code bodies as Java methods need method handles
      Generated as adaptor methods
Compiler problems
 AOT pain
   Code bodies as Java methods need method handles
      Generated as adaptor methods

   Ruby is very terse - the compiled output is much more verbose
Compiler problems
 AOT pain
   Code bodies as Java methods need method handles
      Generated as adaptor methods

   Ruby is very terse - the compiled output is much more verbose
   Mapping symbols safely (class, package, method names)
Compiler problems
 AOT pain
    Code bodies as Java methods need method handles
       Generated as adaptor methods

    Ruby is very terse - the compiled output is much more verbose
    Mapping symbols safely (class, package, method names)

 JIT pain
Compiler problems
 AOT pain
    Code bodies as Java methods need method handles
       Generated as adaptor methods

    Ruby is very terse - the compiled output is much more verbose
    Mapping symbols safely (class, package, method names)

 JIT pain
    Method body must live on a class
Compiler problems
 AOT pain
    Code bodies as Java methods need method handles
       Generated as adaptor methods

    Ruby is very terse - the compiled output is much more verbose
    Mapping symbols safely (class, package, method names)

 JIT pain
    Method body must live on a class
       Class must be live in separate classloader to GC
Compiler problems
 AOT pain
    Code bodies as Java methods need method handles
       Generated as adaptor methods

    Ruby is very terse - the compiled output is much more verbose
    Mapping symbols safely (class, package, method names)

 JIT pain
    Method body must live on a class
       Class must be live in separate classloader to GC

       Class name must be unique within that classloader
Compiler optimizations
Compiler optimizations
 Preallocated, cached Ruby literals
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
    Methods and leaf closures
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
    Methods and leaf closures
       leaf == no contained closures
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
    Methods and leaf closures
       leaf == no contained closures

 No eval(), binding(), etc calls present
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
    Methods and leaf closures
       leaf == no contained closures

 No eval(), binding(), etc calls present
 Monomorphic inline method cache
Compiler optimizations
 Preallocated, cached Ruby literals
 Java opcodes for local flow-control where possible
    Explicit local “return” as cheap as implicit
    Explicit local “next”, “break”, etc simple jumps

 Java local variables when possible
    Methods and leaf closures
       leaf == no contained closures

 No eval(), binding(), etc calls present
 Monomorphic inline method cache
    Polymorphic for 1.1 (probably)
Core class implementations
Core class implementations
 String as copy-on-write byte[] impl
Core class implementations
 String as copy-on-write byte[] impl
 Array as copy-on-write Object[] impl
Core class implementations
 String as copy-on-write byte[] impl
 Array as copy-on-write Object[] impl
 Fast-read Hash implementation
Core class implementations
 String as copy-on-write byte[] impl
 Array as copy-on-write Object[] impl
 Fast-read Hash implementation
 Java “New IO” (NIO) based IO implementation
    Example: implementing analogs for libc IO functions
Core class implementations
 String as copy-on-write byte[] impl
 Array as copy-on-write Object[] impl
 Fast-read Hash implementation
 Java “New IO” (NIO) based IO implementation
    Example: implementing analogs for libc IO functions

 Two custom Regexp implementations
    New one works with byte[] directly
Threading
Threading
 JRuby supports only native OS threads
   Much heavier than Ruby's green threads
   But truly parallel, unlike Ruby 1.9 (GIL)
Threading
 JRuby supports only native OS threads
   Much heavier than Ruby's green threads
   But truly parallel, unlike Ruby 1.9 (GIL)

 Emulates unsafe green operations
   Thread#kill, Thread#raise inherently unsafe
   Thread#critical impossible to guarantee
   All emulated with checkpoints (pain...)
Threading
 JRuby supports only native OS threads
   Much heavier than Ruby's green threads
   But truly parallel, unlike Ruby 1.9 (GIL)

 Emulates unsafe green operations
   Thread#kill, Thread#raise inherently unsafe
   Thread#critical impossible to guarantee
   All emulated with checkpoints (pain...)

 Pooling of OS threads minimizes spinup cost
POSIX
POSIX
 Normal Ruby native extensions not supported
POSIX
 Normal Ruby native extensions not supported
   Maybe in future, but Ruby API exposes too much
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
    Programmatically load libs, call functions
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
    Programmatically load libs, call functions
    Similar to DL in Ruby
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
    Programmatically load libs, call functions
    Similar to DL in Ruby
    Could easily be used for porting extensions
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
    Programmatically load libs, call functions
    Similar to DL in Ruby
    Could easily be used for porting extensions

 JNA used for POSIX functions not in Java
POSIX
 Normal Ruby native extensions not supported
    Maybe in future, but Ruby API exposes too much

 Native libraries accessible with JNA
    Not JNI...JNA = Java Native Access
    Programmatically load libs, call functions
    Similar to DL in Ruby
    Could easily be used for porting extensions

 JNA used for POSIX functions not in Java
    Filesystem support (symlinks, stat, chmod, chown, ...)
Java Integration
Java Integration
 Java types are presented as Ruby types
    Construct instances, call methods, pass objects around
    camelCase or under_score_case both work
    Most Ruby-calling-Java code looks just like Ruby
Java Integration
 Java types are presented as Ruby types
    Construct instances, call methods, pass objects around
    camelCase or under_score_case both work
    Most Ruby-calling-Java code looks just like Ruby

 Integration with Java type hierarchy
    Implement Java interfaces
       longhand “include SomeInterface”
Java Integration
 Java types are presented as Ruby types
    Construct instances, call methods, pass objects around
    camelCase or under_score_case both work
    Most Ruby-calling-Java code looks just like Ruby

 Integration with Java type hierarchy
    Implement Java interfaces
       longhand “include SomeInterface”

 shorthand “SomeInterface.impl { ... }”
Java Integration
 Java types are presented as Ruby types
    Construct instances, call methods, pass objects around
    camelCase or under_score_case both work
    Most Ruby-calling-Java code looks just like Ruby

 Integration with Java type hierarchy
    Implement Java interfaces
       longhand “include SomeInterface”

 shorthand “SomeInterface.impl { ... }”
 closure conversion “add_action_listener { ... }”
Java Integration
 Java types are presented as Ruby types
    Construct instances, call methods, pass objects around
    camelCase or under_score_case both work
    Most Ruby-calling-Java code looks just like Ruby

 Integration with Java type hierarchy
    Implement Java interfaces
       longhand “include SomeInterface”

 shorthand “SomeInterface.impl { ... }”
 closure conversion “add_action_listener { ... }”
 Extend Java concrete and abstract Java types
Performance
Performance
 No, it's not all that important
Performance
 No, it's not all that important
    Until it is!
Performance
 No, it's not all that important
    Until it is!

 JRuby 1.0 was about 2x slower than Ruby 1.8.6
Performance
 No, it's not all that important
    Until it is!

 JRuby 1.0 was about 2x slower than Ruby 1.8.6
 JRuby 1.1 Beta 1 was about 2x faster
Performance
 No, it's not all that important
    Until it is!

 JRuby 1.0 was about 2x slower than Ruby 1.8.6
 JRuby 1.1 Beta 1 was about 2x faster
 JRuby trunk is 5x faster, often faster than 1.9
Performance
 No, it's not all that important
    Until it is!

 JRuby 1.0 was about 2x slower than Ruby 1.8.6
 JRuby 1.1 Beta 1 was about 2x faster
 JRuby trunk is 5x faster, often faster than 1.9
    As a result, we've stopped working on perf for now
Performance
 No, it's not all that important
    Until it is!

 JRuby 1.0 was about 2x slower than Ruby 1.8.6
 JRuby 1.1 Beta 1 was about 2x faster
 JRuby trunk is 5x faster, often faster than 1.9
    As a result, we've stopped working on perf for now
    ...but targeting Java performance next
  DEMO
Benchmarks
JRuby Internals
 JRuby::ast_for(“1+1”) #-> Java AST

 JRuby::ast_for { 1+1 } #-> Java AST

 JRuby::compile(“1+1”) #-> CompiledScript

 CompiledScript.inspect_bytecode

 JRuby::runtime

 JRuby::reference(“str”)
... evil stuff
  a = “foobar”
  a.freeze
  JRuby::reference(a).setFrozen(false)


  class Foobar; end
  something = Object.new
  JRuby::reference(something).setMetaClass(Foobar)


  class Foobar; end
  JRuby::reference(Foobar).getMethods()
Swing GUI programming
Swing GUI programming
 Swing API is very large and complex
Swing GUI programming
 Swing API is very large and complex
    Ruby magic simplifies most of the tricky bits
Swing GUI programming
 Swing API is very large and complex
    Ruby magic simplifies most of the tricky bits

 Java is a very verbose language
Swing GUI programming
 Swing API is very large and complex
    Ruby magic simplifies most of the tricky bits

 Java is a very verbose language
    Ruby makes Swing fun (more fun at least)
Swing GUI programming
 Swing API is very large and complex
    Ruby magic simplifies most of the tricky bits

 Java is a very verbose language
    Ruby makes Swing fun (more fun at least)

 No consistent cross-platform GUI library for Ruby
Swing GUI programming
 Swing API is very large and complex
    Ruby magic simplifies most of the tricky bits

 Java is a very verbose language
    Ruby makes Swing fun (more fun at least)

 No consistent cross-platform GUI library for Ruby
    Swing works everywhere Java does
Swing - direct approach
import javax.swing.JFrame
import javax.swing.JButton

frame = JFrame.new("Swing is easy now!")
frame.set_size 300, 300
frame.always_on_top = true

button = JButton.new("Press me!")
button.add_action_listener do |evt|
  evt.source.text = "Don't press me again!"
  evt.source.enabled = false
end

frame.add(button)
frame.show
Swing - Cheri (builder)
include Cheri::Swing

frame = swing.frame("Swing builders!") { |form|
  size 300, 300
  box_layout form, :Y_AXIS
  content_pane { background :WHITE }

    button("Event binding is nice") { |btn|
      on_click { btn.text = "You clicked me!" }
    }
}

frame.visible = true
Swing - Profligacy
class ProfligacyDemo
  import javax.swing.*
  include Profligacy

 def initialize
   layout = "[<translate][*input][>result]"
   @ui = Swing::LEL.new(JFrame, layout) {|cmps, ints|
     cmps.translate = JButton.new("Translate")
     cmps.input = JTextField.new
     cmps.result = JLabel.new

        translator = proc {|id, evt|
          original = @ui.input.text
          translation = MyTranslator.translate(original)
          @ui.result.text = translation
        }

        ints.translate = {:action => translator}
    }
  end
end
Swing - MonkeyBars (tools)
 GUI editor friendly (e.g. NetBeans “Matisse”)
 Simple Ruby MVC based API
 Combines best of both worlds
Why JRuby on Rails
Why JRuby on Rails
 JDBC for database access
Why JRuby on Rails
 JDBC for database access
 Deployment to any Java application server
Why JRuby on Rails
 JDBC for database access
 Deployment to any Java application server
 Use any Java libraries
    XML, JMX, JCE, EJB, FUD, etc
Why JRuby on Rails
 JDBC for database access
 Deployment to any Java application server
 Use any Java libraries
    XML, JMX, JCE, EJB, FUD, etc

 Integrate with existing infrastructure
    Existing libraries
    Backend services and legacy integration
Why JRuby on Rails
 JDBC for database access
 Deployment to any Java application server
 Use any Java libraries
    XML, JMX, JCE, EJB, FUD, etc

 Integrate with existing infrastructure
    Existing libraries
    Backend services and legacy integration

 Performance
   DEMO
JRuby on Rails
Real world JRuby
Real world JRuby
 mix.oracle.com
   Idea sharing, networking, Q/A
   Production staff wouldn’t run MRI
   Runs on full Oracle stack
Real world JRuby
 mix.oracle.com
   Idea sharing, networking, Q/A
   Production staff wouldn’t run MRI
   Runs on full Oracle stack

 mediacast.sun.com
   Media/marketing distribution channel
Real world JRuby
 mix.oracle.com
   Idea sharing, networking, Q/A
   Production staff wouldn’t run MRI
   Runs on full Oracle stack

 mediacast.sun.com
   Media/marketing distribution channel

 ThoughtWorks Mingle
Real world JRuby
 mix.oracle.com
    Idea sharing, networking, Q/A
    Production staff wouldn’t run MRI
    Runs on full Oracle stack

 mediacast.sun.com
    Media/marketing distribution channel

 ThoughtWorks Mingle
 Sonar - code/project analysis tool
Real world JRuby
 mix.oracle.com
    Idea sharing, networking, Q/A
    Production staff wouldn’t run MRI
    Runs on full Oracle stack

 mediacast.sun.com
    Media/marketing distribution channel

 ThoughtWorks Mingle
 Sonar - code/project analysis tool
 Medienservice - Saxon Government press releases
Deployment - Mongrel
Deployment - Mongrel
 Mongrel as server process
Deployment - Mongrel
 Mongrel as server process
   Times number of apps
Deployment - Mongrel
 Mongrel as server process
   Times number of apps
      Times number of concurrent requests
Deployment - Mongrel
 Mongrel as server process
   Times number of apps
      Times number of concurrent requests

         With monitoring to keep it alive
Deployment - Mongrel
 Mongrel as server process
   Times number of apps
      Times number of concurrent requests

         With monitoring to keep it alive

             Hopefully no zombies or memory leaks
Deployment - Mongrel
 Mongrel as server process
    Times number of apps
       Times number of concurrent requests

          With monitoring to keep it alive

              Hopefully no zombies or memory leaks

 Sure, it works
Deployment - Mongrel
 Mongrel as server process
    Times number of apps
       Times number of concurrent requests

          With monitoring to keep it alive

               Hopefully no zombies or memory leaks

 Sure, it works
    But why?
Deployment - Mongrel
 Mongrel as server process
    Times number of apps
       Times number of concurrent requests

          With monitoring to keep it alive

               Hopefully no zombies or memory leaks

 Sure, it works
    But why?
    The problems have already been solved
Deployment - Java Web server
Deployment - Java Web server
 Package your Rails application in a WAR file
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
 App server deployment:
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
 App server deployment:
    N apps
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
 App server deployment:
    N apps
    N’ concurrent requests
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
 App server deployment:
    N apps
    N’ concurrent requests
    N’’ database connections
Deployment - Java Web server
 Package your Rails application in a WAR file
 Self sustained archive
 Served using a Rails servlet
 App server deployment:
    N apps
    N’ concurrent requests
    N’’ database connections
    1 process, to limits of machine
Deployment - Back to basics
Deployment - Back to basics
 Both worlds
Deployment - Back to basics
 Both worlds
   Production scale application server
Deployment - Back to basics
 Both worlds
   Production scale application server
   Simplicity: one-shot execution, both production and dev
Deployment - Back to basics
 Both worlds
   Production scale application server
   Simplicity: one-shot execution, both production and dev
   Scaling: single process
Deployment - Back to basics
 Both worlds
   Production scale application server
   Simplicity: one-shot execution, both production and dev
   Scaling: single process
   Agile: CLI support, dev time server, no build/deploy
Deployment - Back to basics
 Both worlds
   Production scale application server
   Simplicity: one-shot execution, both production and dev
   Scaling: single process
   Agile: CLI support, dev time server, no build/deploy
   Ruby friendly: “gem install” and run
DEMO
Glassfish
ActiveHibernate
 # define a model (or you can use existing)
 class Project
   include Hibernate
   with_table_name "PROJECTS" #optional
   #column name is optional
   primary_key_accessor :id, :long, :PROJECT_ID
   hattr_accessor :name, :string
   hattr_accessor :complexity, :double
 end

 # connect
 ActiveHibernate.establish_connection(DB_CONFIG)

 # create
 project = Project.new(:name => "JRuby", :complexity => 10)
 project.save
 project_id = project.id

 # query
 all_projects = Project.find(:all)
 jruby_project = Project.find(project_id)

 # update
 jruby_project.complexity = 37
 jruby_project.save
Rubiq
Rubiq
 Lisp layer on top of JRuby
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
 ... and lets JRuby execute it
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
 ... and lets JRuby execute it
    Macros
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
 ... and lets JRuby execute it
    Macros
    Read macros (used to implement regexp syntax, for
    example)
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
 ... and lets JRuby execute it
    Macros
    Read macros (used to implement regexp syntax, for
    example)
    Pure lexical scoping
Rubiq
 Lisp layer on top of JRuby
 Transforms to JRuby AST
 ... and lets JRuby execute it
    Macros
    Read macros (used to implement regexp syntax, for
    example)
    Pure lexical scoping
    Lambdas transparently transforms to blocks or Proc.new
Ruvlets
Ruvlets
 Expose Servlets as Ruby API
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
   Similar in L&F to Camping
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
   Similar in L&F to Camping

 How it works:
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
   Similar in L&F to Camping

 How it works:
   Evaluates file from load path based on URL
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
   Similar in L&F to Camping

 How it works:
   Evaluates file from load path based on URL
   File returns an object with a 'service' method defined
Ruvlets
 Expose Servlets as Ruby API
   Because we can!
   People keep asking for this....really!
   Expose highly tuned web-infrastructure to Ruby
   Similar in L&F to Camping

 How it works:
   Evaluates file from load path based on URL
   File returns an object with a 'service' method defined
   Object cached for all future requests
Bare bones Ruvlet
 class HelloWorld
   def service(context, request, response)
     response.content_type = "text/html"
     response.writer << <<-EOF
       <html>
         <head><title>Hello World!</title></head>
         <body>Hello World!</body>
       </html>
     EOF
   end
 end

 HelloWorld.new
YARV & Rubinius machine
YARV & Rubinius machine
 YARV
   2.0 Compatibility
   Simple machine
   Simple compiler
   Might give interpreted performance improvement
YARV & Rubinius machine
 YARV
   2.0 Compatibility
   Simple machine
   Simple compiler
   Might give interpreted performance improvement

 Rubinius
   Simple machine
   Quite outdated at the moment
   Why do it? Why not?
JtestR
JtestR
 Test Java code with Ruby
JtestR
 Test Java code with Ruby
 Glues JRuby together with state of the art Ruby libraries
JtestR
 Test Java code with Ruby
 Glues JRuby together with state of the art Ruby libraries
 Includes RSpec, Test::Unit, dust, Mocha, etc
JtestR
 Test Java code with Ruby
 Glues JRuby together with state of the art Ruby libraries
 Includes RSpec, Test::Unit, dust, Mocha, etc
 Ant and Maven 2 integration
JtestR
 Test Java code with Ruby
 Glues JRuby together with state of the art Ruby libraries
 Includes RSpec, Test::Unit, dust, Mocha, etc
 Ant and Maven 2 integration
 0.2 to be released “any time now” (tm)
     DEMO
Testing Java with
      Ruby
JSR292, JLR & DaVinci
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
    Interface injection
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
    Interface injection
    Continuations
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
    Interface injection
    Continuations
    Value objects (Lisp fixnums)
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
    Interface injection
    Continuations
    Value objects (Lisp fixnums)
    Tuple types
JSR292, JLR & DaVinci
 Dynamic invocation: non-java call sites
 Method handles
 Anonymous classes
 Faster reflection, escape analysis
    Interface injection
    Continuations
    Value objects (Lisp fixnums)
    Tuple types
    Tail calls
ThoughtWorks Sweden?
 It might happen!
 It might happen this year!
 But not 100%. Not even 70% actually. =)
Resources
Resources
 ruby-lang.org
Resources
 ruby-lang.org
 rubyonrails.org
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
 #jruby at irc.freenode.net
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
 #jruby at irc.freenode.net
 dev@jruby.codehaus.org
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
 #jruby at irc.freenode.net
 dev@jruby.codehaus.org
 user@jruby.codehaus.org
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
 #jruby at irc.freenode.net
 dev@jruby.codehaus.org
 user@jruby.codehaus.org
 headius.blogspot.com
Resources
 ruby-lang.org
 rubyonrails.org
 jruby.org
 #jruby at irc.freenode.net
 dev@jruby.codehaus.org
 user@jruby.codehaus.org
 headius.blogspot.com
 ola-bini.blogspot.com
Q&A

								
To top