07 Feb 2012, 15:00
Generic-user-small

Hans-Joerg von Mettenheim (1 post)

For example when dealing with Eclipse rcp applications one may encounter the following Java code to implement a view:

package org.mypackage;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;


public class MyView extends ViewPart {

	public MyView() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub
		Text text = new Text(parent, SWT.BORDER);
		text.setText("My UI here...");
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}

When I use the Ruby translation

class MyView < org.eclipse.ui.part.ViewPart
  # method definitions here
end

the compiled java class ends up extending RubyObject, like all(?!) compiled JRuby classes.

The challenge here is that MyView will be instantiated and called by the rcp framework. And the framework expects a class that extends ViewPart (and not RubyObject).

A simple though not elegant solution is to write a Java wrapper that will instantiate a Ruby class and delegate the relevant calls to this class. The Java wrapper is boilerplate code and could even be autogenerated. I’m wondering: how do other people translate the @extends@ keyword to JRuby when the subclass is instantiated and used by the Java side?

Thanks, Hans-Joerg

07 Feb 2012, 20:58
Mr_sketchy_pragsmall

Ian Dees (195 posts)

Hello, Hans-Joerg.

Inheriting from an arbitrary class is tough to do with the compiler; I’ll ask my co-authors to chime in here if they’re aware of a way.

With the interpreter, though, there’s a happier story. With the following in @Base.java@:

public class Base {
    public int magic() {
        return 0; // no magic :-(
    }
}

…and the following in @derived.rb@:

require 'java'

class Derived < Java::Base
  def magic
    42
  end
end

…then the following program is able to create instances of the derived Ruby object and cast them to the Java base class:

import org.jruby.embed.ScriptingContainer;

public class Program {
    public static void main(String[] args) {
        ScriptingContainer ruby = new ScriptingContainer();

        Base o = (Base)ruby.runScriptlet("require 'derived'; Derived.new");
        System.out.println(o.magic());
    }
}

So perhaps it’s possible to create a minimal Java wrapper that does the construction using the above technique, but doesn’t require any forwarding for the actual methods. I’m not sure how feasible this is with RCP applications.

Reports of using JRuby to build Eclipse (or at least SWT) apps are mixed. On the one hand, there’s the Glimmer library for SWT apps. On the other hand, there’s an RCP case study where the implementers kept the top-level GUI bits in Java, and used JRuby for the application logic.

–Ian

07 Sep 2013, 21:50
Generic-user-small

Thomas Kane (1 post)

Had the same issue at MMAWorkout.us , thanks for clearing things up Ian.

  You must be logged in to comment