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

File.utime failing with JRuby 9.1.16.0 #5075

Closed
bastien opened this Issue Mar 2, 2018 · 13 comments

Comments

Projects
None yet
3 participants
@bastien

bastien commented Mar 2, 2018

Environment

  • JRuby 9.1.16.0 (2.3.3) 2018-02-21
  • Java version "1.8.0_161"
  • Darwin Kernel Version 16.7.0: Thu Jan 11 22:59:40 PST 2018; root:xnu-3789.73.8~1/RELEASE_X86_64 x86_64

Expected Behavior

With jruby-9.1.15.0

irb > File.utime(Time.at(1420099200), Time.at(1420099200), "foo.txt")
=> 1

Actual Behavior

With jruby-9.1.16.0

irb > File.utime(Time.at(1420099200), Time.at(1420099200), "foo.txt")
NotImplementedError: utimensat unsupported or native support failed to load; see http://wiki.jruby.org/Native-Libraries
	from org/jruby/RubyFile.java:1162:in `utime'
	from (irb):2:in `<eval>'
	from org/jruby/RubyKernel.java:995:in `eval'
	from org/jruby/RubyKernel.java:1316:in `loop'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from /Users/bvaucher/.rbenv/versions/jruby-9.1.16.0/bin/irb:13:in `<main>'
@headius

This comment has been minimized.

Member

headius commented Mar 2, 2018

Hmm...seems to work ok on master. I'll poke around.

@enebo enebo added this to the JRuby 9.1.17.0 milestone Mar 6, 2018

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

Ok, I've confirmed this is also working on JRuby 9.1 HEAD (9.1.17.0) so I'm goin gto need more information here.

[] ~/projects/jruby $ jruby -e 'p File.utime(Time.at(1420099200), Time.at(1420099200), "foo.txt")'
1

[] ~/projects/jruby $ ls -la foo.txt 
-rw-r--r--  1 headius  staff  0 Jan  1  2015 foo.txt

Can you try running with -Xnative.verbose and provide that output?

Also can you confirm what version of OS X you are running on?

@bastien

This comment has been minimized.

bastien commented Mar 15, 2018

?> jruby -Xnative.verbose -e 'p File.utime(Time.at(1420099200), Time.at(1420099200), "foo.txt")'
Successfully loaded native POSIX impl.
NotImplementedError: utimensat unsupported or native support failed to load; see http://wiki.jruby.org/Native-Libraries
   utime at org/jruby/RubyFile.java:1162
  <main> at -e:1

?> ls -la foo.txt
-rw-r--r--  1 bvaucher  staff  0 Mar 15 20:43 foo.txt

And I'm on OSX 10.12.6

@bastien

This comment has been minimized.

bastien commented Mar 15, 2018

And as I was saying, if I switch back to 9.1.15, things work again 😕

?> rbenv local jruby-9.1.15.0
?> jruby -Xnative.verbose -e 'p File.utime(Time.at(1420099200), Time.at(1420099200), "foo.txt")'
Successfully loaded native POSIX impl.
1
@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

So the main thing that changed around this logic is that we're now using platform-specific functions to get the nanosecond granularity we want for filesystem times. This works properly on my OS X 10.13 machine, and it should work fine on your 10.12 machine.

I'll poke around a bit. It's odd that it can't find this function on your machine.

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

Can you try adding flag -Xbacktrace.style=full and provide the output please?

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

Oops...apparently this function is new in High Sierra: https://bugs.python.org/issue31601

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

The following patch probably fixes this, but it's not ideal (it continues trying to use the missing function):

diff --git a/core/src/main/java/org/jruby/RubyFile.java b/core/src/main/java/org/jruby/RubyFile.java
index 94b9e73879..fafb9245c3 100644
--- a/core/src/main/java/org/jruby/RubyFile.java
+++ b/core/src/main/java/org/jruby/RubyFile.java
@@ -42,6 +42,7 @@ import org.jcodings.Encoding;
 import org.jcodings.specific.UTF8Encoding;
 import org.jruby.anno.JRubyClass;
 import org.jruby.anno.JRubyMethod;
+import org.jruby.exceptions.RaiseException;
 import org.jruby.runtime.*;
 import org.jruby.runtime.JavaSites.FileSites;
 import org.jruby.runtime.builtin.IRubyObject;
@@ -1186,7 +1187,19 @@ public class RubyFile extends RubyIO implements EncodingCapable {
                 throw runtime.newErrnoENOENTError(filename.toString());
             }
 
-            int result = runtime.getPosix().utimensat(0, fileToTouch.getAbsolutePath(), atimespec, mtimespec, 0);
+            int result;
+
+            try {
+                result = runtime.getPosix().utimensat(0, fileToTouch.getAbsolutePath(), atimespec, mtimespec, 0);
+            } catch (RaiseException re) {
+                if (re.getException().getMetaClass() == runtime.getNotImplementedError()) {
+                    // fall back on utimes
+                    result = runtime.getPosix().utimes(fileToTouch.getAbsolutePath(), atimespec, mtimespec);
+                } else {
+                    throw re;
+                }
+            }
+
             if (result == -1) {
                 throw runtime.newErrnoFromInt(runtime.getPosix().errno());
             }
@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

@enebo Do you still have an OS X 10.12 machine you could test this on?

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

@bastien Here's your first workaround: update to High Sierra!

The only other workaround would be to reimplement (monkey patch) File.utimes in Ruby.

We should have a fix for this shortly.

@enebo

This comment has been minimized.

Member

enebo commented Mar 15, 2018

Patch works

@headius

This comment has been minimized.

Member

headius commented Mar 15, 2018

So we have confirmed this and we have an "ok" patch.

Remaining questions:

  • How many platforms does this affect? I traced utimensat back to at latest Linux 2.6.26 (2008) which seems fine, but FreeBSD only added this in 10.3 (2016) around the same time OS X did (and I suspect other BSDs.
  • On platforms it affects, how bad is the exception+fallback for overhead? Maybe you can try to test this for us a bit @bastien.

I will commit the patch for now.

@headius headius closed this in f32fb00 Mar 15, 2018

headius added a commit that referenced this issue Mar 15, 2018

headius added a commit that referenced this issue Mar 15, 2018

@bastien

This comment has been minimized.

bastien commented Mar 15, 2018

Nice work. I'll have a look at the patched version next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment