Hello,
is it possible to create empty JRuby environment from JRuby program?
I have experimented with several variants of starting scripting
container,
e.g.
module Thick
class Loader
include Thick::Java::ServerRubyInterface
def initialize(options)
@options = options
ENV['RACK_ENV'] ||= ENV['RAILS_ENV'] ||= @options[:environment]
@application = @options[:application] ||= Rack::Builder.parse_file(File.expand_path(@options[:file], @options[:directory]))[0]
end
def call(env)
#noinspection RubyArgCount
env['rack.input'] = Buffer.new(env['rack.input'])
env['rack.errors'] = env['rack.errors'].to_io
status, headers, body = @application.call(env)
return if env['thick.response_bypass']
This file has been truncated. show original
but contants (classes) are surviving among calls
Do you have any idea?
Thanks
–
Marek J.
m: +420 724 255807
e: [email protected]
social: twitter https://twitter.com/#!/marek_jelen |
githubhttps://github.com/marekjelen |
linkedin http://cz.linkedin.com/in/marekjelen |
bloghttp://www.marekjelen.cz/
projects: brug http://www.brug.cz/ |
wildcloudhttps://github.com/wildcloud
| rupy.eu | noderb https://github.com/noderb
Hello,
On Sat, Mar 31, 2012 at 8:38 AM, Marek J. [email protected] wrote:
Hello,
is it possible to create empty JRuby environment from JRuby program?
I have experimented with several variants of starting scripting container,
e.g.
thick/lib/thick/loader.rb at master · marekjelen/thick · GitHub
but contants (classes) are surviving among calls
Sounds like a singleton type container was instantiated.
What class do you get by:
container.getProvider.class
Btw, it’s very interesting way of using ScriptingContainer.
-Yoko
I did something similar a while back – with the purpose of running two
different version of the same Gem in one application.
I tried several different approaches, but here’s basically what I ended
up with:
boot.rb
$LOAD_PATH << $APP_LOAD_PATH #set the load path from the APP_LOAD_PATH binding
if $RACK_ENV == 'production'
ENV['GEM_PATH'] = "#{File.join($RULE_SERVER_HOME, 'vendor/jruby/1.8')}:#{File.join($TORQUEBOX_HOME, 'jruby/lib/ruby/gems/1.8')}"
ENV['GEM_HOME'] = File.join($RULE_SERVER_HOME, 'vendor/jruby/1.8')
else
puts 'Using global GEM_HOME directory.'
end
require 'rubygems'
This file has been truncated. show original
engine.rb
java_import "javax.script.ScriptContext"
java_import "javax.script.ScriptEngine"
java_import "javax.script.ScriptEngineManager"
java_import "javax.script.ScriptException"
java_import "java.io.FileNotFoundException"
java_import "javax.script.Bindings"
java_import "javax.script.SimpleBindings"
java_import "java.io.FileReader"
java_import "java.io.Reader"
This file has been truncated. show original
It’s been so long that I don’t remember much about why I did things the
way I did. But I did not have the problems like you describe.
I did have to watch out for :foo == :foo returning false within the
embedded jruby
That is odd!
I was surprised that you’ve been able to just call “require ‘rack’”
without requiring rubygems or setting up your GEM_PATH inside the new
runtime. One thing I failed to show from my app was a boot.rb, which
was the first thing I ran in the embedded JRuby. It that did all that:
boot.rb
$LOAD_PATH << $APP_LOAD_PATH #set the load path from the APP_LOAD_PATH binding
if $RACK_ENV == 'production'
ENV['GEM_PATH'] = "#{File.join($RULE_SERVER_HOME, 'vendor/jruby/1.8')}:#{File.join($TORQUEBOX_HOME, 'jruby/lib/ruby/gems/1.8')}"
ENV['GEM_HOME'] = File.join($RULE_SERVER_HOME, 'vendor/jruby/1.8')
else
puts 'Using global GEM_HOME directory.'
end
require 'rubygems'
This file has been truncated. show original
engine.rb
java_import "javax.script.ScriptContext"
java_import "javax.script.ScriptEngine"
java_import "javax.script.ScriptEngineManager"
java_import "javax.script.ScriptException"
java_import "java.io.FileNotFoundException"
java_import "javax.script.Bindings"
java_import "javax.script.SimpleBindings"
java_import "java.io.FileReader"
java_import "java.io.Reader"
This file has been truncated. show original
So i tried to tweak my example to reproduce your error, but I could not
(granted, it doesn’t do quite what you intended yet):
How are you running your app? I’d like to mess around with it and see
if I can get anywhere.
I guess I am inheriting some things from outside or some environment is
being shared. It works without anything like boot.rb file for simple
Rack
applications … with Sinatra it does not however.
clone GitHub - marekjelen/thick: [Moved, check WildWeb] Lightweight web server for JRuby , enter, and checkout
“loader”
branch
create config.ru from Simple Sinatra · GitHub
run jruby bin/thick
You need to have rack and sinatra installed.
That’s all.
Thanks for help.
–
Marek J.
m: +420 724 255807
e: [email protected]
social: twitter https://twitter.com/#!/marek_jelen |
githubhttps://github.com/marekjelen |
linkedin http://cz.linkedin.com/in/marekjelen |
bloghttp://www.marekjelen.cz/
projects: brug http://www.brug.cz/ |
wildcloudhttps://github.com/wildcloud
| rupy.eu | noderb https://github.com/noderb
I think you’d better double check ScriptingContainer knows where all
gems are. The error you got means ScriptingContainer doesn’t know the
definition of “::Rack::Protection::FrameOptions” .
If you don’t pack up all in a jar, setting GEM_PATH on the
ScriptingContainer would work. If you will pack in a jar, you should
set each path to gems using setLoadPath() method. This is cumbersome,
but the best to avoid path related problems.
My blog post,
Using JRuby embed API (RedBridge), it is easy to use Ruby gems from Java. However, packaging might not be simple, so people occasionally str...
, or page 26 - 31 of my presentation slide,
http://redbridge-at-strangeloop2011.herokuapp.com/slideshow , may help
you to understand.
Since you (Marek) correctly instantiated a singlethreaded
ScriptingContainer, perhaps next to check is loading paths.
As far as I tried on the irb, ScriptingContainer created another
instance of Ruby runtime:
irb(main):002:0> require ‘java’
=> true
irb(main):003:0> JRuby.runtime
=> #Java::OrgJruby::Ruby:0x394a8cd1 <— irb’s
runtime
irb(main):004:0> c =
org.jruby.embed.ScriptingContainer.new(org.jruby.embed.LocalContextScope::SINGLETHREAD)
=> #Java::OrgJrubyEmbed::ScriptingContainer:0x7664e5b2
irb(main):005:0> c.getProvider.getRuntime
=> #Java::OrgJruby::Ruby:0x5f5fc606 <—
another runtime instance
irb(main):006:0> ABC = 10
=> 10
irb(main):007:0> c.run_scriptlet(“ABC=100”)
=> 100
irb(main):008:0> ABC
=> 10
<— irb says ABC is 10
irb(main):009:0> c.run_scriptlet(“ABC”)
=> 100
<— ScriptingContainer says ABC is 100
As far as I tried on the irb, ScriptingContainer created another
instance of Ruby runtime:
See Ruby runtimes of singlethreaded ScriptingContainer and irb · GitHub . Below is hard to read.
-Yoko
Hello,
thanks for response.
puts container.getProvider.class #
=> Java::OrgJrubyEmbedInternal::SingleThreadLocalContextProvider
I really hope it’s possible to use it this way
–
Marek J.
m: +420 724 255807
e: [email protected]
social: twitter https://twitter.com/#!/marek_jelen |
githubhttps://github.com/marekjelen |
linkedin http://cz.linkedin.com/in/marekjelen |
bloghttp://www.marekjelen.cz/
projects: brug http://www.brug.cz/ |
wildcloudhttps://github.com/wildcloud
| rupy.eu | noderb https://github.com/noderb