Skip to content
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

NoMethodError thrown which returns false for error.is_a?(Exception) #3359

Closed
naag opened this issue Sep 28, 2015 · 6 comments
Closed

NoMethodError thrown which returns false for error.is_a?(Exception) #3359

naag opened this issue Sep 28, 2015 · 6 comments

Comments

@naag
Copy link

naag commented Sep 28, 2015

We have a problem with JRuby 9.0.1.0 on OpenJDK 8 in combination with Bunny gem (v 2.2.0). Due to other issues, JRuby raises a NoMethodError when Bunny tries to connect to the RabbitMQ host. For some reason that error returns false for error.is_a?(Exception) and is thus not detected properly by Bunny. The same code works flawlessly on MRI 2.1.6. It seems that there are two distinct classes Exception. Should this ever happen?

We have built a minimal example for this issue based on Docker, which you can find here: https://github.com/pressrelations/jruby-exceptions.

To run it, just use the following (in case you have Docker installed):

docker build -t jruby-exceptions .
docker run jruby-exceptions "./fails.rb"
docker run jruby-exceptions "./works.rb"

Otherwise, bundle install and then run fails.rb or works.rb. works.rb includes a monkey patch to Bunny which also catches NoMethodError specifically and fixes the issue.

FYI: There still remains a second issue: why is the error raised in the first place? We're likely going to open a 2nd issue for that on Bunny, but if you have any idea on that, we'd be glad to hear it.

@naag
Copy link
Author

naag commented Sep 28, 2015

Some more detailed information:

root@4a44870574b7:/usr/src/app# gem list

*** LOCAL GEMS ***

amq-protocol (2.0.0)
bundler (1.10.6)
bunny (2.2.0)
jar-dependencies (0.1.15)
jruby-openssl (0.9.11 java)
json (1.8.0 java)
minitest (5.4.1)
power_assert (0.2.3)
psych (2.0.15 java)
rake (10.1.0)
rdoc (4.1.0)
ruby-maven (3.3.3)
ruby-maven-libs (3.3.3)
test-unit (3.0.3)
root@4a44870574b7:/usr/src/app# ruby --version
jruby 9.0.1.0 (2.2.2) 2015-09-02 583f336 OpenJDK 64-Bit Server VM 25.66-b01 on 1.8.0_66-internal-b01 +jit [linux-amd64]
root@4a44870574b7:/usr/src/app# 
root@4a44870574b7:/usr/src/app# dpkg -l openjdk-8-j*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                                       Version                    Architecture               Description
+++-==========================================-==========================-==========================-=========================================================================================
ii  openjdk-8-jdk:amd64                        8u66-b01-1~bpo8+1          amd64                      OpenJDK Development Kit (JDK)
ii  openjdk-8-jre:amd64                        8u66-b01-1~bpo8+1          amd64                      OpenJDK Java runtime, using Hotspot JIT
ii  openjdk-8-jre-headless:amd64               8u66-b01-1~bpo8+1          amd64                      OpenJDK Java runtime, using Hotspot JIT (headless)

I also updated the example in our repo to print a backtrace of the NoMethodError.

$ docker run jruby-exceptions "./fails.rb"
NoMethodError
/usr/local/bundle/gems/bunny-2.2.0/lib/bunny/transport.rb:279:in `initialize_socket'
/usr/local/bundle/gems/bunny-2.2.0/lib/bunny/transport.rb:291:in `maybe_initialize_socket'
/usr/local/bundle/gems/bunny-2.2.0/lib/bunny/session.rb:287:in `start'
./works.rb:7:in `<top>'
W, [2015-09-28T19:43:16.926000 #1]  WARN -- #<Bunny::Session:0xfa4 guest@127.0.0.1:5672, vhost=/, addresses=[127.0.0.1:5672]>: Could not establish TCP connection to 127.0.0.1:5672: private method `open' called for Bunny::JRuby::Socket:Module
Bunny::TCPConnectionFailedForAllHosts: Could not establish TCP connection to any of the configured hosts
  start at /usr/local/bundle/gems/bunny-2.2.0/lib/bunny/session.rb:315
  <top> at ./works.rb:7
$ docker run bunny-bug "./fails.rb"
W, [2015-09-28T19:43:57.699000 #1]  WARN -- #<Bunny::Session:0xfa4 guest@127.0.0.1:5672, vhost=/, addresses=[127.0.0.1:5672]>: Could not establish TCP connection to 127.0.0.1:5672: 
Bunny::TCPConnectionFailedForAllHosts: Could not establish TCP connection to any of the configured hosts
  start at /usr/local/bundle/gems/bunny-2.2.0/lib/bunny/session.rb:315
  <top> at ./fails.rb:6

Since I'm afraid I didn't make myself clear in the first post: one issue is the "private method" error (not sure if that should be raised or not), but the bigger issue is the fact that the raised error NoMethodError doesn't classify as an Exception. Only by adding this to Bunny can we catch the exception:

$ git diff
diff --git a/lib/bunny/exceptions.rb b/lib/bunny/exceptions.rb
index 74e50db..fcae0c7 100644
--- a/lib/bunny/exceptions.rb
+++ b/lib/bunny/exceptions.rb
@@ -69,7 +69,7 @@ module Bunny
       m = case e
           when String then
             e
-          when Exception then
+          when Exception, NoMethodError then
             e.message
           end
       if hostname && port

Hopefully this makes it clearer. Otherwise I'd be happy to provide more details!

@enebo enebo added this to the JRuby 9.0.2.0 milestone Sep 30, 2015
@headius
Copy link
Member

headius commented Oct 7, 2015

Is it possible that your Exception here ends up referring to java.lang.Exception? You might not notice it if for some reason this context imported java.lang.Exception and was attempting to use it for this case.

I will try to reproduce but your example is a bit complicated.

@headius
Copy link
Member

headius commented Oct 7, 2015

I don't really know how to use docker and was unable to run your reproduction. I guess I only have a docker "client" installed? Do I need to run your example on Linux or will it work on OS X?

Perhaps you can pop by #jruby on Freenode IRC today?

@headius
Copy link
Member

headius commented Oct 7, 2015

Moving to 9.0.3 because I don't know how to reproduce yet.

@headius
Copy link
Member

headius commented Oct 7, 2015

Ok, after discussion on IRC we determined that both the NoMethodError and the Exception mismatch are probably bugs in Bunny. We recommended that @naag file issues with the Bunny project and link us here.

Marking this as invalid. Thanks for helping us investigate, @naag!

@naag
Copy link
Author

naag commented Oct 8, 2015

Thanks again @headius and @enebo! Your support on IRC makes me feel all warm and cozy :-) I've now created a PR and an issue over at https://github.com/ruby-amqp/bunny:

ruby-amqp/bunny#355 (to check for the right Exception class)
ruby-amqp/bunny#356 (to fix the underlying private method call error)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants