jrubyjrubyonrails

Create a variable of interface type in jRuby


I was wondering how to create a variable of Interface type and instantiate a object with Implementing class in JRuby.

Currently in Java, we do something like

MyInterface intrf = new ConcreteClass();

How do I do the same in jRuby. I did below and it throws me error saying MyInterface method not found.

MyInterface intrf = ConcreteClass.new;


Solution

  • Firstly, MyInterface intrf = ConcreteClass.new is not valid Ruby. MyInterface is a constant (such as a constant reference to a class, although it could be a reference to any other type), not a type specifier for a reference - Ruby and hence JRuby is dynamically typed.

    Secondly, I assume you want to write a JRuby class ConcreteClass which implements the Java interface MyInterface, which – for example here – I'm saying is in the the Java package 'com.example'.

    require 'java'
    java_import 'com.example.MyInterface' 
    
    class ConcreteClass
      # Including a Java interface is the JRuby equivalent of Java's 'implements'
      include MyInterface
    
      # You now need to define methods which are equivalent to all of
      # the methods that the interface demands.
    
      # For example, let's say your interface defines a method
      #
      #   void someMethod(String someValue)
      #
      # You could implements this and map it to the interface method as
      # follows. Think of this as like an annotation on the Ruby method
      # that tells the JRuby run-time which Java method it should be
      # associated with.
      java_signature 'void someMethod(java.lang.String)'
      def some_method(some_value)
        # Do something with some_value
      end
    
      # Implement the other interface methods...
    end
    
    # You can now instantiate an object which implements the Java interface
    my_interface = ConcreteClass.new
    

    See the JRuby wiki for more details, in particular the page JRuby Reference.