Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception accessing file with long path on windows #3995

Open
ghost opened this issue Jul 4, 2016 · 11 comments
Open

Exception accessing file with long path on windows #3995

ghost opened this issue Jul 4, 2016 · 11 comments
Labels

Comments

@ghost
Copy link

ghost commented Jul 4, 2016

Environment

  • jruby 9.1.2.0 (2.3.0) 2016-05-26 7357c8f Java HotSpot(TM) 64-Bit Server VM 25.60-b23 on 1.8.0_60-b27 +jit [mswin32-x86_64]
  • Windows 7 64 bit

Fails also with:

  • jruby 9.0.1.0 (2.2.2) 2015-09-02 583f336 Java HotSpot(TM) 64-Bit Server VM 25.60-b23 on 1.8.0_60-b27 +jit [Windows 7-amd64]
  • ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32]

Works with:

  • jruby 1.4.1 (ruby 1.8.7 patchlevel 174) (2010-04-26 6586) (Java HotSpot(TM) 64-Bit Server VM 1.8.0_60) [amd64-java]

Expected Behavior

The length of a file name respectively its path shall shall support more than 260 characters.

See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath for more information.

Actual Behavior

When a script tries to access a file with a long path this exception is thrown:

C:/Projects/Head/Build/cm/testdir01/testdir02/testdir03/testdir04/testdir05/testdir06/testdir07/testdir08/testdir09/testdir10/testdir11/testdir12/testdir13/testdir14/testdir15/testdir16/testdir17/testdir18/testdir19/testdir20/testdir21/testdir22/longtestfile.name.txt
Errno::ESRCH: No such process - C:/Projects/Head/Build/cm/testdir01/testdir02/testdir03/testdir04/testdir05/testdir06/testdir07/testdir08/testdir09/testdir10/testdir11/testdir12/testdir13/testdir14/testdir15/testdir16/testdir17/testdir18/testdir19/testdir20/testdir21/testdir22/longtestfile.name.txt
stat at org/jruby/RubyFile.java:885
block in repro_lstat_exception.rb at repro_lstat_exception.rb:45
chdir at org/jruby/RubyDir.java:326
at repro_lstat_exception.rb:16

@ghost
Copy link
Author

ghost commented Jul 4, 2016

long_file_name_error.zip

Example code and a sample directory structure, producing the error above.

@enebo enebo added the windows label Jul 6, 2016
@enebo enebo added this to the JRuby 9.1.3.0 milestone Jul 6, 2016
@headius
Copy link
Member

headius commented Jul 11, 2016

Thank you for the repro. A couple notes.

  • Does MRI fail at the same depth? From your script it sounds like JRuby and MRI both get to 21 path segments and then fail.
  • Can you get a repro with -Xbacktrace.style=full? I don't have Windows handy today and that would give me a full JVM stack trace.

@enebo You worked on Windows stat stuff a few times...any ideas?

@ghost
Copy link
Author

ghost commented Jul 12, 2016

Yes, JRuby and MRI crashed at the same directory depth. As mentioned above, I believe it is related to a legacy MAX_PATH definition of 260 characters in windows. Longer path names needs to be handled differently.

This is full backtrace:

C:\Projects\Head\Build\cm>jruby -Xbacktrace.style=full repro_lstat_exception.rb
C:/Projects/Head/Build/cm/testdir01/testdir02/testdir03/testdir04/testdir05/testdir06/testdir07/testdir08/testdir09/testdir10/testdir11/testdir12/testdir13/testdir14/testdir15/testdir16/testdir17/testdir18/testdir19/testdir20/testdir21/testdir22/longtestfile.name.txt
Errno::ESRCH: No such process - C:/Projects/Head/Build/cm/testdir01/testdir02/testdir03/testdir04/testdir05/testdir06/testdir07/testdir08/testdir09/testdir10/testdir11/testdir12/testdir13/testdir14/testdir15/testdir16/testdir17/testdir18/testdir19/testdir20/testdir21/testdir22/longtestfile.name.txt
                      getStackTrace at java/lang/Thread.java:1552
                   getBacktraceData at org/jruby/runtime/backtrace/TraceType.java:183
                       getBacktrace at org/jruby/runtime/backtrace/TraceType.java:47
                   prepareBacktrace at org/jruby/RubyException.java:223
                           preRaise at org/jruby/exceptions/RaiseException.java:215
                           preRaise at org/jruby/exceptions/RaiseException.java:194
                             <init> at org/jruby/exceptions/RaiseException.java:110
                  newRaiseException at org/jruby/Ruby.java:4057
                    newErrnoFromInt at org/jruby/Ruby.java:3775
                              setup at org/jruby/RubyFileStat.java:140
                        newFileStat at org/jruby/RubyFileStat.java:100
                        newFileStat at org/jruby/Ruby.java:3430
                               stat at org/jruby/RubyFile.java:885
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:313
                               call at org/jruby/runtime/callsite/CachingCallSite.java:163
  block in repro_lstat_exception.rb at repro_lstat_exception.rb:42
                    commonYieldPath at org/jruby/runtime/CompiledIRBlockBody.java:70
                            doYield at org/jruby/runtime/IRBlockBody.java:140
                              yield at org/jruby/runtime/BlockBody.java:77
                              yield at org/jruby/runtime/Block.java:147
                              chdir at org/jruby/RubyDir.java:326
                               call at org/jruby/internal/runtime/methods/DynamicMethod.java:201
                       cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:323
                          callBlock at org/jruby/runtime/callsite/CachingCallSite.java:173
                               call at org/jruby/runtime/callsite/CachingCallSite.java:177
                              <top> at repro_lstat_exception.rb:13
                invokeWithArguments at java/lang/invoke/MethodHandle.java:627
                               load at org/jruby/ir/Compiler.java:111
                          runScript at org/jruby/Ruby.java:822
                          runScript at org/jruby/Ruby.java:814
                        runNormally at org/jruby/Ruby.java:752
                        runFromMain at org/jruby/Ruby.java:574
                      doRunFromMain at org/jruby/Main.java:409
                        internalRun at org/jruby/Main.java:304
                                run at org/jruby/Main.java:231
                               main at org/jruby/Main.java:200

