-
-
Notifications
You must be signed in to change notification settings - Fork 942
Description
JMX fails to bind when running bundle exec.
system ~/projects/jruby $ cat blah.rb
#!/usr/bin/env jruby
system ~/projects/jruby $ JRUBY_OPTS="-J-Dcom.sun.management.jmxremote -J-Dcom.sun.management.jmxremote.authenticate=false -J-Dcom.sun.management.jmxremote.ssl=false -J-Dcom.sun.management.jmxremote.port=1100 --server" jruby -S bundle exec ./blah.rb
file:/Users/headius/projects/jruby/lib/jruby.jar!/jruby/kernel/kernel.rb:25 warning: unsupported exec option: close_others
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 1100; nested exception is:
java.net.BindException: Address already in use
Bundler's "bundle exec" basically loads up your gemfile, prepares the appropriate library versions, and then re-starts JRuby with those libraries, using exec. Exec on JRuby does a real native exec, replacing the parent process with the new one. However, because the JVM does not set socket descriptors CLOEXEC, the JMX socket bound in the initial launch of JRuby remains bound in the replaced process, causing the second JRuby/JVM instance to fail to bind.
In order to fix this, we need to set sockets to be CLOEXEC. That requires native access to fcntl(2), but so does the real native exec.
A workaround for this may be to use the -G flag, which boots up Bundler's gemfile before starting up RubyGems.
Reported by @polysics on IRC.