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

should not be able to instantiate an interface (using new) #3275

Closed
kares opened this issue Aug 23, 2015 · 8 comments
Closed

should not be able to instantiate an interface (using new) #3275

kares opened this issue Aug 23, 2015 · 8 comments

Comments

@kares
Copy link
Member

@kares kares commented Aug 23, 2015

... for what-ever reason Interface.new generates an anonymous class, currently :

kares@sputnik:~/workspace/oss/jruby-rack$ irb
jruby-9.0.0.0 :001 > java.lang.Runnable.new
 => #<#<Class:0x79714e09>:0x7dba6f28> 
jruby-9.0.0.0 :002 > java.lang.Runnable.new.class
 => #<Class:0x79714e09> 
jruby-9.0.0.0 :003 > java.lang.Runnable.new.class.name
 => nil 
@kares
Copy link
Member Author

@kares kares commented Mar 10, 2016

the idea is for interfaces to behave more closely to modules :

jruby-1.7.24 :001 > Enumerable.new
NoMethodError: undefined method `new' for Enumerable:Module
    from (irb):1:in `evaluate'
    from org/jruby/RubyKernel.java:1079:in `eval'
    from org/jruby/RubyKernel.java:1479:in `loop'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from /opt/local/rvm/rubies/jruby-1.7.24/bin/irb:13:in `(root)'

which they currently do not, although there might be some reasons for that (due the proxy machinery) :

jruby-1.7.24 :002 > java.lang.Runnable.new
 => #<#<Class:0x1e683a3e>:0x2053d869> 
jruby-1.7.24 :003 > java.lang.Runnable.new 42
ArgumentError: wrong number of arguments calling `initialize` (1 for 0)
    from org/jruby/java/proxies/JavaInterfaceTemplate.java:452:in `new'
    from (irb):3:in `evaluate'
    from org/jruby/RubyKernel.java:1079:in `eval'
    from org/jruby/RubyKernel.java:1479:in `loop'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from /opt/local/rvm/rubies/jruby-1.7.24/bin/irb:13:in `(root)'

jruby-1.7.24 :004 > runnable = java.lang.Runnable.new
 => #<#<Class:0x1e683a3e>:0x3d5c822d> 
jruby-1.7.24 :005 > runnable.run
NoMethodError: undefined method `run' for #<#<Class:0x1e683a3e>:0x3d5c822d>
    from (irb):5:in `evaluate'
    from org/jruby/RubyKernel.java:1079:in `eval'
    from org/jruby/RubyKernel.java:1479:in `loop'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from org/jruby/RubyKernel.java:1242:in `catch'
    from /opt/local/rvm/rubies/jruby-1.7.24/bin/irb:13:in `(root)'

... still its ugly and for generating a useful dynamic impl the impl method is used currently :

jruby-1.7.24 :013 >   runnable = java.lang.Runnable.impl { puts "#{self} #{__method__} running!" }
 => #<#<Class:0x63a12c68>:0x1b1426f4> 
jruby-1.7.24 :014 > runnable.run
main irb_binding running!
 => nil 
@Lan5432
Copy link
Contributor

@Lan5432 Lan5432 commented Mar 10, 2016

What bugs me is that Ruby doesn't clearly know what Runnable is once instantiated. If you try to instantiate another class Ruby knows where it is, but that hex code in the output, is that a normal thing to happen?

@kares
Copy link
Member Author

@kares kares commented Mar 10, 2016

its a generated anonymous proxy class - just like in Java (thus without a name).

@Lan5432
Copy link
Contributor

@Lan5432 Lan5432 commented Mar 18, 2016

Is "new" loaded as part of the InterfaceInitializer method loading? Maybe we're loading from a general implementation of Classes in said initializer

@Lan5432
Copy link
Contributor

@Lan5432 Lan5432 commented Mar 18, 2016

Ok, I think I made progress, fixing (or breaking my version even more), commenting unused method: "new_impl" (line: 442) in JavaInterfaceTemplate seems to work, yielding as a result:

2.2.1 :011 > java.lang.Runnable.new
NoMethodError: undefined method `new' for Java::JavaLang::Runnable:Module
        from (irb):11:in `<eval>'
        from org/jruby/RubyKernel.java:983:in `eval'
        from org/jruby/RubyKernel.java:1290:in `loop'
        from org/jruby/RubyKernel.java:1103:in `catch'
        from org/jruby/RubyKernel.java:1103:in `catch'
        from jirb:13:in `<top>'
2.2.1 :002 > JRUBY_VERSION
 => "9.1.0.0-SNAPSHOT" 

Though it shouldn't say "module"... so that is possibly a problem. This did not break object generation, as I tested with:

java.util.ArrayList.new
 => #<Java::JavaUtil::ArrayList:0xc3c60d> 
2.2.1 :004 > array = java.util.ArrayList.new
 => #<Java::JavaUtil::ArrayList:0x151f06e> 
2.2.1 :005 > array.add(5)
 => true 
2.2.1 :006 > puts array.get(0)
5
 => nil 

I'm not sure this did the job, but I think it's a step onwards

@enebo
Copy link
Member

@enebo enebo commented Mar 18, 2016

We could possibly make:

module Interface < Module
end

so it prints out nicer? Potential naming conflict since interface is a fairly common computery name:

module Java
  module Interface < Module
  end
end
@kares
Copy link
Member Author

@kares kares commented Mar 18, 2016

@Lan5432 it is simply re-using what Ruby Class/Module hierarchies do have. its semi correct since JRuby is trying to present Java interfaces as modules (they can get included). its nice to tune but I believe you would need to do that on multiple places where Ruby is expected to print info about a module.

Tom, has layout a simple plan if you're interested ... I personally would not pursuit this too much :)

unfortunately travis-ci is not 💚 at the moment but you could try to tun rake spec:ji rake test:jruby locally and maybe try adding a spec for this new behavior - no being able to Interface.new (similary to how you can not instantiate a "plain" Ruby module).

@Lan5432
Copy link
Contributor

@Lan5432 Lan5432 commented Mar 18, 2016

@kares Yeah, I guess modifying code to make it display in a nicer way is not one of the main worries of the project. I guess I can do that on extra time, just for the sake of it.

So you say adding a new spec to show this new characteristic. I can get to it to get familiar with creating specs.

What about the solution itself, can we incorporate this to the project itself? There might be other modifications of the code for this particular issue, so we should check if those are necessary for the issue to be solved.

@kares kares closed this in #3752 Apr 27, 2016
kares added a commit that referenced this issue Apr 27, 2016
Removing 'new' class method from interfaces #3275
@enebo enebo added this to the JRuby 9.1.0.0 milestone May 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants
You can’t perform that action at this time.