This is what I'm using to extract a rails app in a jar to ~/.jruby
require 'java'
require 'fileutils'
require 'rbconfig'
ZipFile = java.util.zip.ZipFile
ZipEntry = java.util.zip.ZipEntry
# extract from jar to jruby.home/.
class ExtractFromJar
attr_reader :path_to_jarfile, :name, :destination, :zip
def initialize(path_to_jarfile, dir = nil)
@path_to_jarfile = path_to_jarfile
@name = @path_to_jarfile.split(File::SEPARATOR).last[/(.*)\.(jar$)/, 1]
@destination = dir || File.join(Config::CONFIG['prefix'], @name)
if need_extract?
raise "error: can't locate enclosed archive from #{__FILE__}" if @path_to_jarfile.nil?
@zip = ZipFile.new(java.net.URLDecoder.decode(@path_to_jarfile, "utf-8"))
end
end
def need_extract?
!File.directory?(@destination) || (File.stat(@path_to_jarfile).mtime > File.stat(@destination).mtime)
end
def entries
enum = @zip.entries
def enum.each
while hasMoreElements
yield nextElement
end
end
enum
end
def extract
return nil unless need_extract?
entries.each do |entry|
if entry.directory?
FileUtils.mkdir_p("#{@destination}#{File::SEPARATOR}#{entry.name}")
else
path = write_entry entry, entry.name
end
end
end
def write_entry(entry, name)
entry_path = "#{@destination.sub(%r{/$},'')}#{File::SEPARATOR}#{name}"
puts "creating #{entry_path}"
FileUtils.mkdir_p(File.dirname(entry_path))
instream = @zip.getInputStream(entry)
outstream = java.io.FileOutputStream.new(entry_path)
buffer = java.lang.reflect.Array.newInstance(java.lang.Byte::TYPE, 8192)
while (num_read = instream.read(buffer)) != -1
outstream.write buffer, 0, num_read
end
entry_path
ensure
instream.close if instream
outstream.close if outstream
end
end
class ExtractFromResource < ExtractFromJar
attr_reader :resource_in_jar
def initialize(resource_in_jar, dir = nil)
@resource_in_jar = resource_in_jar
cl = java.lang.Class.forName('org.jruby.Ruby').classLoader
super(cl.find_resource(@resource_in_jar).file[/file:(.*.jar)!\//, 1])
end
end
This is what I'm running in the irb console started from web start
require 'jrubygems'
require 'lib/extract_from_jar.rb'
e = ExtractFromResource.new("blog/config/environment.rb")
e.extract
require "#{e.destination}/blog/config/boot.rb"
require 'commands/server'
# and here's the stack trace now (much further along!)
=> Booting WEBrick...
TypeError: can't convert nil into String
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/webrick.rb:17
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/webrick.rb:17:in `options'
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/webrick.rb:17
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/servers/webrick.rb:17:in `require'
from /Users/stephen/.jruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496:in `new_constants_in'
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:318:in `require'
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:496
from /Users/stephen/.jruby/lib/ruby/gems/1.8/gems/rails-2.0.2/lib/commands/server.rb:38:in `require'
from /Users/stephen/.jruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from (irb):7:in `puts'