Skip to content

JMX tries to double-bind a port when using bundle exec #1859

@headius

Description

@headius

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions