Search code examples
jrubyfxml

JRuby class & Java baseclass: making private java methods available to child


I have a JRuby child class with a Java parent class. I need to override the Java function so that when it is called my JRuby method implementation is called first. The problem is that the java method is private. Any ideas?*

// Java:
public class JavaClass {
     private void check(String what) {
          System.out.println(what);
     }
}

# JRuby:
class RubyClass < JavaClass
  def check() # => private above.  any way to force it public
    super("RubyClass.check was called first")
  end
end

*I am aware that this is not generally a good idea. I'm trying to get FXMLLoader to work in JRuby without wholesale reimplementation.


Solution

  • you can call the private method (using Java's reflection) ... but you won't be able to make it public on the original Java class (just on the JRuby side) and thus you can not call it using super ... here's a sample :

    >> big_int = Java::JavaMath::BigInteger.new '42'
    => #<Java::JavaMath::BigInteger:0x787faefa>
    >> big_int.signInt
    NoMethodError: undefined method `signInt' for #<Java::JavaMath::BigInteger:0x787faefa>
                   from (irb):6:in `evaluate'
    

    now let's do some Java reflection to invoke the (Java) private signInt method :

    class Java::JavaMath::BigInteger
      def sign_int
        signInt = java_class.declared_method :signInt
        signInt.accessible = true
        signInt.invoke(self)
      end
    end
    

    and try again :

    >> big_int.sign_int
    => 0