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

UDPSocket.new(Socket::AF_INET6) throws exception (JRuby 9.1.14.0) #4869

Closed
jordansissel opened this Issue Nov 27, 2017 · 13 comments

Comments

Projects
None yet
2 participants
@jordansissel
Contributor

jordansissel commented Nov 27, 2017

Environment

Provide at least:

  • JRuby version: 9.1.14.0
  • Operating system and platform (e.g. uname -a): Linux xyz 4.13.12-300.fc27.x86_64 #1 SMP Wed Nov 8 16:38:01 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

The example reproduction works correctly in JRuby 9.1.13.0

Expected Behavior

  • Describe your expectation of how JRuby should behave, perhaps by showing how CRuby/MRI behaves.

Creating a UDPSocket for IPv6 throws a Java exception.

  • Provide an executable Ruby script or a link to an example repository.
% ruby --version
jruby 9.1.14.0 (2.3.3) 2017-11-08 2176f24 OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]

% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
<crashes w/ exception>

Actual Behavior

  • Describe or show the actual behavior.
% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
Unhandled Java exception: java.lang.UnsupportedOperationException: IPv6 not available
java.lang.UnsupportedOperationException: IPv6 not available
               <init> at sun/nio/ch/DatagramChannelImpl.java:138
  openDatagramChannel at sun/nio/ch/SelectorProviderImpl.java:46
                 open at java/nio/channels/DatagramChannel.java:182
           initialize at org/jruby/ext/socket/RubyUDPSocket.java:126
           initialize at org/jruby/ext/socket/RubyUDPSocket.java:116
                 call at org/jruby/ext/socket/RubyUDPSocket$INVOKER$i$initialize.gen:-1
                 call at org/jruby/internal/runtime/methods/JavaMethod.java:739
         cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:278
                 call at org/jruby/runtime/callsite/CachingCallSite.java:79
          newInstance at org/jruby/RubyClass.java:1022
          newInstance at org/jruby/RubyIO.java:875
                 call at org/jruby/RubyIO$INVOKER$s$0$0$newInstance.gen:-1
                 call at org/jruby/internal/runtime/methods/DynamicMethod.java:204
                 call at org/jruby/internal/runtime/methods/DynamicMethod.java:200
         cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:318
                 call at org/jruby/runtime/callsite/CachingCallSite.java:155
     invokeOther0:new at -e:1
               <main> at -e:1
  invokeWithArguments at java/lang/invoke/MethodHandle.java:627
                 load at org/jruby/ir/Compiler.java:95
            runScript at org/jruby/Ruby.java:828
          runNormally at org/jruby/Ruby.java:747
          runNormally at org/jruby/Ruby.java:765
          runFromMain at org/jruby/Ruby.java:578
        doRunFromMain at org/jruby/Main.java:417
          internalRun at org/jruby/Main.java:305
                  run at org/jruby/Main.java:232
                 main at org/jruby/Main.java:204

jordansissel added a commit to elastic/logstash that referenced this issue Nov 27, 2017

Revert "Upgrade to JRuby 9.1.14.0"
This reverts commit d38e4ff.
(Original commit was part of
#8620)

The revert is due to `UDPSocket.new(Socket::AF_INET)` crashing in
9.1.14.0:

* #8736
* jruby/jruby#4869

elasticsearch-bot pushed a commit to elastic/logstash that referenced this issue Nov 27, 2017

Revert "Upgrade to JRuby 9.1.14.0"
This reverts commit d38e4ff.
(Original commit was part of
#8620)

The revert is due to `UDPSocket.new(Socket::AF_INET)` crashing in
9.1.14.0:

* #8736
* jruby/jruby#4869

Fixes #8738

elasticsearch-bot pushed a commit to elastic/logstash that referenced this issue Nov 27, 2017

Revert "Upgrade to JRuby 9.1.14.0"
This reverts commit d38e4ff.
(Original commit was part of
#8620)

The revert is due to `UDPSocket.new(Socket::AF_INET)` crashing in
9.1.14.0:

* #8736
* jruby/jruby#4869

Fixes #8738

elasticsearch-bot pushed a commit to elastic/logstash that referenced this issue Nov 27, 2017

Revert "Upgrade to JRuby 9.1.14.0"
This reverts commit d38e4ff.
(Original commit was part of
#8620)

The revert is due to `UDPSocket.new(Socket::AF_INET)` crashing in
9.1.14.0:

* #8736
* jruby/jruby#4869

Fixes #8738
@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 27, 2017

Member

This error appears to be coming from the JDK. Does IPv6 UDP work from Java?

Member

headius commented Nov 27, 2017

This error appears to be coming from the JDK. Does IPv6 UDP work from Java?

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

The JDK lines are pretty straightforward...seems like IPv6 is just not available. But you say it works in 9.1.13, so that's very confusing.

https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/nio/ch/DatagramChannelImpl.java#L137-L139

We should handle that error better, obviously. I'll fix that now.

No theories as to why IPv6 suddenly is unavailable in 9.1.14.0 :-( It really doesn't seem like something we could do.

Member

headius commented Nov 28, 2017

The JDK lines are pretty straightforward...seems like IPv6 is just not available. But you say it works in 9.1.13, so that's very confusing.

https://github.com/frohoff/jdk8u-jdk/blob/master/src/share/classes/sun/nio/ch/DatagramChannelImpl.java#L137-L139

We should handle that error better, obviously. I'll fix that now.

No theories as to why IPv6 suddenly is unavailable in 9.1.14.0 :-( It really doesn't seem like something we could do.

headius added a commit that referenced this issue Nov 28, 2017

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

Ok, I can reproduce it if I tell the JDK to prefer IPv4. Perhaps you are setting this in some environment, or otherwise unsetting it for 9.1.13?

(This is with the new error)

$ jruby -J-Djava.net.preferIPv4Stack=true -rsocket -e "UDPSocket.new(Socket::AF_INET6)"
Errno::EAFNOSUPPORT: Address family not supported by protocol family - socket(2) - udp
  initialize at org/jruby/ext/socket/RubyUDPSocket.java:134
  initialize at org/jruby/ext/socket/RubyUDPSocket.java:116
         new at org/jruby/RubyIO.java:877
      <main> at -e:1
Member

headius commented Nov 28, 2017

Ok, I can reproduce it if I tell the JDK to prefer IPv4. Perhaps you are setting this in some environment, or otherwise unsetting it for 9.1.13?

(This is with the new error)

$ jruby -J-Djava.net.preferIPv4Stack=true -rsocket -e "UDPSocket.new(Socket::AF_INET6)"
Errno::EAFNOSUPPORT: Address family not supported by protocol family - socket(2) - udp
  initialize at org/jruby/ext/socket/RubyUDPSocket.java:134
  initialize at org/jruby/ext/socket/RubyUDPSocket.java:116
         new at org/jruby/RubyIO.java:877
      <main> at -e:1

@headius headius added this to the JRuby 9.1.15.0 milestone Nov 28, 2017

@headius headius added the stdlib label Nov 28, 2017

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

FWIW I did not find this property in either our bash script or or native launcher.

It might be getting set in some CI environments to avoid issues with IPv4/IPv6 address resolution (JDK tended to prefer IPv6 for binding while MRI preferred IPv4).

Member

headius commented Nov 28, 2017

FWIW I did not find this property in either our bash script or or native launcher.

It might be getting set in some CI environments to avoid issues with IPv4/IPv6 address resolution (JDK tended to prefer IPv6 for binding while MRI preferred IPv4).

@jordansissel

This comment has been minimized.

Show comment
Hide comment
@jordansissel

jordansissel Nov 28, 2017

Contributor

Nothing I can tell -- I am using rbenv, and from the same shell:

% rbenv shell jruby-9.1.14.0
% ruby --version
jruby 9.1.14.0 (2.3.3) 2017-11-08 2176f24 OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]

% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
Unhandled Java exception: java.lang.UnsupportedOperationException: IPv6 not available
...

% rbenv shell jruby-9.1.13.0
% ruby --version
jruby 9.1.13.0 (2.3.3) 2017-09-06 8e1c115 OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]
% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
<no output, successful exit>

If I throw in a sleep so I can check the java args with jps sleep 10; UDPSocket.new(Socket:AF_INET6), I show the following:

  • Jruby 9.1.14.0
239720 Main -Djdk.home= -Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.14.0 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/arm-Linux -Xmx500m -Xss2048k -Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jruby.jar -Djava.security.egd=file:/dev/urandom
  • JRuby 9.1.13.0
239895 Main -Djdk.home= -Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.13.0 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/arm-Linux -Xmx500m -Xss2048k -Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jruby.jar

For easier viewing, here's a diff of the arguments (sorted):

--- /tmp/jps.13 2017-11-27 19:59:58.496754680 -0800
+++ /tmp/jps.14 2017-11-27 20:00:01.386075726 -0800
@@ -1,9 +1,10 @@
+-Djava.security.egd=file:/dev/urandom
 -Djdk.home=
--Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/arm-Linux
--Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.13.0
+-Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/arm-Linux
+-Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.14.0
 -Djruby.script=jruby
 -Djruby.shell=/bin/sh
 Main
--Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jruby.jar
+-Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jruby.jar
 -Xmx500m
 -Xss2048k
Contributor

jordansissel commented Nov 28, 2017

Nothing I can tell -- I am using rbenv, and from the same shell:

% rbenv shell jruby-9.1.14.0
% ruby --version
jruby 9.1.14.0 (2.3.3) 2017-11-08 2176f24 OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]

% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
Unhandled Java exception: java.lang.UnsupportedOperationException: IPv6 not available
...

% rbenv shell jruby-9.1.13.0
% ruby --version
jruby 9.1.13.0 (2.3.3) 2017-09-06 8e1c115 OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]
% ruby -rsocket -e 'UDPSocket.new(Socket::AF_INET6)'
<no output, successful exit>

If I throw in a sleep so I can check the java args with jps sleep 10; UDPSocket.new(Socket:AF_INET6), I show the following:

  • Jruby 9.1.14.0
239720 Main -Djdk.home= -Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.14.0 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/arm-Linux -Xmx500m -Xss2048k -Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jruby.jar -Djava.security.egd=file:/dev/urandom
  • JRuby 9.1.13.0
239895 Main -Djdk.home= -Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.13.0 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/arm-Linux -Xmx500m -Xss2048k -Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jruby.jar

For easier viewing, here's a diff of the arguments (sorted):

--- /tmp/jps.13 2017-11-27 19:59:58.496754680 -0800
+++ /tmp/jps.14 2017-11-27 20:00:01.386075726 -0800
@@ -1,9 +1,10 @@
+-Djava.security.egd=file:/dev/urandom
 -Djdk.home=
--Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jni/arm-Linux
--Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.13.0
+-Djffi.boot.library.path=/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/sparcv9-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64le-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/aarch64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/x86_64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/ppc64-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/i386-Linux:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jni/arm-Linux
+-Djruby.home=/home/jls/.rbenv/versions/jruby-9.1.14.0
 -Djruby.script=jruby
 -Djruby.shell=/bin/sh
 Main
--Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.13.0/lib/jruby.jar
+-Xbootclasspath/a:/home/jls/.rbenv/versions/jruby-9.1.14.0/lib/jruby.jar
 -Xmx500m
 -Xss2048k
@jordansissel

This comment has been minimized.

Show comment
Hide comment
@jordansissel

jordansissel Nov 28, 2017

Contributor
# JRuby 9.1.13.0
>> java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)
=> #<Java::JavaNet::DatagramSocket:0x6aaceffd>

#JRuby 9.1.14.0
>> java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)
Java::JavaNet::SocketException: Protocol family unavailable

