Is it possible to override a method in a Java class

Hey all.

Is it possible, in a JRuby app, to override a method in a Java class?

For example, given a Java class com.foo.Bar that has some method m, I
want to change the behavior of m.

I know I can do this in a subclass, but I want to alter the behavior of
the Java class itself.

Thanks,

James B.

Neurogami - Avant-garage Research & Development

[email protected]

Yes, I did this:

com.myco.MyClass.class_eval do
alias :real_myMethod :myMethod
def myMethod *args
# do stuff
real_myMethod *args
# do other stuff
end
end

and it seemed to work. jruby 1.7.0 jdk7u11

-Dave

aside:
I used this approach to display the ruby call stack when a java
exception was thrown inside the method. The code I wrote looks like:

def myMethod *args
begin
real_myMethod *args
rescue Exception
puts ‘exception caught in method execution - dumping ruby call
stack’
caller.each do |st|
puts st
end
raise
end
end

Please let me know if you have any comments or suggestions for
improvement

This might not work, as real_myMethod will not only invoke by Ruby code,
it also can be invoked inside Java code too.

Lei G.

From: Dave L. [email protected]
To: [email protected]
Sent: Saturday, January 26, 2013 10:59 AM
Subject: Re: [jruby-user] Is it possible to override a method in a Java
class

Yes, I did this:

com.myco.MyClass.class_eval do
alias :real_myMethod :myMethod
def myMethod *args

do stuff

real_myMethod *args

do other stuff

end
end

and it seemed to work. jruby 1.7.0 jdk7u11

-Dave

aside:
I used this approach to display the ruby call stack when a java
exception was thrown inside the method. The code I wrote looks like:

def myMethod *args
begin
real_myMethod *args
rescue Exception
puts ‘exception caught in method execution - dumping ruby call stack’
caller.each do |st|
puts st
end
raise
end
end

Please let me know if you have any comments or suggestions for
improvement
On Saturday, January 26, 2013 at 10:24 AM, James B. wrote:
Hey all.

Dave -

I’m surprised that the modifications you made worked. I suspect that
JRuby added a wrapper class around the Java class, and modified that
wrapper.
I’m pretty sure that class modifications of a Java class in Ruby code
would be seen only on the Ruby side.

Given that it did work, though, I suspect that the Java class accessed
in Java code would ignore the modifications.

It should be pretty easy to put together a test, but I don’t have time
at the moment.

  • Keith

Keith R. Bennett

Yes, I did not need the modifications to work when the original java
method was called from java code. I only needed them to be in place when
the method was called from jruby code. Since the original request
mentioned “in a JRuby app”, I thought my approach might help.

-Dave

Dave -

I’m surprised that the modifications you made worked. I suspect that
JRuby added a wrapper class around the Java class, and modified that
wrapper.
I’m pretty sure that class modifications of a Java class in Ruby code
would be seen only on the Ruby side.

Given that it did work, though, I suspect that the Java class accessed
in Java code would ignore the modifications.

It should be pretty easy to put together a test, but I don’t have time
at the moment.

  • Keith

Keith R. Bennett

Dave -

On Jan 26, 2013, at 6:23 PM, Dave L. [email protected]
wrote:

Yes, I did not need the modifications to work when the original java method was
called from java code. I only needed them to be in place when the method was
called from jruby code.

Oh, I see.

Since the original request mentioned “in a JRuby app”, I thought my approach
might help.

Yes, hopefully it would. However, “a JRuby app” can make heavy use of
Java libraries that use callbacks. For example, my “Game of Life
Viewer” (article:
http://www.bbs-software.com/blog/2012/09/05/conways-game-of-life-viewer/,
code: GitHub - keithrbennett/life_game_viewer) is a JRuby app
that uses Java Swing for the GUI framework. Swing makes heavy use of
callbacks.

So that’s an example of a JRuby app in which the
directly-modify-Java-class approach would not work (I don’t think),
whereas the subclass-Java-class approach would. Pretty cool what you did
though.

Thanks,
Keith

Keith B. wrote:

that uses Java Swing for the GUI framework. Swing makes heavy use of
callbacks.

So that’s an example of a JRuby app in which the
directly-modify-Java-class approach would not work (I don’t think),
whereas the subclass-Java-class approach would. Pretty cool what you did
though.

Thanks very much for these answers.

I spent more time looking into this, adding yet more proof that the
surest way to solve a problem is to post a question about it because
inevitable (well, maybe) one then figures it out.

Turns out that i was not able to get my code to work at first because I
was not correctly addressing the class of interest. Instead I was
creating a new class; the intended target of this code was unaware.

Once I was able to refer to the correct class I did this:

 class Java::ComLeapmotionLeap::Frame
   alias_method :leap_hands, :hands

   def hands
     hands = leap_hands
     # My own nefarious code here
     # ...
   end

 end

In actual use a Frame object (created by third-party Java code) is
passed to a callback method (onFrame) that has to be defined in a
Listener class that handles the callback. In my JRuby app that class
is sub-classed from a Java class. The objects (and sub-objects) it gets
passed though can be already modified with whatever enhancements I see
fit. Which, of course, is very cool.

Thanks again!

James

Dave -

On Jan 26, 2013, at 6:23 PM, Dave L. [email protected]
wrote:

Yes, I did not need the modifications to work when the original java method was
called from java code. I only needed them to be in place when the method was
called from jruby code.

Oh, I see.

Since the original request mentioned “in a JRuby app”, I thought my approach
might help.

Yes, hopefully it would. However, “a JRuby app” can make heavy use of
Java libraries that use callbacks. For example, my “Game of Life
Viewer” (article:
http://www.bbs-software.com/blog/2012/09/05/conways-game-of-life-viewer/,
code: GitHub - keithrbennett/life_game_viewer) is a JRuby app
that uses Java Swing for the GUI framework. Swing makes heavy use of
callbacks.

So that’s an example of a JRuby app in which the
directly-modify-Java-class approach would not work (I don’t think),
whereas the subclass-Java-class approach would. Pretty cool what you did
though.

Thanks,
Keith