Requiring a compiled class file from within a Jar using RedBridge

Hello everyone,

We recently encountered a bug executing one of our JRuby applications
(which
we execute via RedBridge from within a Tomcat 5.5 context). The
application
works in Windows, but throws an exception from our Linux (Fedora) box
running Java 1.5. We have tested this using both JRuby 1.4 and 1.5RC1
and
both fail with the same message.

Below is the equivalent of what we are doing. I’m working to put
together a
simplified, reproducible example but wanted to see if anyone on the list
had
encountered this before.

// Initialize a new Scripting container
ScriptingContainer container = new
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
// Outputs true
container.runScriptlet(“puts
File.exist?(‘file:/home/kinetic/tomcat/webapps/kinetic/WEB-INF/lib/kinetic-task.jar!/lib/kinetic_task/adapter/base.class’)”);
// Raises the exception below
container.runScriptlet(“require
‘file:/home/kinetic/tomcat/webapps/kinetic/WEB-INF/lib/kinetic-task.jar!/lib/kinetic_task/adapter/base’”);

:1:in `require': no such file to load -- file:/home/kinetic/tomcat/webapps/kinetic/WEB-INF/lib/kinetic-task.jar!/lib/kinetic_task/adapter/base (LoadError) from :1 Any ideas? Thanks, Ben Christenson Developer/Analyst Kinetic Data, Inc. "Building a Better Service Experience" Recipient of the WWRUG09 Innovator of the Year Award 651.556.0937 I www.kineticdata.com

On Wed, Apr 21, 2010 at 1:42 PM, Benjamin Christenson
[email protected] wrote:

encountered this before.

:1:in `require': no such file to load -- file:/home/kinetic/tomcat/webapps/kinetic/WEB-INF/lib/kinetic-task.jar!/lib/kinetic_task/adapter/base (LoadError) from :1

Perhaps, you need to set a load path to the class. Try this to see
what paths are set.

container.runScriptlet(“p $LOAD_PATH”);

If the path to the class doesn’t show up, you can add the path by

container.setLoadPaths(…);

-Yoko

651.556.0937 I www.kineticdata.com


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Yoko,

Do I need to add something to the load path if it is being referenced by
a
fully qualified name?

To simplify my tests, I created a jar file with a single Ruby file,
bar.rb,
into it. The file does a simple puts(“BAR”). I then attempted to
require
the file from within jirb and a simple Servlet, each using a
ScriptingContainer and fully qualified path. The jirb execution worked
as
expected, however the Servlet raised a “no such file to load” LoadError
for
the exact same code.

I have the complete irb output, example Servlet / logfiles, and the load
path for each at http://pastebin.com/QkaHyquZ. Below is a
simplification of
this information.

==> IRB <==
[[email protected] ~]$ java -jar
~/tomcat/webapps/kinetic/WEB-INF/lib/jruby-complete-1.4.0.jar -S irb
irb(main):001:0> include_class org.jruby.embed.LocalContextScope
irb(main):002:0> include_class org.jruby.embed.ScriptingContainer
irb(main):004:0> container =
ScriptingContainer.new(LocalContextScope.valueOf(“THREADSAFE”))
irb(main):005:0> container.runScriptlet(“require
‘file:/home/kinetic/fubar.jar!/bar’”)
BAR
=> true

== Servlet ==
public class LoaderServlet extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
ScriptingContainer container = new
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
container.runScriptlet(“require
‘file:/home/kinetic/fubar.jar!/bar’”);
}
}

==> Servlet Output <==
org.jruby.embed.EvalFailedException: no such file to load –
file:/home/kinetic/fubar.jar!/bar
at
org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:116)
at
org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:457)
at
org.jruby.embed.ScriptingContainer.runScriptlet(ScriptingContainer.java:450)
at com.kineticdata.LoaderServlet.init(LoaderServlet.java:14)

Caused by: org.jruby.exceptions.RaiseException: no such file to load –
file:/home/kinetic/fubar.jar!/bar
at (unknown).new(:1)
at Kernel.require(:1)
at (unknown).(unknown)(:1)

Any ideas?

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

On Mon, Apr 26, 2010 at 12:41 PM, Benjamin Christenson
[email protected] wrote:

the exact same code.
This is because only one thread involved on jirb, but multiple threads
did on servlet.

ScriptingContainer.new(LocalContextScope.valueOf(“THREADSAFE”))
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
org.jruby.embed.ScriptingContainer.runUnit(ScriptingContainer.java:457)
Any ideas?
In general, the thread used to instantiate a servlet and call it’s
init() method is not the same as the thread used to handle HTTP
request. Usually, pooled worker threads run doGet()/doPost() methods.
When you choose threadsafe model, individual worker thread has it’s
own Ruby runtime since runtime will be thread local. So, if you change
the code like in below, it will probably work.

