The document discusses using JRuby to leverage Java libraries and the JVM while still programming in Ruby. Some key points made include:
- Most developers are familiar with Java and its libraries, and JRuby allows using these from Ruby
- JRuby provides features like real threads and a functioning garbage collector that vanilla Ruby lacks
- It leverages the performance benefits of the JVM like just-in-time compilation while maintaining Ruby's simplicity
- Examples show how to easily interface with Java libraries for things like RabbitMQ and use Java concepts like threads from Ruby
6. TL;DR
Most of you are Java developers
Writing Java is tedious
There’s truckloads of great Java libraries
The JVM is awesome
Ruby is awesome
∴ JRuby FTW
måndag 19 mars 12
7. just
I’M NOT HERE TO
MAKE FUN OF JAVA
måndag 19 mars 12
8. JRuby vs. vanilla Ruby
Real threads
A working GC
Every Java, Scala and Ruby library ever made
All the JVM awesomeness, JIT, the lot
måndag 19 mars 12
9. JRuby vs. Java
It doesn’t make you want to stab yourself
måndag 19 mars 12
15. JRuby ♥ Java
class Worker < Thread
def run
puts 'Hard work, no play'
end
end
# or
class Worker
include Runnable
def run
puts 'Hard work, no play'
end
end
måndag 19 mars 12
16. JRuby ♥ Java
pool = Executors.new_fixed_thread_pool(3)
memes = LinkedBlockingQueue.new
10.times do
pool.submit do
open('http://api.autome.me/text').read.each_line do |meme|
memes << meme
end
end
end
pool.shutdown
pool.await_termination(3, TimeUnit::DAYS)
memes.each { |m| puts(m) }
måndag 19 mars 12
17. JRUBY FOR
REPRESSED JAVA
DEVELOPERS
måndag 19 mars 12
18. Made up fact
84% of Java devs don’t write tests because it’s
way too much extra code to type.
måndag 19 mars 12
19. Testing
public class Person {
public final String firstName;
public final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFullName() {
return String.format("%s %s", firstName, lastName);
}
// omg I’m already bored
}
måndag 19 mars 12
20. Testing
class TestPerson < Test::Unit::TestCase
def setup
@person = Person.new('James', 'Gosling')
end
def test_full_name
assert_equal('James Gosling', @person.full_name)
end
end
# this is TestUnit, it’s part of the stdlib
måndag 19 mars 12
21. Testing
describe Person do
describe '#full_name' do
before do
@person = Person.new('James', 'Gosling')
end
it 'is the first name and the last name with a space in-between' do
@person.full_name.should == 'James Gosling'
end
end
end
# this is RSpec, read more at rspec.info
måndag 19 mars 12
22. Made up fact
Ant was designed by the same people who
came up with the QWERTY layout.
måndag 19 mars 12
23. Automation
<?xml version="1.0"?>
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init" description="compile the source ">
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile" description="generate the distribution">
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- And don’t get me started on Maven, $%&@*! -->
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
måndag 19 mars 12
24. Automation
require 'ant'
src_dir = 'src'
build_dir = 'build'
dist_dir = 'dist'
timestamp = Time.now
task :init do
mkdir_p build_dir
end
task :compile => :init do
ant.javac :srcdir => src_dir, :destdir => build_dir
end
task :dist => :compile do
mkdir_p "#{dist_dir}/lib"
ant.jar :jarfile => "#{dist_dir}/lib/MyProject-#{timestamp}.jar",
:basedir => build_dir
end
task :clean do
rm_rf build_dir
rm_rf dist_dir
måndag 19 mars 12
25. Made up fact
The average number of lines in a Java web
application is somewhere around 100 000
måndag 19 mars 12
26. Don’t make it so hard
get '/' do
erb :index
end
post '/register' do
stuff.save(params[:name], params[:email], params[:shoe_size])
redirect '/thanks'
end
get '/thanks' do
@name = params[:name]
erb :thanks
end
# this is Sinatra, read more at sinatrarb.com
måndag 19 mars 12
27. Pack it up in a
WAR and ship it
$ warbler war
# warbler can be found at github.com/jruby/warbler
# also check out torquebox.org, and github.com/trinidad/trinidad
måndag 19 mars 12
28. Make a console
$ hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.90.4-cdh3u2, r, Thu Oct 13 20:32:26 PDT 2011
hbase(main):001:0> create 'test', 'cf'
0 row(s) in 1.2200 seconds
hbase(main):002:0> put 'test', 'row1', 'cf:a', 'value1'
0 row(s) in 0.0560 seconds
hbase(main):003:0> put 'test', 'row2', 'cf:b', 'value2'
0 row(s) in 0.0370 seconds
måndag 19 mars 12
29. Monitoring
require 'jmx'
client = JMX.connect(:port => 7199)
storage_service = client['org.apache.cassandra.db:type=StorageService']
storage_service.keyspaces.each do |keyspace|
puts keyspace
end
memory_mbean = client['java.lang:type=Memory']
puts memory_mbean.heap_memory_usage.used
memory_mbean.gc
måndag 19 mars 12
40. Our stack: Akka
Scala is nice, but we’ve got better things to do
than to wait for code to compile
Akka is awesome, so we created Mikka
github.com/iconara/mikka
måndag 19 mars 12
41. Our stack: Akka
class Ping < Mikka::Actor
def pre_start
@pong = context.actor_of(Pong)
@pong << :ping
end
def receive(message)
context.reply(:ping)
end
end
class Pong < Mikka::Actor
def receive(message)
context.reply(:pong)
end
end
ping = Mikka.actor_of(Ping).start
måndag 19 mars 12
42. Our stack: numbers
We process hundreds of millions of messages
per day, using less than 20K lines of JRuby
måndag 19 mars 12
43. twitter.com/iconara
architecturalatrocities.com
burtcorp.com
måndag 19 mars 12