Adding flag to skip calling File.getCanonicalPath() on argv[0] during exec() #4746
+10
−2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.