jira.codehaus.org

  • Log In Access more options
    • Online Help
    • Keyboard Shortcuts
    • About JIRA
    • JIRA Credits
    • What?s New
  • Dashboards Access more options (Alt+d)
  • Projects Access more options (Alt+p)
  • Issues Access more options (Alt+i)
  • JRuby
  • JRUBY-2708

JRuby should load relative path reference to AOT classes

  • Log In
  • Views
    • XML
    • Word
    • Printable

Details

  • Type: Wish Wish
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.1.2
  • Fix Version/s: JRuby 1.7.0.pre1
  • Component/s: Interpreter
  • Labels:
    None

Description

Occasionally, when loading classes that have been compiled ahead-of-time, references such as require './foo.rb' is encountered by the runtime. The runtime is already smart enough to also look for foo.class when loading 'foo.rb'. It would be nice if it will also automatically consider foo.class if "./foo.rb" or ".\foo.rb" is requested.

  • Options
    • Sort By Name
    • Sort By Date
    • Ascending
    • Descending
    • Download All

Attachments

  1. Text File
    jruby_load_class_without_relative_prefix.patch
    02/Jul/08 4:34 PM
    0.9 kB
    Peter K Chan
  2. File
    test_jruby_load_relative_path_from_jar_2.rb
    16/Jul/08 12:18 PM
    0.6 kB
    Peter K Chan
  3. File
    test_jruby_load_relative_path_from_jar.rb
    03/Jul/08 11:20 AM
    0.7 kB
    Peter K Chan

Activity

Ascending order - Click to sort in descending order
  • All
  • Comments
  • Work Log
  • History
  • Activity
Hide
Permalink
Peter K Chan added a comment - 26/Jun/08 1:08 PM

Sorry, the name of this issue is incomplete. It should be "JRuby should load relative path reference to AOT classes"

Show
Peter K Chan added a comment - 26/Jun/08 1:08 PM Sorry, the name of this issue is incomplete. It should be "JRuby should load relative path reference to AOT classes"
Hide
Permalink
Peter K Chan added a comment - 02/Jul/08 4:34 PM

The attached patch will try loading class "foo/bar" when asked to load "./foo/bar".

Show
Peter K Chan added a comment - 02/Jul/08 4:34 PM The attached patch will try loading class "foo/bar" when asked to load "./foo/bar".
Hide
Permalink
Charles Oliver Nutter added a comment - 02/Jul/08 7:00 PM

Fixing bug title.

Show
Charles Oliver Nutter added a comment - 02/Jul/08 7:00 PM Fixing bug title.
Hide
Permalink
Charles Oliver Nutter added a comment - 02/Jul/08 7:08 PM

Ok, I'm a little confused. Can you provide a test case for this or something that shows what you need it to do? Removing the relative path seems like an odd thing to do, if not a dangerous one, since it would then start trying to load things from elsewhere in the load path. If this is intended to just have "load" gain the behavior to look for .class as well as .rb, I can handle that. Test case please?

Show
Charles Oliver Nutter added a comment - 02/Jul/08 7:08 PM Ok, I'm a little confused. Can you provide a test case for this or something that shows what you need it to do? Removing the relative path seems like an odd thing to do, if not a dangerous one, since it would then start trying to load things from elsewhere in the load path. If this is intended to just have "load" gain the behavior to look for .class as well as .rb, I can handle that. Test case please?
Hide
Permalink
Peter K Chan added a comment - 02/Jul/08 7:30 PM

Here is an example from an older version of Active Support that I still use:

On the very last line of active_support/inflector.rb, there is a line that uses the _FILE_ reference:

require File.dirname(__FILE__) + '/inflections'

Which is translated to "./active_support/inflections" at run time. However, if /active_support/inflections.rb has been pre-compiled as a Java class, then you have to load it with the name "active_support/inflections" and not "./active_support/inflections" Otherwise, even if active_support/inflections.class is available, the following error result:

no such file to load -- ./active_support/inflections

The attached patch only changes the very specific case of locating a Java class, and it does not affect other cases, such as loading .rb files or any other such ways.

Show
Peter K Chan added a comment - 02/Jul/08 7:30 PM Here is an example from an older version of Active Support that I still use: On the very last line of active_support/inflector.rb, there is a line that uses the _FILE_ reference:
require File.dirname(__FILE__) + '/inflections'
Which is translated to "./active_support/inflections" at run time. However, if /active_support/inflections.rb has been pre-compiled as a Java class, then you have to load it with the name "active_support/inflections" and not "./active_support/inflections" Otherwise, even if active_support/inflections.class is available, the following error result:
no such file to load -- ./active_support/inflections
The attached patch only changes the very specific case of locating a Java class, and it does not affect other cases, such as loading .rb files or any other such ways.
Hide
Permalink
Charles Oliver Nutter added a comment - 03/Jul/08 9:53 AM

Hmm, are you sure this isn't working? Can you provide a reproducible case that doesn't depend on Rails? For example, I tried precompiling optparse into my current dir, and then renamed the .class file to make sure it wasn't loading optparse.rb from anywhere. This works:

~/NetBeansProjects/jruby ➔ ls -l optparse2.class 
-rw-r--r--  1 headius  headius  161848 Jul  3 09:30 optparse2.class
~/NetBeansProjects/jruby ➔ jruby -e "require './optparse2'; p OptionParser"
OptionParser

What's more, even if it's in a subdir it seems to work ok. What am I doing differently than your app?

~/NetBeansProjects/jruby ➔ mv optparse2.class tmp
~/NetBeansProjects/jruby ➔ jruby -e "require './tmp/optparse2'; p OptionParser"
OptionParser
Show
Charles Oliver Nutter added a comment - 03/Jul/08 9:53 AM Hmm, are you sure this isn't working? Can you provide a reproducible case that doesn't depend on Rails? For example, I tried precompiling optparse into my current dir, and then renamed the .class file to make sure it wasn't loading optparse.rb from anywhere. This works:
~/NetBeansProjects/jruby ➔ ls -l optparse2.class 
-rw-r--r--  1 headius  headius  161848 Jul  3 09:30 optparse2.class
~/NetBeansProjects/jruby ➔ jruby -e "require './optparse2'; p OptionParser"
OptionParser
What's more, even if it's in a subdir it seems to work ok. What am I doing differently than your app?
~/NetBeansProjects/jruby ➔ mv optparse2.class tmp
~/NetBeansProjects/jruby ➔ jruby -e "require './tmp/optparse2'; p OptionParser"
OptionParser
Hide
Permalink
Peter K Chan added a comment - 03/Jul/08 11:20 AM

It looks like the problem only occurs in the specific case of when you load AOT compiled classes from a JAR.

I have a half working test script attached. I am in a hurry to step out now, so I don't have time to debug it, but give it a try (it acts weird on Windows, but may actually runs fine on Linux). Even if it doesn't work, you should be able to reproduce the problem manually by emulating what the script does.

Show
Peter K Chan added a comment - 03/Jul/08 11:20 AM It looks like the problem only occurs in the specific case of when you load AOT compiled classes from a JAR. I have a half working test script attached. I am in a hurry to step out now, so I don't have time to debug it, but give it a try (it acts weird on Windows, but may actually runs fine on Linux). Even if it doesn't work, you should be able to reproduce the problem manually by emulating what the script does.
Hide
Permalink
Charles Oliver Nutter added a comment - 15/Jul/08 12:32 AM

Ok, I was able to confirm the problem:

~/NetBeansProjects/jruby ➔ cat test.rb
require './foo.rb'
~/NetBeansProjects/jruby ➔ cat foo.rb
puts 'here'
~/NetBeansProjects/jruby ➔ jruby test.rb
here
~/NetBeansProjects/jruby ➔ jrubyc test.rb foo.rb
Compiling test.rb to class test
Compiling foo.rb to class foo
~/NetBeansProjects/jruby ➔ jar cf blah.jar foo.class test.class
~/NetBeansProjects/jruby ➔ java -cp blah.jar:lib/jruby.jar test
here
~/NetBeansProjects/jruby ➔ rm foo.rb foo.class
~/NetBeansProjects/jruby ➔ java -cp blah.jar:lib/jruby.jar test
Exception in thread "main" test.rb:1:in `require': no such file to load -- ./foo (LoadError)
	from test.rb:1
	...internal jruby stack elided...

Refreshing my memory about the patch, but I'll probably go ahead and apply it.

Show
Charles Oliver Nutter added a comment - 15/Jul/08 12:32 AM Ok, I was able to confirm the problem:
~/NetBeansProjects/jruby ➔ cat test.rb
require './foo.rb'
~/NetBeansProjects/jruby ➔ cat foo.rb
puts 'here'
~/NetBeansProjects/jruby ➔ jruby test.rb
here
~/NetBeansProjects/jruby ➔ jrubyc test.rb foo.rb
Compiling test.rb to class test
Compiling foo.rb to class foo
~/NetBeansProjects/jruby ➔ jar cf blah.jar foo.class test.class
~/NetBeansProjects/jruby ➔ java -cp blah.jar:lib/jruby.jar test
here
~/NetBeansProjects/jruby ➔ rm foo.rb foo.class
~/NetBeansProjects/jruby ➔ java -cp blah.jar:lib/jruby.jar test
Exception in thread "main" test.rb:1:in `require': no such file to load -- ./foo (LoadError)
	from test.rb:1
	...internal jruby stack elided...
