Charles Oliver Nutter-2 wrote:
backspaces wrote:
>
> Charles Oliver Nutter-2 wrote:
>> backspaces wrote:
>>> In the jruby - dev forum I found:
>>> ...
>>> So two questions:
>>> 1 - Is the goal for JRuby to be able to have complete bi-directionality
>>> in
>>> terms of subclassing of Java classes? I.e. much the way quoted above?
>>> 2 - If so, does it currently work?
>> If by bi-directionality, you mean such subclasses are usable in both
>> Ruby and Java...yes, that is the intent. I believe it's *partially*
>> working, but this is going to be a big area of focus over the next
>> several months.
>>
> Yup, that's exactly my goal: I want to subclass a Java class within JRuby.
> The JRuby class will call the Java superclass methods for graphics
> primitives. And the Java superclass will call certain methods in the JRuby
> subclass for initialization and stepping the graphics through its animation.
> Specifically, the protocol is that the superclass will call two methods,
> setup() and draw() in the JRuby subclass.
That's good! We should support this. If we do not support it correctly
today, we need to work to support it, and that's what this next
development cycle is going to focus on. So any and all bugs you can feed
us about this type of integration will be very important and useful.
- Charlie
OK, I've done two tests: one a trivial check to see whether subclassing works the way I think it does, and a second actually using the Processing library. The first works fine, yeehaaa! That's wonderful news. The second fails on an exception that should be caught by the Processing code but somehow does not.
Here's the first test (note this was also discussed in the groovy forum where I found out that the groovy method signature needs to use "void" rather than "def").
First, I build a trivial java class with a setup method and a util method which simply prints a string. In addition, I add a method that simply calls this instance's setup method:
public class JavaClass {
public void setup() {
util("JavaClass: setup called.");
}
public void util(String s) {
System.out.println(s);
}
public void callSetup() {
this.setup();
}
}
I then build a java subclass overriding setup(), and include a main which lets me test it. The test creates an instance of JavaClass and an instance of the subclass. It then calls setup directly, and indirectly via callSetup:
public class JavaSubClass extends JavaClass {
public void setup() {
util("JavaSubClass: setup called.");
}
public static void main(String[] args) {
JavaClass jc = new JavaClass();
jc.setup();
jc.callSetup();
System.out.println("");
JavaSubClass jsc = new JavaSubClass();
jsc.setup();
jsc.callSetup();
}
}
When I run it, I get what you'd expect:
owen|~/src/jruby[1110]: java JavaSubClass
JavaClass: setup called.
JavaClass: setup called.
JavaSubClass: setup called.
JavaSubClass: setup called.
Next for the JRuby test:
require 'java'
include_class "JavaClass"
javaClass = JavaClass.new
javaClass.setup()
javaClass.callSetup()
class RubyClass < JavaClass
def setup()
util('RubyClass: setup called')
end
end
puts
rubyClass = RubyClass.new
rubyClass.setup()
rubyClass.callSetup()
.. which works just fine:
owen|~/src/jruby[1111]: jruby testjava.rb
JavaClass: setup called.
JavaClass: setup called.
RubyClass: setup called
RubyClass: setup called
I'll report in another post on the Processing problem. Briefly, however, it appears to be a problem with catching an exception within the PApplet code:
Applet.java:181:in `java.applet.Applet.getAppletContext': java.lang.NullPointerException: null (NativeException)
from null:-1:in `processing.core.PApplet$Proxy0.__super$getAppletContext'
from NativeMethodAccessorImpl.java:-2:in `sun.reflect.NativeMethodAccessorImpl.invoke0'
from NativeMethodAccessorImpl.java:39:in `sun.reflect.NativeMethodAccessorImpl.invoke'
from DelegatingMethodAccessorImpl.java:25:in `sun.reflect.DelegatingMethodAccessorImpl.invoke'
from Method.java:585:in `java.lang.reflect.Method.invoke'
from JavaMethod.java:204:in `org.jruby.javasupport.JavaMethod.invokeWithExceptionHandling'
..... and so on
Owen