public class LoaderServlet extends HttpServlet {
private ScriptingContainer containerl
public void init(ServletConfig config) throws ServletException {
super.init(config);
ScriptingContainer container = new
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
}

public void doGet(HttpServletRequest request, HttpServletResponse
response)
throws IOException {

container.runScriptlet(“require
‘file:/home/kinetic/fubar.jar!/bar’”);
}

-Yoko

works in Windows, but throws an exception from our Linux (Fedora) box
// Initialize a new Scripting container

Ben Christenson
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

After attempting to recreate this issue on multiple environments, it
looks
like this is an issue with the underlying JRE. Once I updated to Sun’s
Java
1.5.0_22 the issue no longer occurred.

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

On Tue, Apr 27, 2010 at 2:46 PM, Benjamin Christenson <

On Tue, Apr 27, 2010 at 5:32 PM, Benjamin Christenson
[email protected] wrote:

After attempting to recreate this issue on multiple environments, it looks
like this is an issue with the underlying JRE. Once I updated to Sun’s Java
1.5.0_22 the issue no longer occurred.

Thanks for reporting how you could fix your problem.

It is really interesting. Before you updated, what Java version did
you use? There might be other people who have the same problem.

-Yoko

irb(main):004:0> container =
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
Developer/Analyst

[email protected] wrote:

the file from within jirb and a simple Servlet, each using a
load
ScriptingContainer.new(LocalContextScope.valueOf(“THREADSAFE”))
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:116)
at Kernel.require(:1)

       throws IOException {

Developer/Analyst

[email protected] wrote:

1.5RC1
// Initialize a new Scripting container

what paths are set.

Any ideas?


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

It was on an old CentOS machine using Sun’s Java 1.5.0_09.

If I get some time this weekend, I’ll decrement and increment the
version to
determine which versions behave incorrectly. I’ll also try it out on a
few
other flavors of Linux to see if it is purely a Java version issue or if
there are other environmental factors.

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

Yoko,

I don’t think that this is a Thread issue (although, I did try your
suggestion in case I was missing something). The LoaderServlet did not
have
a doGet method at all. I am purely using the Servlet to initialize the
ScriptingContainer and attempt to require a file from within a jar
(file:/home/kinetic/fubar.jar!/bar.rb).

Further, I also tested with jruby-complete-1.5.RC1.jar and tested “load
‘file:/home/kinetic/fubar.jar!/bar.rb’” rather than a require statement.
In
all cases, the code works in IRB and not from the ScriptingContainer.

To restate:

==> Contents of file:/home/kinetic/fubar.jar!/bar.rb <==
puts “BAR”

==> Execution from within IRB <==
irb(main):004:0> container =
ScriptingContainer.new(LocalContextScope.valueOf(“THREADSAFE”))
irb(main):005:0> container.runScriptlet(“puts
File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)”);
// true
irb(main):006:0> container.runScriptlet(“require
‘file:/home/kinetic/fubar.jar!/bar’”)
// BAR

==> Execution from within a Servlet <==
ScriptingContainer container = new
ScriptingContainer(LocalContextScope.valueOf(“THREADSAFE”));
container.runScriptlet(“puts
File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)”);
// true
container.runScriptlet(“require ‘file:/home/kinetic/fubar.jar!/bar’”);
// org.jruby.embed.EvalFailedException: no such file to load –
file:/home/kinetic/fubar.jar!/bar

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

OK, upgrading the Java version was actually a red herring solution. In
doing so, I changed the way that I started Tomcat. It actually looks
like
the issue I was encountering was due to the current working directory
being
the root directory (’/’). The issue doesn’t look to be with Redbridge
at
all (that just happened to be the only way were were calling into
JRuby),
but with JRuby parsing file paths while the current working directory is
set
to ‘/’. I have tested this in both Linux and Windows and it appears to
have
the same behavior.

I’m assuming that the behavior below (and at
http://pastebin.com/0r5nmWc7)
is not expected?

[[email protected] ~]$ java -version
java version “1.5.0_15”
Java™ 2 Runtime Environment, Standard Edition (build 1.5.0_15-b04)
Java HotSpot™ Client VM (build 1.5.0_15-b04, mixed mode)

[[email protected] ~]$ java -jar /home/kinetic/jruby-complete-1.4.0.jar -S
irb
irb(main):001:0> Dir.pwd
=> “/home/kinetic”
irb(main):002:0> File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)
=> true
irb(main):003:0> load(‘file:/home/kinetic/fubar.jar!/bar.rb’)
BAR
=> true
irb(main):004:0> Dir.chdir ‘/’
=> 0
irb(main):005:0> Dir.pwd
=> “/”
irb(main):006:0> File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)
=> true
irb(main):007:0> load(‘file:/home/kinetic/fubar.jar!/bar.rb’)
LoadError: No such file to load – file:/home/kinetic/fubar.jar!/bar.rb
from (irb):8:in `load’
from (irb):8
irb(main):008:0> exit

[[email protected] ~]$ java -jar /home/kinetic/jruby-complete-1.5.0.RC2.jar
-S
irb
irb(main):001:0> Dir.pwd
=> “/home/kinetic”
irb(main):002:0> File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)
=> true
irb(main):003:0> load(‘file:/home/kinetic/fubar.jar!/bar.rb’)
BAR
=> true
irb(main):004:0> Dir.chdir ‘/’
=> 0
irb(main):005:0> Dir.pwd
=> “/”
irb(main):006:0> File.exist?(‘file:/home/kinetic/fubar.jar!/bar.rb’)
=> true
irb(main):007:0> load(‘file:/home/kinetic/fubar.jar!/bar.rb’)
LoadError: No such file to load – file:/home/kinetic/fubar.jar!/bar.rb
from (irb):7:in `load’
from (irb):7
irb(main):008:0> exit
[[email protected] ~]$

Thanks,
Ben Christenson
Developer/Analyst

Kinetic Data, Inc.
“Building a Better Service Experience”
Recipient of the WWRUG09 Innovator of the Year Award

651.556.0937 I www.kineticdata.com http://www.kineticdata.com

On Wed, Apr 28, 2010 at 10:44 AM, Benjamin Christenson <

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs