Porting a .java to a .rb to learn both Java and JRuby

Hiya List,

In my previous e-mail I described how I want to use JRuby to learn
Java (in order to used a kewl Java-API).

Also I expressed some thoughts about how I can mentally relate the
Java package declaration to my way of doing things in Ruby.

This Java-API comes with a sample program.

In order to get-good with this API, I’ll try to “port” the sample
program to JRuby.

It is an exercise designed to flow some knowledge into my brain.

So, here is the first bit of syntax I want to port to JRuby:

/*

  • Main.java

*/

package TestJavaClient;

import java.awt.Component;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class Main {

// This method is called to start the application
public static void main (String args[]) {
    SampleFrame sampleFrame = new SampleFrame();
    sampleFrame.setVisible(true);
}

static public void inform( final Component parent, final String str) 

{
if( SwingUtilities.isEventDispatchThread() ) {
showMsg( parent, str, JOptionPane.INFORMATION_MESSAGE);
}
else {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
showMsg( parent, str, JOptionPane.INFORMATION_MESSAGE);
}
});
}
}

static private void showMsg( Component parent, String str, int type) 

{
// this function pops up a dlg box displaying a message
JOptionPane.showMessageDialog( parent, str, “IB Java Test
Client”, type);
}
}

If it looks ugly in your e-mail I put a copy in pastie.org:

http://pastie.org/1080616

So, again, my aim is to port the above Main.java file into main.rb

The first line I see is this:

package TestJavaClient;

I’m tempted to ignore it but perhaps I will eventually morph it into a
Ruby-module declaration.

The next 3 lines are easy to port:

import java.awt.Component;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

They become this:

#!/usr/bin/env jruby

main.rb

require ‘java’

include_class java.awt.Component
include_class javax.swing.JOptionPane
include_class javax.swing.SwingUtilities

Next, I am looking at this Java code:

public class Main {

// This method is called to start the application
public static void main (String args[]) {
    SampleFrame sampleFrame = new SampleFrame();
    sampleFrame.setVisible(true);
}

}

Perhaps a proper port of that Java code to JRuby would be this:

#!/usr/bin/env jruby

main.rb

require ‘java’

include_class java.awt.Component
include_class javax.swing.JOptionPane
include_class javax.swing.SwingUtilities

class Main
def main(args= nil)
sample_frame = SampleFrame.new
sample_frame.set_visible(true)
end
end

??

I tried running it on my Mac and it ran error free.

During the 1 second that it ran it popped up a little-white-coffee-cup
in my doc.

I think I starting to scratch the surface of this problem.

Here is the next bit of code I want to port:

static public void inform( final Component parent, final String str) 

{

  // java code here
}

I have no idea what the “final” declarations do in the argument list
but I am tempted to ignore them.

Perhaps this would do it:

def inform(parent, str)
# JRuby code here
end

??

Thoughts anyone?


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Fri, Aug 6, 2010 at 6:31 PM, Audrey L. [email protected]
wrote:

The first line I see is this:

package TestJavaClient;

I’m tempted to ignore it but perhaps I will eventually morph it into a
Ruby-module declaration.

Packaging them in a module seems like a good facsimile for Java
packages.

main.rb

Perhaps a proper port of that Java code to JRuby would be this:
 def main(args= nil)
  sample_frame = SampleFrame.new
  sample_frame.set_visible(true)
 end
end

??

Java always puts everything in classes because there is no “toplevel”
space like in Ruby. With Ruby scripts, the script body itself is
basically like a small piece of the program’s “main” method. So you
could also write the above as:


include_class javax.swing.SwingUtilities

sample_frame = SampleFrame.new
sample_frame.set_visible(true)

In order to be a bit more directly like Java, you might do it this way:

class Main
def self.main(*args) # note self.main
sample_frame = SampleFrame.new
sample_frame.set_visible(true)
end
end

Main.main

Note that I used “self.main” to define the “main” method directly on
the “Main” class. This is a bit closer in structure to the “static”
main method from the Java example.

I tried running it on my Mac and it ran error free.

During the 1 second that it ran it popped up a little-white-coffee-cup
in my doc.

That was likely just Swing starting up the windowing logic for that
JVM process. If you were to actually call Main.main as I show above,
you would see the window itself pop up and the JVM would also start up
the Swing event-handling thread.

I have no idea what the “final” declarations do in the argument list
but I am tempted to ignore them.

Perhaps this would do it:

 def inform(parent, str)
  # JRuby code here
 end

Normally, “final” variables in Java code are declared such so that
they can be used in anonymous inner classes, like the “new Runnable()
{” part in your original example. If you were to port that body of
code to Ruby, it might look like this (and note that I’m using the
more “rubyish” names for several methods here like
“isEventDispatchThread” => “event_dispatch_thread?”):

def self.inform(parent, str)
if SwingUtilities.event_dispatch_thread?
show_msg parent, str, JOptionPane::INFORMATION_MESSAGE
else
SwingUtilities.invoke_later {
show_msg parent, str, JOptionPane.INFORMATION_MESSAGE
}
end
end

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

Hello List,

I offer big thanks to Charlie for pointing me in the right direction.

I think I’m making good progress at learning Java by interacting with
JRuby.

I uploaded the code I am working with to github if anyone wants to look
at it:

The Java file I want to ‘port’ to JRuby is here:

The current state of my main.rb file is here:

When I run the above file I see this:

Sun Aug 08 16:47 /pt/trading/api/IBJts/java maco$ jruby main.rb
main.rb:15:in new_proxy': no public constructors for SampleFrame (TypeError) from main.rb:15:in main’
from main.rb:32
Sun Aug 08 16:47 /pt/trading/api/IBJts/java maco$

The first obvious question I have is:

  1. Which “layer” of software is giving me this error? JRuby? Or the
    Java underneath?

I typed this into Google:

http://www.google.com/search?q=JRuby+no+public+constructors+(TypeError)

Most of the resulting content made little sense to me.

I did pick up a sense that a “public constructor” is a Java thing.

This search seemed to validate that:

http://www.google.com/search?hl=en&q=Java+public+constructor

Also, this search also indicates to me that a “public constructor” is
a Java thing.

http://www.google.com/search?hl=en&q=Ruby+public+constructor

Next, I looked at the file SampleFrame.java to see if I could make sense
of it:

I don’t know Java (yet) but I do see an obvious class declaration:

class SampleFrame extends JFrame implements EWrapper

Next, I went looking for a method which looks like a constructor.

In Ruby I look for a method named initialize() which is entered when I
call new().

This Java class, SampleFrame, does not have an initialize() method but
I do see a method called ‘SampleFrame()’.

I turned to Google:

http://www.google.com/search?hl=en&q=how+do+I+construct+a+class+in+java

The above search verifies to me that the constructor of the class
SampleFrame is SampleFrame().

So, I found the constructor for SampleFrame and now the obvious question
is:

“How do I ask/tell/force JRuby to use it?”

On 8/7/10, Charles Oliver N. [email protected] wrote:

main.rb

Perhaps a proper port of that Java code to JRuby would be this:
def main(args= nil)
could also write the above as:
def self.main(*args) # note self.main

the Swing event-handling thread.

they can be used in anonymous inner classes, like the "new Runnable()
show_msg parent, str, JOptionPane.INFORMATION_MESSAGE


To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email

On Sun, Aug 8, 2010 at 7:29 PM, Audrey L. [email protected]
wrote:

    from main.rb:32
Sun Aug 08 16:47 /pt/trading/api/IBJts/java maco$

SampleFrame does have a constructor, but it’s not public.

In Java, unless you specify “public SampleFrame()” the constructor
will be what’s called “package visible”. In other words, only other
classes within that package can access that constructor (or method, or
field, etc). Adding “public” to the constructor would make it work.

We usually try to make methods that aren’t public visible to Ruby
code, since sometimes the Ruby code really ought to be able to call
the target code. In this case, it appears we are not making
constructors visible, so that would qualify as an inconsistency in
JRuby (i.e. a bug) that could be filed and fixed. I’ve filed it here:
http://jira.codehaus.org/browse/JRUBY-5009

  • Charlie

To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email