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

Warning: "singleton on non-persistent Java type" with JRuby 1.7.4 #3

Open
dvgica opened this issue Oct 4, 2013 · 7 comments
Open

Comments

@dvgica
Copy link

dvgica commented Oct 4, 2013

Hi,

I'm using mocha (and thus, this gem) on a JRuby 1.7.4 project which uses some Java classes.

It appears that line 4 of object_methods.rb triggers the following warning:

~/.rvm/gems/jruby-1.7.4@project/gems/metaclass-0.0.1/lib/metaclass/object_methods.rb:4 warning: singleton on non-persistent Java type Java::User (http://wiki.jruby.org/Persistence)

I did read the JRuby wiki about this: https://github.com/jruby/jruby/wiki/Persistence. But I'm not terribly sure what can be done in metaclass, if anything.

Any ideas? I don't think it's super-critical, but something to be aware of, perhaps.

Thanks!

/cc @kopchickm @karlj-spindance

@floehopper
Copy link
Owner

I can't seem to reproduce the warning. Here's what I've tried:

# jruby-warning.rb
require 'bundler/setup'
require 'metaclass'

p java.lang.String.__metaclass__
$ ruby -v
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.6.0_31-b04-413-12C60 [darwin-x86_64]

$ ruby -w jruby-warning.rb
#<Class:Java::JavaLang::String>

If this really is a problem, we could (a) detect JRuby within the #__metaclass__ method and set __persistent__ to true as per the wiki; or (b) try to supress this specific warning somehow.

@floehopper
Copy link
Owner

To be honest. Given that Object#singleton_class has been added to Ruby since v1.9.2 [1], I suspect Mocha can start using that and this whole gem can go away soon!

[1] http://ruby-doc.org/core-1.9.2/Object.html#method-i-singleton_class

@dvgica
Copy link
Author

dvgica commented Oct 16, 2013

Thanks for looking into this. I was able to reproduce the issue by slightly modifying your test script:

require 'rubygems' # didn't use Bundler
require 'metaclass'

p java.lang.String.new("test").__metaclass__

Results in:

$ ruby -w jruby-warning.rb 
/home/davidv/.rvm/gems/jruby-1.7.4/gems/metaclass-0.0.1/lib/metaclass/object_methods.rb:4 warning: singleton on non-persistent Java type Java::JavaLang::String (http://wiki.jruby.org/Persistence)
#<Class:#<Java::JavaLang::String:0x3bd54235>>

Ruby version:

$ ruby -v
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.7.0_40-b43 +indy [linux-amd64]

@floehopper
Copy link
Owner

Hmm. This seems to be more fundamental than I first thought. Setting __persistent__ to true on the first line of #__metaclass__ doesn't solve the problem. And even calling Object#singleton_class (i.e. nothing to do with the metaclass gem) without setting __persistent__ to true generates a warning:

p java.lang.String.new("test").singleton_class
$ ruby -w jruby-warning.rb
jruby-warning.rb:5 warning: singleton on non-persistent Java type Java::JavaLang::String (http://wiki.jruby.org/Persistence)
#<Class:#<Java::JavaLang::String:0x2904b5ae>>

I'm not sure I can see a way around this other than explicitly setting __persistent__ to true for the relevant Java class yourself.

java.lang.String.__persistent__ = true
p java.lang.String.new("test").singleton_class
$ ruby -w jruby-warning.rb
#<Class:#<Java::JavaLang::String:0x6153e0c0>>

Personally I think I'd be tempted to try to avoid stubbing the Java class directly - perhaps by wrapping it in some kind of Ruby adaptor class. Sorry - I hope that helps.

@dvgica
Copy link
Author

dvgica commented Oct 16, 2013

That does help, thanks.

I did manage to set __persistent__ in #__metaclass__. I'm not sure how my way is different than yours, but it did seem to work (I just monkeypatched Metaclass::ObjectMethods right in jruby-warning.rb:

module Metaclass::ObjectMethods
  def __metaclass__
    self.class.__persistent__ = true
    class << self
      self
    end
  end
end

Digging deeper, it looks like we have this issue for another gem besides metaclass (https://github.com/apotonick/representable).

So it seems that setting __persistent__ is really the only option... I'm just not sure whether it's more appropriate to do it in the gem (as above), or in my application. Maybe @headius could weigh in here?

@floehopper
Copy link
Owner

Oh. Cool. I'm not sure what I was doing (have deleted it), but whatever it was it was wrong!

In order to come up with a better solution, I think we'd need to look in detail at how Mocha is using the singleton class and see whether we could store state in a different data structure as per the alternatives section on the JRuby wiki page.

@floehopper
Copy link
Owner

I think we ought to be able to use RUBY_PLATFORM == 'java' to decide whether or not to set __persistent__ to true.

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

No branches or pull requests

2 participants