You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 Java HotSpot(TM) 64-Bit Server VM 25.92-b14 on 1.8.0_92-b14 +jit [darwin-x86_64]
OS X 10.10.5 – Darwin Kernel Version 14.5.0
and on
jruby 9.1.5.0 (2.3.1) 2016-09-07 036ce39 Java HotSpot(TM) Server VM 25.102-b14 on 1.8.0_102-b14 +jit [linux-i386]
Linux #1 SMP Fri Dec 11 14:03:26 EST 2015 i686 i686 i386 GNU/Linux
Expected Behavior
Child processes spawned from ruby with Kernel.system should not inherit any open sockets from parent ruby process. This is not true for sockets created with standard java methods like java.net.ServerSocket.
Actual Behavior
Child processes created by Kernel#system (and others like backticks, ..) inherit open sockets from parent process if they are created with standard java methods like java.net.ServerSocket.
This also applies to sockets created by some gems like trinidad or activerecord-jdbc-adapter.
Sockets created with ruby methods like TCPServer.new do not leak.
Example
require'socket'# ruby socket, does not leakserv=TCPServer.new("127.0.0.1",28561)Thread.new{loop{Thread.new{c=serv.accept;c.putsTime.now;c.close;}}}# java socket, does leakjsocket=Java::java.net.ServerSocket.new(22334)Thread.new{jsocket.accept}# show leaked socket in sub processsystem('echo $$; lsof -i -a -p $$',close_others: true);puts`echo $$; lsof -i -a -p $$`
Implications
Long running child processes that hold a handle to socket (and propably are sent to background), can stay alive and hinder another new process to bind to the now already taken port.
Demo
$ jruby -e 'jsocket = Java::java.net.ServerSocket.new(22334); Thread.new {jsocket.accept}; system("sleep 30 &")'# this one starts sleep with socket bound to 22334
$ jruby -e 'jsocket = Java::java.net.ServerSocket.new(22334); Thread.new {jsocket.accept}; system("sleep 30 &")'
Unhandled Java exception: java.net.BindException: Address already in use
java.net.BindException: Address already in use
socketBind at java/net/PlainSocketImpl.java:-2
bind at java/net/AbstractPlainSocketImpl.java:387
bind at java/net/ServerSocket.java:375
<init> at java/net/ServerSocket.java:237
<init> at java/net/ServerSocket.java:128
newInstance at java/lang/reflect/Constructor.java:423
newInstanceDirect at org/jruby/javasupport/JavaConstructor.java:278
newInstance at org/jruby/RubyClass.java:1001
call at org/jruby/RubyClass$INVOKER$i$newInstance.gen:-1
invokeOther5:new at -e:1
<main> at -e:1
invokeWithArguments at java/lang/invoke/MethodHandle.java:627
runScript at org/jruby/Ruby.java:834
runNormally at org/jruby/Ruby.java:749
runNormally at org/jruby/Ruby.java:767
runFromMain at org/jruby/Ruby.java:580
doRunFromMain at org/jruby/Main.java:425
internalRun at org/jruby/Main.java:313
run at org/jruby/Main.java:242
main at org/jruby/Main.java:204
The text was updated successfully, but these errors were encountered:
Environment
and on
Expected Behavior
Child processes spawned from ruby with Kernel.system should not inherit any open sockets from parent ruby process. This is not true for sockets created with standard java methods like java.net.ServerSocket.
Actual Behavior
Child processes created by Kernel#system (and others like backticks, ..) inherit open sockets from parent process if they are created with standard java methods like java.net.ServerSocket.
This also applies to sockets created by some gems like trinidad or activerecord-jdbc-adapter.
Sockets created with ruby methods like TCPServer.new do not leak.
Example
Implications
Long running child processes that hold a handle to socket (and propably are sent to background), can stay alive and hinder another new process to bind to the now already taken port.
Demo
The text was updated successfully, but these errors were encountered: