Issue Details (XML | Word | Printable)

Key: JRUBY-3048
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: Charles Oliver Nutter
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
JRuby

Specs for all load path, load/require, home dir, url, and other load-logic cases

Created: 10/Oct/08 12:40 AM   Updated: 21/May/09 01:47 AM
Component/s: Core Classes/Modules
Affects Version/s: None
Fix Version/s: JRuby 1.x+

Time Tracking:
Not Specified


 Description  « Hide
There are many different combinations of logic involved in the loading of files. Very few of them have a clear set (or perhaps any set) of codified specifications. This bug can be a placeholder for recording various combinations of behavior, in the hope that a set of specifications will follow (and fixes to JRuby will follow that).

I'll start it off with a failing case in JRuby with load of a file using ./ pathing:

~/projects/jruby ➔ jruby -Ifoo -e "load 'foo/bar.rb'"
foo/bar.rb:1: unhandled exception
	from foo/bar.rb:1:in `load'
	from -e:1

~/projects/jruby ➔ ruby -Ifoo -e "load 'foo/bar.rb'"
./foo/bar.rb:1: unhandled exception
	from -e:1:in `load'
	from -e:1


 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Charles Oliver Nutter added a comment - 10/Oct/08 12:41 AM
From JRUBY-2909:

It seems that largely, Ruby leaves relative paths relative and absolute paths absolute, using those literal paths in logging and traces. It also resolves relative paths dynamically at runtime based on the process CWD:

~/projects/jruby ➔ ruby -Ifoo -e "require 'bar'"
./foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby ➔ cd foo
~/projects/jruby/foo ➔ ruby -e "require 'bar'"
./bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby/foo ➔ cd ../lib
~/projects/jruby/lib ➔ ruby -I../foo -e "require 'bar'"
../foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby/lib ➔ ruby -I../../jruby/foo -e "require 'bar'"
../../jruby/foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby/lib ➔ ruby -I/Users/headius/projects/jruby/foo -e "require 'bar'"
/Users/headius/projects/jruby/foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby/lib ➔ cd ..
~/projects/jruby ➔ ruby -Ifoo -e "Dir.chdir('lib'); require 'bar'"
-e:1:in `require': no such file to load -- bar (LoadError)
	from -e:1

So our problem, and the reason why we always seem to have full paths in traces, is that we always turn paths into absolute paths, losing that original short path. This also represents a behavioral difference; notice in the last case that when the CWD is changed, relative paths no longer resolve the same.


Charles Oliver Nutter added a comment - 10/Oct/08 12:42 AM
From JRUBY-2909:

A few more interesting cases:

~/projects/jruby ➔ ruby -Ifoo -e "require 'bar'"
./foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby ➔ ruby -e "require 'foo/bar'"
./foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1
~/projects/jruby ➔ ruby -e "require './foo/bar'"
./foo/bar.rb:1: unhandled exception
	from -e:1:in `require'
	from -e:1

Note that, while not immediately apparent here, Ruby does appear to attempt to certain paths as-is before trying load paths, and does not appear to ever attach load paths to absolute paths (which makes some sense). So adding a short-circuit that tries the path as-is first seems to also be in the cards.


Charles Oliver Nutter added a comment - 10/Oct/08 12:42 AM
From JRUBY-2909:

A couple more, showing Ruby does not attempt to search load path for a relative path based on . (CWD):

First with no bar.rb in current dir, but a bar.rb in the 'foo' dir:

~/projects/jruby ➔ ruby -Ifoo -e "require './bar.rb'"
-e:1:in `require': no such file to load -- ./bar.rb (LoadError)
	from -e:1

Now with a bar.rb in current dir:

~/projects/jruby ➔ echo puts \'hello\' > bar.rb
~/projects/jruby ➔ ruby -Ifoo -e "require './bar.rb'"
hello

Obviously we need to put together specs for all the many cases. A few more that need to be specified:

  • home dir using ~ and ~username
  • all URLs, not just the limited support for file: and jar: we have now
  • Windows paths
  • paths with symlinks (to see whether they get expanded or left as-is in traces, etc)

Others?


Charles Oliver Nutter added a comment - 10/Oct/08 12:43 AM
From JRUBY-2922, mostly fixed now I believe but not spec'ed or tested anywhere:

Note the difference between these two traces:

Ruby:

./test2.rb:3: unhandled exception
	from test1.rb:2:in `require'
	from test1.rb:2

JRuby:

/Users/headius/NetBeansProjects/jruby/./test2.rb:3:in `(unknown)': unhandled exception
	from /Users/headius/NetBeansProjects/jruby/./test2.rb:2:in `require'
	from test1.rb:2:in `(unknown)'

LoadService is currently expanding paths to their full absolute path (and in some cases, to their canonical non-symlinked path) before passing the file off to be parsed and loaded. This is largely why backtraces, trace events, compiled package names, and so on have the full path. Tom Enebo fixed the parser in the last release to not use long paths, and it seems that currently the only remaining issue is in the load process.


Charles Oliver Nutter added a comment - 10/Oct/08 12:45 AM
See also JRUBY-3029 for a discussion about .class versus .rb search ordering (fixed along with that bug, but not yet spec'ed/tested well.

Charles Oliver Nutter added a comment - 10/Oct/08 12:48 AM
From JRUBY-3014, still unresolved issues with _FILE_ and jar-based or class-based (precompiled) scripts:

Here's the breakdown:
Compiled and uncompiled Ruby classes from the command line work fine
Compiled and uncompiled Ruby classes in the root of a jar do not properly resolve File.expand_path(File.dirname(_FILE_))
Compiled Ruby classes in a sub-directory of a jar do not properly resolve File.expand_path(File.dirname(_FILE_))
Uncompiled Ruby classes in a sub-directory of a jar DO properly resolve File.expand_path(File.dirname(_FILE_))

#=== file_test.rb ===

puts "__FILE__: #{__FILE__}"
puts "File.dirname(__FILE__): #{File.dirname(__FILE__)}"
puts "File.expand_path(File.dirname(__FILE__)): #{File.expand_path(File.dirname(__FILE__))}"

#=== bootstrap1.rb === (used to test uncompiled Ruby files in a jar)
require 'file_test'

#=== bootstrap2.rb === (used to test uncompiled Ruby files in a jar)
require 'src/file_test'

# GIVES CORRECT OUTPUT
#=== Running the file_test.rb file unmodified using MRI and JRuby ===
ruby file_test.rb 
__FILE__: file_test.rb
File.dirname(__FILE__): .
File.expand_path(File.dirname(__FILE__)): /Users/david/dev/projects/general/jruby_test

jruby file_test.rb 
__FILE__: file_test.rb
File.dirname(__FILE__): .
File.expand_path(File.dirname(__FILE__)): /Users/david/dev/projects/general/jruby_test

# GIVES CORRECT OUTPUT
# === Compile the file_test.rb file (jrubyc file_test.rb) ===
java -cp ~/dev/libs/jruby/lib/jruby.jar:. file_test
__FILE__: file_test.rb
File.dirname(__FILE__): .
File.expand_path(File.dirname(__FILE__)): /Users/david/dev/projects/general/jruby_test

# GIVES INCORRECT OUTPUT
# === Jarring the file_test.rb (jar -cvf file_test.jar file_test.rb bootstrap1.class) and placing jar file in /jar sub-directory ===
# Adding in compiled bootstrap1 class so java has something to launch
java -cp ~/dev/libs/jruby/lib/jruby-complete.jar:file_test.jar bootstrap1 #<-- no output, internally an exception?

# GIVES INCORRECT OUTPUT
# === Jarring the file_test.class (jar -cvf file_test.jar file_test.class) (also placing in /jar sub-directory) ===
# Moved file_test.jar into /jar subdirectory to prevent accidentally pulling in .class file
java -cp ~/dev/libs/jruby/lib/jruby-complete.jar:file_test.jar file_test
__FILE__: file_test.rb
File.dirname(__FILE__): .
File.expand_path(File.dirname(__FILE__)): /Users/david/dev/projects/general/jruby_test/jar #<-- should have /file_test.jar! on the end

GIVES CORRECT OUTPUT
# === Uncompiled Ruby file in /src directory in jar file ===
# Use bootstrap2 file to require file in 'src/test_file'
java -cp ~/dev/libs/jruby/lib/jruby-complete.jar:file_test.jar bootstrap2
__FILE__: file:/Users/david/dev/projects/general/jruby_test/jar/file_test.jar!/src/file_test.rb
File.dirname(__FILE__): file:/Users/david/dev/projects/general/jruby_test/jar/file_test.jar!/src
File.expand_path(File.dirname(__FILE__)): file:/Users/david/dev/projects/general/jruby_test/jar/file_test.jar!/src #<-- We get the jar file and the sub-dir, yay!

GIVES INCORRECT OUTPUT
# === Compiled Ruby file in /src directory in jar file ===
# As above but with compiled Ruby file, same bootstrap2 file
java -cp ~/dev/libs/jruby/lib/jruby-complete.jar:file_test.jar bootstrap2
__FILE__: file_test.rb
File.dirname(__FILE__): .
File.expand_path(File.dirname(__FILE__)): /Users/david/dev/projects/general/jruby_test/jar #<-- missing /file_test.jar!/src

Charles Oliver Nutter added a comment - 02/Dec/08 03:25 PM
Still need specs, and there's still outstanding bugs relating to require (like the fact that it always tries cwd even if . isn't in load path).

Charles Oliver Nutter added a comment - 23/Feb/09 04:11 PM
There are a lot of new specs in RubySpec for load stuff, but we need some of our own for URLs, jar files, all that. It's still fuzzily covered.