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

Comments

Projects
None yet
3 participants
@kares
Member

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

This comment has been minimized.

Show comment
Hide comment
@kares

kares Mar 10, 2016

Member

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 
Member

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

This comment has been minimized.

Show comment
Hide comment
@Lan5432

Lan5432 Mar 10, 2016

Contributor

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?

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@kares

kares Mar 10, 2016

Member

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

Member

kares commented Mar 10, 2016

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

@Lan5432

This comment has been minimized.

Show comment
Hide comment
@Lan5432

Lan5432 Mar 18, 2016

Contributor

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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@Lan5432

Lan5432 Mar 18, 2016

Contributor

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

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@enebo

enebo Mar 18, 2016

Member

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
Member

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

This comment has been minimized.

Show comment
Hide comment
@kares

kares Mar 18, 2016

Member

@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).

Member

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

This comment has been minimized.

Show comment
Hide comment
@Lan5432

Lan5432 Mar 18, 2016

Contributor

@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.

Contributor

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

Merge pull request #3752 from Lan5432/master
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