JRuby (please use github issues at http://bugs.jruby.org)
  1. JRuby (please use github issues at http://bugs.jruby.org)
  2. JRUBY-5273

[1.9] The "." dir should not be in load path, but we also put it in CLASSPATH

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: JRuby 1.6.4
    • Component/s: Ruby 1.9.2
    • Labels:
      None
    • Number of attachments :
      0

      Description

      Ruby 1.9 no longer includes the "." dir in the default load path. We can make this change, and JRUBY-5251 tracks the progress of that fix (and a related bug). However, we also include "." in the default CLASSPATH, which means even if it's not in load path, we will eventually still find resources in the current directory.

      There are a couple possible routes here:

      • Ignore it, and just accept that CLASSPATH and load path are different. I'm not sure this is an option, since it will cause us to always deviate on whether we find resources in the current directory.
      • At startup, don't include . in CLASSPATH. Currently, in both jruby.bash and the native launcher, I think we include "." explicitly. We could turn that off, if so.

      Of course, system-global CLASSPATH settings would be impossible to modify.

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        Moving to 1.6.1, if we do anything about it at all.

        Show
        Charles Oliver Nutter added a comment - Moving to 1.6.1, if we do anything about it at all.
        Hide
        Hiroshi Nakamura added a comment -

        Here's a typescript from JRUBY-5526.

        0% ls
        0% echo 'p :loaded' > target.rb
        0% ruby -e 'require "target"'
        /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require': cannot load such file -- target (LoadError)
        	from /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
        	from -e:1:in `<main>'
        1% jruby --1.9 -e 'require "target"'
        :loaded
        0% jruby --1.9 -e 'p $LOAD_PATH'
        ["/home/nahi/git/jruby/lib/ruby/site_ruby/1.9", "/home/nahi/git/jruby/lib/ruby/site_ruby/shared", "/home/nahi/git/jruby/lib/ruby/site_ruby/1.8", "/home/nahi/git/jruby/lib/ruby/1.9"]
        

        And here's the artificial example what might be a problem.

        0% echo 'require "httpclient"; p HTTPClient' > httpclient.rb
        0% ruby httpclient.rb
        HTTPClient
        0% jruby --1.9 httpclient.rb
        NameError: uninitialized constant HTTPClient
          const_missing at org/jruby/RubyModule.java:2528
                 (root) at /home/nahi/git/jruby/httpclient.rb:1
                require at org/jruby/RubyKernel.java:1046
                require at /home/nahi/git/jruby/httpclient.rb:29
                 (root) at httpclient.rb:1
        1% mv httpclient.rb _httpclient.rb
        0% jruby --1.9 _httpclient.rb 
        HTTPClient
        0% 
        

        I don't think this difference is important. I think it's OK with the current behavior for 1.6GA.

        Show
        Hiroshi Nakamura added a comment - Here's a typescript from JRUBY-5526 . 0% ls 0% echo 'p :loaded' > target.rb 0% ruby -e 'require "target"' /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require': cannot load such file -- target (LoadError) from /usr/local/lib/ruby/1.9.1/rubygems/custom_require.rb:35:in `require' from -e:1:in `<main>' 1% jruby --1.9 -e 'require "target"' :loaded 0% jruby --1.9 -e 'p $LOAD_PATH' ["/home/nahi/git/jruby/lib/ruby/site_ruby/1.9", "/home/nahi/git/jruby/lib/ruby/site_ruby/shared", "/home/nahi/git/jruby/lib/ruby/site_ruby/1.8", "/home/nahi/git/jruby/lib/ruby/1.9"] And here's the artificial example what might be a problem. 0% echo 'require "httpclient"; p HTTPClient' > httpclient.rb 0% ruby httpclient.rb HTTPClient 0% jruby --1.9 httpclient.rb NameError: uninitialized constant HTTPClient const_missing at org/jruby/RubyModule.java:2528 (root) at /home/nahi/git/jruby/httpclient.rb:1 require at org/jruby/RubyKernel.java:1046 require at /home/nahi/git/jruby/httpclient.rb:29 (root) at httpclient.rb:1 1% mv httpclient.rb _httpclient.rb 0% jruby --1.9 _httpclient.rb HTTPClient 0% I don't think this difference is important. I think it's OK with the current behavior for 1.6GA.
        Hide
        Hiroshi Nakamura added a comment -

        Charles, I found that I don't understand the sentence you wrote to JRUBY-5526 'we have always included "." in CLASSPATH, like Java does.' But Java applications don't depend on CWD as well as CRuby >= 1.9.2, right? It's JRuby who adds "." in CLASSPATH as you explained at the top of this issue.

        CRuby 1.9.2 removed CWD dependency (2009-06-22 r23816) without adding a rational but I believe it's from concern about 'Untrusted search path vulnerability'. CRuby 1.9 provided 'require_relative' and trying to let user use it instead of CWD dependency. CRuby 1.8 didn't accept this change for compatibility I guess.

        I think JRuby 1.9 mode should remove "." from CLASSPATH as well as LOAD_PATH, like CRuby 1.9.2, mainly from security concern.

        Show
        Hiroshi Nakamura added a comment - Charles, I found that I don't understand the sentence you wrote to JRUBY-5526 'we have always included "." in CLASSPATH, like Java does.' But Java applications don't depend on CWD as well as CRuby >= 1.9.2, right? It's JRuby who adds "." in CLASSPATH as you explained at the top of this issue. CRuby 1.9.2 removed CWD dependency (2009-06-22 r23816) without adding a rational but I believe it's from concern about 'Untrusted search path vulnerability'. CRuby 1.9 provided 'require_relative' and trying to let user use it instead of CWD dependency. CRuby 1.8 didn't accept this change for compatibility I guess. I think JRuby 1.9 mode should remove "." from CLASSPATH as well as LOAD_PATH, like CRuby 1.9.2, mainly from security concern.
        Hide
        Charles Oliver Nutter added a comment -

        Java actually does include CWD if you don't specify a classpath:

        ~/projects/jruby &#10132; mirahc -e "puts 'hello, world'"
        
        ~/projects/jruby &#10132; ls -l DashE.class 
        -rw-r--r--  1 headius  staff  490 Mar  7 19:21 DashE.class
        
        ~/projects/jruby &#10132; java DashE
        hello, world
        
        ~/projects/jruby &#10132; java -cp lib/jruby.jar DashE
        Exception in thread "main" java.lang.NoClassDefFoundError: DashE
        Caused by: java.lang.ClassNotFoundException: DashE
        	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        	at java.security.AccessController.doPrivileged(Native Method)
        	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        
        ~/projects/jruby &#10132; java -cp lib/jruby.jar:. DashE
        hello, world
        
        ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar java DashE
        Exception in thread "main" java.lang.NoClassDefFoundError: DashE
        Caused by: java.lang.ClassNotFoundException: DashE
        	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        	at java.security.AccessController.doPrivileged(Native Method)
        	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        
        ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar:. java DashE
        hello, world
        

        We do have some logic in jruby-launcher and jruby.bash to detect when the user specifies a CLASSPATH, but I'm not sure if we should follow the CLASSPATH behavior, the LOAD_PATH behavior, or some hybrid of the two. If we follow the Java CLASSPATH behavior, the following should fail the second time:

        ~/projects/jruby &#10132; jruby -rjava -e "Java::DashE.main([].to_java(:string))"
        hello, world
        
        ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar jruby -rjava -e "Java::DashE.main([].to_java(:string))"
        hello, world
        

        Of course claspath and load path are two different things, but much of our work over the years has been moving JRuby toward unifying the two more seamlessly.

        So the basic problem, to sum up:

        • We always include . in CLASSPATH (Java only does if no CLASSPATH is specified in env var or -cp flag)
        • We search CLASSPATH for Ruby scripts, so we always see . (Ruby 1.9 does not include . in load path)

        If we do it the Java way, then . would still be in CLASSPATH if jruby is started without any additional CLASSPATH set. If we do it the Ruby way, then . could never be in CLASSPATH in 1.9 mode, since it would mean we would find scripts there (and we'd have to add --1.9 logic into jruby-launcher and jruby.bash, where there is none now).

        Show
        Charles Oliver Nutter added a comment - Java actually does include CWD if you don't specify a classpath: ~/projects/jruby &#10132; mirahc -e "puts 'hello, world'" ~/projects/jruby &#10132; ls -l DashE.class -rw-r--r-- 1 headius staff 490 Mar 7 19:21 DashE.class ~/projects/jruby &#10132; java DashE hello, world ~/projects/jruby &#10132; java -cp lib/jruby.jar DashE Exception in thread "main" java.lang.NoClassDefFoundError: DashE Caused by: java.lang.ClassNotFoundException: DashE at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) ~/projects/jruby &#10132; java -cp lib/jruby.jar:. DashE hello, world ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar java DashE Exception in thread "main" java.lang.NoClassDefFoundError: DashE Caused by: java.lang.ClassNotFoundException: DashE at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar:. java DashE hello, world We do have some logic in jruby-launcher and jruby.bash to detect when the user specifies a CLASSPATH, but I'm not sure if we should follow the CLASSPATH behavior, the LOAD_PATH behavior, or some hybrid of the two. If we follow the Java CLASSPATH behavior, the following should fail the second time: ~/projects/jruby &#10132; jruby -rjava -e "Java::DashE.main([].to_java(:string))" hello, world ~/projects/jruby &#10132; CLASSPATH=lib/jruby.jar jruby -rjava -e "Java::DashE.main([].to_java(:string))" hello, world Of course claspath and load path are two different things, but much of our work over the years has been moving JRuby toward unifying the two more seamlessly. So the basic problem, to sum up: We always include . in CLASSPATH (Java only does if no CLASSPATH is specified in env var or -cp flag) We search CLASSPATH for Ruby scripts, so we always see . (Ruby 1.9 does not include . in load path) If we do it the Java way, then . would still be in CLASSPATH if jruby is started without any additional CLASSPATH set. If we do it the Ruby way, then . could never be in CLASSPATH in 1.9 mode, since it would mean we would find scripts there (and we'd have to add --1.9 logic into jruby-launcher and jruby.bash, where there is none now).

          People

          • Assignee:
            Thomas E Enebo
            Reporter:
            Charles Oliver Nutter
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: