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

Adding flag to skip calling File.getCanonicalPath() on argv[0] during exec() #4746

Conversation

danielford
Copy link

We are running into an issue with JRuby due to the way ShellLauncher.java calls File.getCanonicalPath() on argv[0] during a call to Kernel#exec. Our company uses an in-house build-and-deploy framework that works by building a "symlink tree" that merges all of an application's dependencies (JRuby, gems, and many other things including non-Ruby dependencies) that make it look to the application as if all of its dependencies exist in a single directory structure, even though it is comprised of many packages located in separate folders on disk. We then use a custom executable in our shebang lines that walk up this tree in order to find their "environment root" in order to properly set LD_LIBRARY_PATH and many other environment variables needed at runtime.

The problem is that when our JRuby code needs to exec() another process (could be another JRuby script, or even something in a completely different language), calling File.getCanonicalPath() follows the symlinks in argv[0] to the actual location of the interpreter as opposed to its location in the symlink tree, and it is unable to find the environment root.

Here's a rough example to illustrate the issue (where /apps/foobar is the "environment root" for the application):
/apps/foobar/bin/jruby -> /packages/JRuby-x.x.x.x/bin/jruby
/apps/foobar/something/some-script.rb -> /packages/SomePackage-x.x.x.x/something/some-script.rb
/apps/foobar/lib/jruby.jar -> /packages/JRuby-x.x.x.x/lib/jruby.jar
/apps/foobar/lib/some-other-lib.jar -> /packages/SomeLibrary-x.x.x.x/lib/some-other-lib.jar
/apps/foobar/bin/python -> /packages/Python-x.x.x.x/bin/python
...etc...
/apps/foobar/.envroot is a special marker file that indicates an "environment root"

The shebang line for some-script.rb will use our special executable that will take argv[0] and keep walking up the tree until it finds the .envroot marker file, then will set some environment variables and then invoke JRuby (or whatever arguments are in the shebang line).

This works if argv[0] is /apps/foobar/something/some-script.rb because it will walk up the tree until it finds that /apps/foobar contains the marker file. However, if argv[0] is actually /packages/SomePackage/something/some-script.rb as a result of JRuby calling File.getCanonicalPath(), then our launcher can't find the environment root and fails to setup the environment properly.

This patch is an initial attempt to provide a configuration value that would let us disable this behavior without affecting the default behavior in JRuby. Of course I'm open to alternative ideas on how to implement this if anyone has a better idea.

This option allows disabling the behavior where ShellLauncher.java calls
File.getCanonicalPath() on argv[0] (which follows any symlinks).
@zendes
Copy link

zendes commented Aug 24, 2017

the two failing builds are both timeouts. are there any concerns with this patch, and if so what should we do to get it merged?

@enebo enebo requested review from headius and kares January 10, 2018 15:04
@enebo
Copy link
Member

enebo commented Jan 10, 2018

I added two people who will have an opinion on this. Part of me wrinkles my nose at another option so I am wondering if they won't come up with an alternate mechanism (I am not all that against the option but my memory of the various execs vs how our ShellLauncher works is dusty).

@kares
Copy link
Member

kares commented Jan 10, 2018

I don't like this one that much ... there was a thumbs down from me 😈

esp. supporting one "corner" case with a 'public' --option ... for a while
maybe having it turn on with a system property would make it somehow (subjectively) acceptable
(-Djruby.native.exec.canonicalize but not listed within props - till it makes sense for more folks)

considering @zendes and @danielford still need this ?

@danielford
Copy link
Author

Thanks for taking a look, but actually we don't need this anymore. Our root problem was fixed with another commit: 6e2088a

I'll close this out.

@danielford danielford closed this Jan 10, 2018
@enebo enebo added this to the Won't Fix milestone Jan 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants