Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: JRuby 1.6.7
-
Fix Version/s: None
-
Component/s: Ruby 1.8.7
-
Labels:None
-
Environment:HideWindows xp 32 bit
Ruby version 1.8.7 (java)
RubyGems version 1.8.24
Rack version 1.4
Rails version 3.2.5
JavaScript Runtime therubyrhino (Rhino)
Active Record version 3.2.5
Action Pack version 3.2.5
Active Resource version 3.2.5
Action Mailer version 3.2.5
Active Support version 3.2.5
Middleware
ActionDispatch::Static
Rack::Lock
#<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0xa205d1>
Rack::Runtime
Rack::MethodOverride
ActionDispatch::RequestId
Rails::Rack::Logger
ActionDispatch::ShowExceptions
ActionDispatch::DebugExceptions
ActionDispatch::RemoteIp
ActionDispatch::Reloader
ActionDispatch::Callbacks
ActiveRecord::ConnectionAdapters::ConnectionManagement
ActiveRecord::QueryCache
ActionDispatch::Cookies
ActionDispatch::Session::CookieStore
ActionDispatch::Flash
ActionDispatch::ParamsParser
ActionDispatch::Head
Rack::ConditionalGet
Rack::ETag
ActionDispatch::BestStandardsSupport
Application root C:/temp/gem_in_jar/gem_in_jar
Environment development
Database adapter sqlite3
Database schema versionShowWindows xp 32 bit Ruby version 1.8.7 (java) RubyGems version 1.8.24 Rack version 1.4 Rails version 3.2.5 JavaScript Runtime therubyrhino (Rhino) Active Record version 3.2.5 Action Pack version 3.2.5 Active Resource version 3.2.5 Action Mailer version 3.2.5 Active Support version 3.2.5 Middleware ActionDispatch::Static Rack::Lock #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0xa205d1> Rack::Runtime Rack::MethodOverride ActionDispatch::RequestId Rails::Rack::Logger ActionDispatch::ShowExceptions ActionDispatch::DebugExceptions ActionDispatch::RemoteIp ActionDispatch::Reloader ActionDispatch::Callbacks ActiveRecord::ConnectionAdapters::ConnectionManagement ActiveRecord::QueryCache ActionDispatch::Cookies ActionDispatch::Session::CookieStore ActionDispatch::Flash ActionDispatch::ParamsParser ActionDispatch::Head Rack::ConditionalGet Rack::ETag ActionDispatch::BestStandardsSupport Application root C:/temp/gem_in_jar/gem_in_jar Environment development Database adapter sqlite3 Database schema version
-
Number of attachments :
Description
gem_in_a_jar, as found here:
http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar/
cannot be used in rails unless the gems are specified in bundler's Gemfile, this might make no sense but it will...
For this example we will arbitrarily use the time-warp gem
C:\temp\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar -S gem install -i ./time_warp time-warp Fetching: time-warp-1.0.13.gem (100%) Successfully installed time-warp-1.0.13 1 gem installed C:\temp\gem_in_jar>jar cf tw-gem.jar -C time_warp . C:\temp\gem_in_jar>ls | grep tw tw-gem.jar
Now we have our 'Gem in a jar' via tw-gem.jar.
Consider the following script (tw-test.rb):
require 'java' require 'tw-gem.jar' require 'rubygems' require "time_warp" puts "success!"
We will launch this script via tw_test_backtick.rb:
puts "hi" result = `java -jar c:\\languages\\jruby-1.6.7.2\\lib\\jruby-complete-1.6.7.2.jar ./tw_test.rb 2>&1` puts result
Here is the result:
C:\temp\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar tw_test_backtick.rb hi success!
So our gem in a jar worked!
Now let us put this code into a rails app:
C:\temp\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar -S rails new gem_in_jar
create
create README.rdoc
create Rakefile
etc...
In rails root we will place tw-gem.jar and tw-test.rb, and then in RAILS_ROOT/config/initializers we create runbackticks.rb as follows:
begin puts "hi" result = `java -jar c:\\languages\\jruby-1.6.7.2\\lib\\jruby-complete-1.6.7.2.jar ./tw_test.rb 2>&1` puts result end
Next we start up WEBrick:
C:\temp\gem_in_jar\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar -S ./script/rails server -e development -p 3000 => Booting WEBrick => Rails 3.2.5 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server hi LoadError: no such file to load -- time_warp require at org/jruby/RubyKernel.java:1033 (root) at ./tw_test.rb:4 [2012-07-03 13:36:03] INFO WEBrick 1.3.1 [2012-07-03 13:36:03] INFO ruby 1.8.7 (2012-05-01) [java] [2012-07-03 13:36:03] INFO WEBrick::HTTPServer#start: pid=4368 port=3000
In rails it fails to find the appropriate 'gem in a jar' even though it is invoked via back ticks (remember the 'gem in a jar' is in rails root)!
The only (awful) fix I can find is to modify the 'Gemfile' and add the line " gem 'time-warp'" then run bundler's install as follows:
C:\temp\gem_in_jar\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar -S bundle install Fetching gem metadata from https://rubygems.org/......... .... Installing time-warp (1.0.13)
Now it works:
C:\temp\gem_in_jar\gem_in_jar>java -jar c:\languages\jruby-1.6.7.2\lib\jruby-complete-1.6.7.2.jar -S ./script/rails server -e development -p 3000 => Booting WEBrick => Rails 3.2.5 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server hi success!
But it does not really work as I can make tw-gem.jar be of size zero, so it never really uses the jar.
In a nutshell I have no way to separate the dependencies of my jobs from those of my rails app which runs the jobs.
BTW if, in tw_test.rb, I change the require 'tw_gem.jar' to tw_gem2.jar it does complain about not finding the jar (from the rails app) so I know it is finding the jar.
just my random thoughts . . .
as far understand bundler it does a good job to keep forked processes inside the same "load path" as the originating process. so that all the commandline tools which like to fork work nicely with bundler. that is why your awful fix works.
you probably can load your gems_in_a_jar.jar with a new classloader which parent is the system-classloader and load a ruby-time from that new classloader and execute your script with it. that classloader is separated from the rails classloader. the way I do it is calling org.jruby.Main.main("-e", "puts 'hello'") - be aware that you use the Main class from the right classloader since you have it twice !!