Ahead-of-time compiling JRuby, packaging a Java Jar, creating a Gemspec, using Warbler
In this blog post I’ll share some code to demonstrate ahead-of-time compiling and packaging JRuby code into a standalone Java Jar. This functionality is nice if you develop locally via RVM, and want to deploy to a JVM server.
Created file:.ruby-version
jruby-1.7.4
Created file: .ruby-gemset
jruby_jar
Created file: Gemfile
source 'https://rubygems.org'
#gem 'warbler'
# ^ LoadError: no such file to load -- zip/zip:
gem 'warbler', :git => 'git://github.com/jruby/warbler.git'
Executed bundle to install required gems
$ bundle
Created main module, file: lib/jruby-jar-example.rb
require 'jruby-jar-example/some_class'
module JRubyJarExample
#PATH = File.expand_path(File.dirname(__FILE__))
extend self
def my_var
@my_var ||= get_my_var
end
def my_class_var
@my_class_var ||= get_my_class_var
end
private
def get_my_var
'JRubyJarExample var'
end
def get_my_class_var
SomeClass.my_var
end
end
Created sample class, file: lib/jruby-jar-example/some_class.rb
module JRubyJarExample
class SomeClass
def self.my_var
@my_var ||= get_my_var
end
class << self
private
def get_my_var
'JRubyJarExample::SomeClass var'
end
end
end
end
Created main bin file, file: bin/jruby-jar-example-main.rb. This file will be the main bin file that drives the Jar execution.
#!/usr/bin/env jruby
# include rubygems
require 'rubygems'
# load main module conditionally
require "#{File.expand_path(File.dirname(__FILE__))}/../lib/jruby-jar-example" unless Module.const_defined? 'JRubyJarExample'
# do stuff here
puts JRubyJarExample.my_var
puts JRubyJarExample.my_class_var
Created a gemspec file, file: jruby-jar-example.gemspec
Gem::Specification.new do |s|
s.name = 'jruby-jar-example'
s.version = '1.0.0'
s.authors = ['Eric London']
s.date = '2013-10-01'
s.description = 'JRuby Jar Example'
s.email = ['ericlondon@example.com']
s.homepage = 'http://ericlondon.com'
s.require_paths = ['lib','bin']
s.rubygems_version = '1.8.24'
s.summary = 'JRuby Jar Example'
s.files = Dir.glob("{bin,lib}/**/*")
#s.licenses = ['MIT']
s.executables = ['jruby-jar-example-main.rb']
end
[Optional] Now that the gemspec defines the project, it can be built and tested via IRB:
$ gem build jruby-jar-example.gemspec
$ gem install ./jruby-jar-example-1.0.0.gem
$ gem list
*** LOCAL GEMS ***
bundler (1.3.5)
jruby-jar-example (1.0.0)
jruby-jars (1.7.4)
jruby-rack (1.1.13.2)
rake (10.1.0)
rubyzip (1.0.0, 0.9.9)
warbler (1.3.8)
$ irb
jruby-1.7.4 :001 > require 'jruby-jar-example'
=> true
jruby-1.7.4 :002 > JRubyJarExample.my_var
=> "JRubyJarExample var"
jruby-1.7.4 :003 > JRubyJarExample.my_class_var
=> "JRubyJarExample::SomeClass var"
Warbler will use a gemspec if it exists. If you didn’t create one, or need to modify additional settings, you can execute “warble config” to generate a config/warble.rb file to override project settings.
At this point the code can be compiled and packaged into a Java jar using warble:
$ warble compiled jar
rm -f jruby_jar.jar
Creating jruby_jar.jar
rm -f bin/jruby-jar-example-main.class lib/jruby-jar-example.class lib/jruby-jar-example/some_class.class
Your Jar can now be executed or deployed to a JVM:
$ java -jar jruby_jar.jar
JRubyJarExample var
JRubyJarExample::SomeClass var