Refreshing my memory about the patch, but I'll probably go ahead and apply it.
Hide
Permalink
Charles Oliver Nutter added a comment - 15/Jul/08 12:56 AM

Ok, I've gone ahead and applied the fix, because I was able to reproduce the problem and see that it fixed it, and it didn't appear to break anything with normal filesystem-based requiring of .class files. No problem. But the test you provided didn't seem to pass, or at least didn't seem to test what I fixed. Can you try to clean it up for 1.1.3 and we'll mark this as resolved? Or if there's still an issue on your end, let me know?

Show
Charles Oliver Nutter added a comment - 15/Jul/08 12:56 AM Ok, I've gone ahead and applied the fix, because I was able to reproduce the problem and see that it fixed it, and it didn't appear to break anything with normal filesystem-based requiring of .class files. No problem. But the test you provided didn't seem to pass, or at least didn't seem to test what I fixed. Can you try to clean it up for 1.1.3 and we'll mark this as resolved? Or if there's still an issue on your end, let me know?
Hide
Permalink
Peter K Chan added a comment - 16/Jul/08 2:35 AM

I can verify that the relative reference is now automatically handled when trying to load for class. I no longer have to hook the require statement to strip the initial "./"

I have worked on a simpler test script, but I am having a hard time polishing it up (I want to delete the JAR for test teardown, but I can't delete it, if it is loaded into the JVM by JRuby for AOT loading). I will try, I may not be able to get the test case in in time for 1.1.3.

Show
Peter K Chan added a comment - 16/Jul/08 2:35 AM I can verify that the relative reference is now automatically handled when trying to load for class. I no longer have to hook the require statement to strip the initial "./" I have worked on a simpler test script, but I am having a hard time polishing it up (I want to delete the JAR for test teardown, but I can't delete it, if it is loaded into the JVM by JRuby for AOT loading). I will try, I may not be able to get the test case in in time for 1.1.3.
Hide
Permalink
Peter K Chan added a comment - 16/Jul/08 12:18 PM

Looks like in my effort to write the test script, I have uncovered a bug/incompleteness in the handling of relative path loading. The attached script fails when the ruby class is loaded dynamically using require('test.jar'), as opposed to when test.jar was included on the JVM classpath at launch.

The patch that I previously submitted only deals with classloading with compiled ruby files that are already in the JVM initial classpath, but not when the JAR is later added to the loadpath.

Show
Peter K Chan added a comment - 16/Jul/08 12:18 PM Looks like in my effort to write the test script, I have uncovered a bug/incompleteness in the handling of relative path loading. The attached script fails when the ruby class is loaded dynamically using require('test.jar'), as opposed to when test.jar was included on the JVM classpath at launch. The patch that I previously submitted only deals with classloading with compiled ruby files that are already in the JVM initial classpath, but not when the JAR is later added to the loadpath.
Hide
Permalink
Peter K Chan added a comment - 16/Jul/08 12:20 PM

Charles, I probably won't have time to come up with a new patch in time for JRuby 1.1.3 release. Unless you see a quick way to patch for the other use case, feel free to postpone this bug for after 1.1.3.

Show
Peter K Chan added a comment - 16/Jul/08 12:20 PM Charles, I probably won't have time to come up with a new patch in time for JRuby 1.1.3 release. Unless you see a quick way to patch for the other use case, feel free to postpone this bug for after 1.1.3.
Hide
Permalink
Charles Oliver Nutter added a comment - 16/Jul/08 12:57 PM

Ok Peter, thanks for responding. I'll leave your fix in place for this for 1.1.3, since it doesn't hurt anything and it does fix at least one instance of loading from a jar file. We'll bump the remaining work off 1.1.3 and continue to find and fix cases, for complete resolution as part of a future release.

Show
Charles Oliver Nutter added a comment - 16/Jul/08 12:57 PM Ok Peter, thanks for responding. I'll leave your fix in place for this for 1.1.3, since it doesn't hurt anything and it does fix at least one instance of loading from a jar file. We'll bump the remaining work off 1.1.3 and continue to find and fix cases, for complete resolution as part of a future release.
Hide
Permalink
Charles Oliver Nutter added a comment - 08/Feb/09 1:34 AM

Peter: Can you give this another try with current JRuby? We've done a couple passes at making require logic more logical, and there's a strong chance we've got all cases covered now.

Show
Charles Oliver Nutter added a comment - 08/Feb/09 1:34 AM Peter: Can you give this another try with current JRuby? We've done a couple passes at making require logic more logical, and there's a strong chance we've got all cases covered now.
Hide
Permalink
Peter K Chan added a comment - 08/Feb/09 2:48 PM

I am out of town right now. I will look at this before the end of this week.

Show
Peter K Chan added a comment - 08/Feb/09 2:48 PM I am out of town right now. I will look at this before the end of this week.
Hide
Permalink
Peter K Chan added a comment - 12/Feb/09 11:45 PM

I have verified that JRuby 1.2.0 trunk fails the test to require "./foo.rb" when loading from a JAR file.

IRB transcript below, where tmp_test.jar contains a 'foo.class' on the top level:

c:\work>c:\tmp\jruby\bin\jruby c:\tmp\jruby\bin\jirb
irb(main):001:0> require 'tmp_test.jar'
=> true
irb(main):002:0> require './foo.rb'
LoadError: no such file to load – ./foo
from (irb):3:in `require'
from (irb):3
irb(main):003:0> require 'foo.rb'
Foo loading...
=> true

Note how the "foo.rb" reference works, but "./foo.rb" does not.

This failure only pertains to loading "./foo.rb" from a packaged JAR file. If foo.class lies on the file system without any package, then require "./foo.rb" also works.

Show
Peter K Chan added a comment - 12/Feb/09 11:45 PM I have verified that JRuby 1.2.0 trunk fails the test to require "./foo.rb" when loading from a JAR file. IRB transcript below, where tmp_test.jar contains a 'foo.class' on the top level: c:\work>c:\tmp\jruby\bin\jruby c:\tmp\jruby\bin\jirb irb(main):001:0> require 'tmp_test.jar' => true irb(main):002:0> require './foo.rb' LoadError: no such file to load – ./foo from (irb):3:in `require' from (irb):3 irb(main):003:0> require 'foo.rb' Foo loading... => true Note how the "foo.rb" reference works, but "./foo.rb" does not. This failure only pertains to loading "./foo.rb" from a packaged JAR file. If foo.class lies on the file system without any package, then require "./foo.rb" also works.
Hide
Permalink
Josh Matthews added a comment - 30/Aug/09 10:10 PM

This fails because of a call to ClassLoader.getResource() with the resource "././foo.rb". This occurs because the load path being tested is ".", and it has a slash appended to it.

Show
Josh Matthews added a comment - 30/Aug/09 10:10 PM This fails because of a call to ClassLoader.getResource() with the resource "././foo.rb". This occurs because the load path being tested is ".", and it has a slash appended to it.
Hide
Permalink
Josh Matthews added a comment - 30/Aug/09 11:25 PM

Actually the previous comment is a complete lie. The answer lies in this comment at the end of findFileInClassPath():

// Try to load from classpath without prefix. "A/b.rb" will not load as "./A/b.rb" in a jar file.

Assuming that comment's correct, the only solution I can see is stripping off the ./ prefix.

Show
Josh Matthews added a comment - 30/Aug/09 11:25 PM Actually the previous comment is a complete lie. The answer lies in this comment at the end of findFileInClassPath(): // Try to load from classpath without prefix. "A/b.rb" will not load as "./A/b.rb" in a jar file. Assuming that comment's correct, the only solution I can see is stripping off the ./ prefix.
Hide
Permalink
Charles Oliver Nutter added a comment - 01/Sep/09 4:27 PM

Hmmm, sounds like there's a patch in here somewhere. Someone want to try fixing it?

Show
Charles Oliver Nutter added a comment - 01/Sep/09 4:27 PM Hmmm, sounds like there's a patch in here somewhere. Someone want to try fixing it?
Hide
Permalink
Hiro Asari added a comment - 17/May/12 10:10 PM

Charlie,

After 2.5 years, this issue seems to be fixed. Do you agree?

$ java -cp blah.jar:../lib/jruby.jar test
here
Show
Hiro Asari added a comment - 17/May/12 10:10 PM Charlie, After 2.5 years, this issue seems to be fixed. Do you agree?
$ java -cp blah.jar:../lib/jruby.jar test
here
Hide
Permalink
Charles Oliver Nutter added a comment - 18/May/12 1:19 PM

Yeah, I agree! If it looks fixed, mark it fixed!

Show
Charles Oliver Nutter added a comment - 18/May/12 1:19 PM Yeah, I agree! If it looks fixed, mark it fixed!

People

  • Assignee:
    Charles Oliver Nutter
    Reporter:
    Peter K Chan
Vote (0)
Watch (3)

Dates

  • Created:
    26/Jun/08 1:07 PM
    Updated:
    Saturday 12:38 AM
    Resolved:
    Saturday 12:38 AM
  • Atlassian JIRA (v5.0.4#731-sha1:3aa7374)
  • Report a problem
  • Powered by a free Atlassian JIRA open source license for Codehaus. Try JIRA - bug tracking software for your team.