@ghost
Copy link
Author

ghost commented Jul 12, 2016

This is the corresponding MRI bug: https://bugs.ruby-lang.org/issues/12551

@headius
Copy link
Member

headius commented Jul 12, 2016

@lbenner Ahh, thanks for the extra info and the MRI bug link.

We generally don't change functionality unilaterally, and I'm not sure how to fix this given that we're currently just using JDK features to navigate and manipulate paths. I'm inclined to see what ruby-core has to say about this one. If they come up with a solution (or you help us all come up with a solution) we'll see about getting it into JRuby.

@ghost
Copy link
Author

ghost commented Jul 12, 2016

I am only a little bit surprised, because it was working with jruby 1.4.1 (ruby 1.8.7 patchlevel 174) (2010-04-26 6586) (Java HotSpot(TM) 64-Bit Server VM 1.8.0_60) [amd64-java], using the same JVM. But the same applies to the old MRI version.

@enebo
Copy link
Member

enebo commented Jul 12, 2016

@lbenner This is pretty weird. I put a lot of effort in making long path support in the last 3-4 months. I even have a JUnit test for jnr-posix of a long path. I guess something is still not correct. MRI should also pass this. I am confused :)

@headius
Copy link
Member

headius commented Aug 11, 2016

I think we should punt this until MRI decides how they want to handle it.

@headius
Copy link
Member

headius commented May 15, 2018

No progress on MRI end. Detargeting.

@preetpalS
Copy link

I tested this on Windows 11 (I have long paths enabled in OS) and could not reproduce this issue. Accessing long paths works on both MRI and JRuby. I have a project folder with a node_modules folder in a nested folder which cannot be accessed unless you have long path support enabled in the OS and for your executable. For example, if you compile the file finding utility in this gist without enabling long path support, it will crash when searching that project folder. Using the Ruby script below on that folder will not crash.

Code used for testing (ran with jruby find_file.rb .*\.d$)

#!/usr/bin/env ruby

if __FILE__ == $PROGRAM_NAME
  if ARGV.length < 1
    puts "Only entered #{ARGV.length} arguments!"
    puts "Usage: #{ARGV[0]} wildcard"
    exit 1
  end

  require 'find'

  wildcard = Regexp.new(ARGV[0]).freeze

  Find.find('.') do |path|
    if FileTest.file?(path)
      if wildcard.match?(path)
        puts path
      end
    end
  end
end

Ruby versions tested:

C:\Users\myuser\Projects>ruby -v
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x64-mingw-ucrt]

C:\Users\myuser\Projects>jruby -v
jruby 9.4.0.0 (3.1.0) 2022-11-23 95c0ec159f OpenJDK 64-Bit Server VM 11.0.12+7 on 11.0.12+7 +jit [x86_64-mswin32]

Example path printed: ./RailsProject/RailsProject/rails_project/node_modules/bootswatch/docs/3/node_modules/fsevents/build/Release/.deps/Users/eshanker/Code/fsevents/lib/binding/Release/node-v48-darwin-x64/fse.node.d

This issue should be closed.

@preetpalS
Copy link

preetpalS commented Nov 29, 2022

No progress on MRI end. Detargeting.

@headius, @enebo MRI handles long paths now on Windows. See this merged pull request. They enabled long path support via an application manifest which changes the behavior of Windows API calls (by removing MAX_PATH restrictions). Since long paths are working in JRuby this issue should be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants
@headius @enebo @preetpalS and others