Fascinating! Inet6 really seems disabled somehow ... strace shows this for the given java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first) code:

# 9.1.14.0
[pid 240525] socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 17
[pid 240525] setsockopt(17, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
[pid 240525] setsockopt(17, SOL_IP, IP_MULTICAST_ALL, [0], 4) = 0

# 9.1.13.0
[pid 241108] socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP) = 6
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
[pid 241108] setsockopt(6, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_RECVPKTINFO, [0], 4) = 0
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_MULTICAST_HOPS, [1], 4) = 0
Contributor

jordansissel commented Nov 28, 2017

# JRuby 9.1.13.0
>> java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)
=> #<Java::JavaNet::DatagramSocket:0x6aaceffd>

#JRuby 9.1.14.0
>> java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)
Java::JavaNet::SocketException: Protocol family unavailable

Fascinating! Inet6 really seems disabled somehow ... strace shows this for the given java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first) code:

# 9.1.14.0
[pid 240525] socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 17
[pid 240525] setsockopt(17, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
[pid 240525] setsockopt(17, SOL_IP, IP_MULTICAST_ALL, [0], 4) = 0

# 9.1.13.0
[pid 241108] socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP) = 6
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_V6ONLY, [0], 4) = 0
[pid 241108] setsockopt(6, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_RECVPKTINFO, [0], 4) = 0
[pid 241108] setsockopt(6, SOL_IPV6, IPV6_MULTICAST_HOPS, [1], 4) = 0
@jordansissel

This comment has been minimized.

Show comment
Hide comment
@jordansissel

jordansissel Nov 28, 2017

Contributor
% rbenv shell jruby-9.1.14.0
% ruby  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true
% rbenv shell jruby-9.1.13.0
% ruby  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true

I'm going to close this since it is clear my system has preferIPv4 enabled, but honestly I have no idea how. If I find the reason and if that reason is mysterious, I'll post it here for posterity, but I don't think this is a JRuby bug at this time.

From Java directly, System.out.println(System.getProperty("java.net.preferIPv4Stack")) prints null, not true as it does in my ruby tests... this is wild.

Contributor

jordansissel commented Nov 28, 2017

% rbenv shell jruby-9.1.14.0
% ruby  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true
% rbenv shell jruby-9.1.13.0
% ruby  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true

I'm going to close this since it is clear my system has preferIPv4 enabled, but honestly I have no idea how. If I find the reason and if that reason is mysterious, I'll post it here for posterity, but I don't think this is a JRuby bug at this time.

From Java directly, System.out.println(System.getProperty("java.net.preferIPv4Stack")) prints null, not true as it does in my ruby tests... this is wild.

@jordansissel

This comment has been minimized.

Show comment
Hide comment
@jordansissel

jordansissel Nov 28, 2017

Contributor

I tested on a fresh docker image ubuntu and downloaded JRuby 9.1.14.0 to reproduce it

% docker run -it ubuntu bash -li
...
root@14a33df15475:/# apt-get update
...
root@14a33df15475:/# apt-get install openjdk-8-jre-headless
...
root@14a33df15475:/# apt-get install wget
...
root@14a33df15475:/# wget https://repo1.maven.org/maven2/org/jruby/jruby-complete/9.1.14.0/jruby-complete-9.1.14.0.jar
...
root@14a33df15475:/# java -jar jruby-complete-9.1.14.0.jar  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true
root@14a33df15475:/# java -jar jruby-complete-9.1.14.0.jar -e 'java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)'
Unhandled Java exception: java.net.SocketException: Protocol family unavailable
Contributor

jordansissel commented Nov 28, 2017

I tested on a fresh docker image ubuntu and downloaded JRuby 9.1.14.0 to reproduce it

% docker run -it ubuntu bash -li
...
root@14a33df15475:/# apt-get update
...
root@14a33df15475:/# apt-get install openjdk-8-jre-headless
...
root@14a33df15475:/# apt-get install wget
...
root@14a33df15475:/# wget https://repo1.maven.org/maven2/org/jruby/jruby-complete/9.1.14.0/jruby-complete-9.1.14.0.jar
...
root@14a33df15475:/# java -jar jruby-complete-9.1.14.0.jar  -e 'puts java.lang.System.getProperty("java.net.preferIPv4Stack")'
true
root@14a33df15475:/# java -jar jruby-complete-9.1.14.0.jar -e 'java.net.DatagramSocket.new(8888, java.net.InetAddress.getAllByName("::1").first)'
Unhandled Java exception: java.net.SocketException: Protocol family unavailable
@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

@jordansissel Of course I should have grepped JRuby source as well. I discovered 691bf16 meant to address #775, and this does indeed attempt to set the related Java property to prefer IPv4.

Given this, my current theory is that some library or core change to JRuby in 9.1.14.0 has now allowed this setting to actually take effect when it wasn't before. For example, a newer RubyGems may not need to activate the socket library, allowing our settings to kick in before the JDK's socket subsystem boots. This could be the changes I did for JDK9 to defer some reflection until needed.

Member

headius commented Nov 28, 2017

@jordansissel Of course I should have grepped JRuby source as well. I discovered 691bf16 meant to address #775, and this does indeed attempt to set the related Java property to prefer IPv4.

Given this, my current theory is that some library or core change to JRuby in 9.1.14.0 has now allowed this setting to actually take effect when it wasn't before. For example, a newer RubyGems may not need to activate the socket library, allowing our settings to kick in before the JDK's socket subsystem boots. This could be the changes I did for JDK9 to defer some reflection until needed.

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

If my theory plays out, then this IPv4-forcing has not been working consistently anyway, and we may as well eliminate the configurable setting.

Member

headius commented Nov 28, 2017

If my theory plays out, then this IPv4-forcing has not been working consistently anyway, and we may as well eliminate the configurable setting.

@jordansissel

This comment has been minimized.

Show comment
Hide comment
@jordansissel

jordansissel Nov 28, 2017

Contributor

Of course I should have grepped JRuby source as well

haha, this was the last place I expected to find the answer, fwiw. I spent a bit of time chasing down rbenv, fedora global java settings, jdk source code, etc. It was a good adventure for me! :)

I can at least confirm that in Java, when preferIPv4Stack=true, UDP on IPV6 fails:

% java U
java.net.preferIPv4Stack: null
Socket: java.net.DatagramSocket@4e25154f

% java -Djava.net.preferIPv4Stack=true U
java.net.preferIPv4Stack: true
Exception in thread "main" java.net.SocketException: Protocol family unavailable

I think your theory makes sense. My gut says that y'all fixed some things in 9.1.14.0 that accidentally enabled this feature that was (for years!) intended to have this effect.

Let me know if I can help further. I'm open to sending a patch also, if you want to spread that load. I am also happy to test any patches if I am not authoring.

Contributor

jordansissel commented Nov 28, 2017

Of course I should have grepped JRuby source as well

haha, this was the last place I expected to find the answer, fwiw. I spent a bit of time chasing down rbenv, fedora global java settings, jdk source code, etc. It was a good adventure for me! :)

I can at least confirm that in Java, when preferIPv4Stack=true, UDP on IPV6 fails:

% java U
java.net.preferIPv4Stack: null
Socket: java.net.DatagramSocket@4e25154f

% java -Djava.net.preferIPv4Stack=true U
java.net.preferIPv4Stack: true
Exception in thread "main" java.net.SocketException: Protocol family unavailable

I think your theory makes sense. My gut says that y'all fixed some things in 9.1.14.0 that accidentally enabled this feature that was (for years!) intended to have this effect.

Let me know if I can help further. I'm open to sending a patch also, if you want to spread that load. I am also happy to test any patches if I am not authoring.

@headius

This comment has been minimized.

Show comment
Hide comment
@headius

headius Nov 28, 2017

Member

It's possible the feature did work originally, but as time went on it became less of a concern. In any case, I think it may be better to just relegate this setting to JAVA_OPTS and remove it from our properties.

Member

headius commented Nov 28, 2017

It's possible the feature did work originally, but as time went on it became less of a concern. In any case, I think it may be better to just relegate this setting to JAVA_OPTS and remove it from our properties.

@headius

This comment has been minimized.

Show comment
Hide comment
@headius
Member

headius commented Nov 28, 2017

@headius headius closed this in d55cd48 Nov 29, 2017

insukcho added a commit to insukcho/logstash that referenced this issue Feb 1, 2018

Revert "Upgrade to JRuby 9.1.14.0"
This reverts commit d38e4ff.
(Original commit was part of
elastic#8620)

The revert is due to `UDPSocket.new(Socket::AF_INET)` crashing in
9.1.14.0:

* elastic#8736
* jruby/jruby#4869

Fixes elastic#8738
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment