This is Part Two of a series of articles on Java.next. In Part Two, I will look at how Java.next languages interoperate with Java.Java interop is trivial in all of the Java.next languages. We have Java itself to thank for this–the Java Virtual Machine Specification makes it easy for other languages to reflect against and call Java code.A Swing exampleAs a first example, consider calling into the Java Swing API to create an application [1] that has a frame button a button handler that responds with a model dialog For starters, here is the application in plain old Java:<pre class="prettyprint"><code>// Java import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JOptionPane; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class Swing { public static void main(String[] args) { JFrame frame = new JFrame("Hello Swing"); JButton button = new JButton("Click Me"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { JOptionPane.showMessageDialog(null, String.format("<html>Hello from <b>Java</b> " + "Button %s pressed", event.getActionCommand())); } }); frame.getContentPane().add(button); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } } Below, I will present the same Swing application, ported to the Java.next languages. Please take note of two things about these examples: For this post, I am presenting the languages in order of increasing syntactic distance from Java. This makes sense for porting a simple example from the well-known to the increasingly unfamiliar. The ports below are not best practice in the Java.next languages. They are deliberately simplistic, so that I can focus on Java interop. In later installments of this series I will show more idiomatic Java.next code. Groovy Swing exampleGroovy is the Java.next language that looks most like Java. Here is the same example in Groovy: <pre class="prettyprint"><code>// Groovy import javax.swing.JFrame import javax.swing.JButton import javax.swing.JOptionPane import java.awt.event.ActionListener frame = new JFrame("Hello Swing") button = new JButton("Click Me") button.addActionListener({ JOptionPane.showMessageDialog(null, """<html>Hello from <b>Groovy</b> Button ${it.actionCommand} pressed""") } as ActionListener) frame.contentPane.add button frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE frame.pack() frame.visible = true If you compare this to the Java example, it is almost the same code, minus a bunch of unnecessary ceremony. The Groovy version lets us omit: semicolons type declarations most parentheses get and set for property access The most important benefit, however, comes in the action listener. The Groovy version sports a multiline string (delimited by “””) string interpolation of it.actionCommand (inside ${}) no need to write an anonymous inner class, simply pass an anonymous function For a more idiomatic approach to Swing in Groovy, see the Groovy SwingBuilder project. Since this post is about Java interop I will state the obvious: From Groovy, Java interop is entirely trivial.Scala Swing exampleNext, let’s look at the Scala version:<pre class="prettyprint"><code>// Scala (almost right, see below) import javax.swing._ import java.awt.event.{ActionEvent, ActionListener} object HelloWorld extends JFrame("Hello Swing") { def showButtonMessage(msg: String) = JOptionPane.showMessageDialog(null, String.format("""<html>Hello from <b>Scala</b>. Button %s pressed""", Array(msg))); def main(args: Array[String]) { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) val button = new JButton("Click Me") button.addActionListener((e:ActionEvent) => showButtonMessage(e.getActionCommand.toString)) getContentPane add button pack setVisible(true) } } The Scala version offers many of the same advantages over Java that the Groovy version provided: fewer type declarations than Java fewer semicolons fewer parentheses We also see a few items unique to Scala: In Scala, the import wildcard is _, not *. In Scala, * is a valid identifier. (Scala’s punctuation-friendly identifiers will be a big advantage later when I am writing DSLs.) Scala has an inline syntax for importing multiple classes in a package. Since we only need one, we declare an object instead of a class. Our object extends JFrame, and Scala lets us call the JFrame constructor inline, instead of having to declare a separate constructor. Again, the most important differences are in the action listener. Like Groovy, Scala lets us skip the anonymous inner class ritual, and simply pass a function:<pre class="prettyprint"><code>button.addActionListener((e:ActionEvent) => showButtonMessage(e.getActionCommand.toString)) That looks great, except I cheated a little. Scala’s implementation of strong typing won’t automatically coerce a function into an ActionListener, so the above code won’t compile out of the box. Fortunately, Scala’s implicit conversions let us have our cake and eat it too: strong typing plus much of the syntactic convenience of a looser type system. All we have to do is tell Scala the the conversion is legal: <pre class="prettyprint"><code>// Yes, we can implicit def actionPerformedWrapper(func: (ActionEvent) => Unit) = new ActionListener { def actionPerformed(e:ActionEvent) = func(e) } With this one-time setup in place, we can now pass a function where an ActionListener is expected. There seem to be several projects to wrap Swing in more idiomatic Scala. Using one of these libraries you should be able to get a syntax cleaner than the sample code here. See ScalaGUI for one example.From Scala, Java interop is trivial. JRuby Swing exampleLet’s see how JRuby fares:<pre class="prettyprint"><code>include Java import javax.swing.JFrame import javax.swing.JButton import javax.swing.JOptionPane import java.awt.event.ActionListener button = JButton.new "Click Me" button.add_action_listener do |evt| JOptionPane.showMessageDialog(nil, <<-END) <html>Hello from <b>JRuby</b>. Button '#{evt.getActionCommand()}' clicked. END end frame = JFrame.new "Hello Swing" frame.content_pane.add button frame.default_close_operation = JFrame::EXIT_ON_CLOSE frame.pack frame.visible = true If you compare this to the earlier Groovy example, you will see almost exactly the same feature set: fewer type declarations fewer semicolons fewer parentheses simplified property access (no get or set) a multiline string (delimited by END) string interpolation of evt.getActionCommand (the stuff inside #{}) The action listener callback is simplified in a fashion similar to the Groovy example. Ruby automatically generates the ActionListener from a block: <pre class="prettyprint"><code>button.add_action_listener { |evt| # do stuff } In the JRuby example I used Ruby conventions for method names, even on Java objects:<pre class="prettyprint"><code># Ruby frame.content_pane Java programmers expect camel case. As a convenience, JRuby supports both naming conventions: <pre class="prettyprint"><code># Groovy, Scala, or JRuby frame.contentPane Ruby’s flexibility has encouraged a lot of experimentation with alternate syntaxes for Java interop. See JRUBY-903 for some of the history. For a more idiomatic approach to Swing in JRuby, see the Profligacy project. From JRuby, Java interop is trivial.Clojure Swing exampleHere is the Clojure version:<pre class="prettyprint"><code>; Clojure ; Clojure (import '(javax.swing JFrame JButton JOptionPane)) (import '(java.awt.event ActionListener)) (let [frame (JFrame. "Hello Swing") button (JButton. "Click Me")] (.addActionListener button (proxy [ActionListener] [] (actionPerformed [evt] (JOptionPane/showMessageDialog nil, (str "<html>Hello from <b>Clojure</b>. Button " (.getActionCommand evt) " clicked."))))) (.. frame getContentPane (add button)) (doto frame (setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) pack (setVisible true))) Because Clojure is a Lisp, the syntax is radically different from the others. This deserves hours of discussion, or none. Since my focus here is on Java interop, I am going to save The Great Parenthesis Debate for a later entry in this series. For now, let us suspend judgment on syntax, and focus exclusively on the Java interop. Importing Java classes is easy. import takes a list. The first element of the list is a package, and the remaining elements are classes to add to the current namespace. Note that this allows the import of multiple classes in a single line.<pre class="prettyprint"><code>(import '(javax.swing JFrame JButton JOptionPane)) Creating a Java instance is easy. Use the (class. &args) form.<pre class="prettyprint"><code>(JFrame. "Hello Swing") There are multiple ways to call methods on a Java class. If you want to call a single method, you can use the (.methodName obj &args) form. For static calls, you can also use the (class/method &args) form: <pre class="prettyprint"><code>(JOptionPane/showMessageDialog nil "A message") Sometimes you want to chain multiple calls together. Where in Java you would say x.y().z(), in Clojure you can use the (.. x (y) (z)) form.<pre class="prettyprint"><code>(.. frame (getContentPane) (add button)) The last three method calls in our example are all on the same frame object. With Clojure’s doto form, you can perform multiple operations on an object without having to repeat the object each time.<pre class="prettyprint"><code>(doto frame (setDefaultCloseOperation JFrame/EXIT_ON_CLOSE) pack (setVisible true))) As with the other examples, the action listener is the most interesting part. In Clojure, proxy will dynamically create a Java instance [2], allowing you to implement interfaces and methods as needed. <pre class="prettyprint"><code>(proxy [ActionListener] [] (actionPerformed [evt] {do stuff here...})) As with JRuby, this solution is more general, and requires more syntax, than the Groovy approach. Also as with JRuby, you can easily roll your own syntax.From Clojure, Java interop is trivial.Try this at homeThe interop story in Java.next is almost boring: It Just Works. So to spice things up a little, here is an exercise in rolling your own constructs, inspired by the examples above. Consider Clojure’s import, which can import multiple Java classes in a single line of code. <pre class="prettyprint"><code>(import '(javax.swing JFrame JButton JOptionPane)) Why can’t this be even more general? Try your hand at writing a custom import function in one of the Java.next languages. Some useful features might be import all the classes in a JAR import all the classes in the intersection of a package and a JAR import only interfaces import all classes macthing some criteria import all classes except those matching some criteria Let me know what you come up with, and I will link to it here.ConclusionIn the examples above, I have demonstrated how all of the Java.next libraries can trivially interoperate with Java. Each of examples called the Swing library with fewer lines of code than the Java version. More importantly, the Java.next versions capture the essence of the program with less ceremony. Seamless interoperation with Java should not be the primary yardstick when measuring Java.next languages, because they all get it right. There are complexities and corner cases beyond what I have shown here, in all of the Java.next languages. But I consider the Java interop problem to be basically solved. In these first two articles, I have stayed fairly close to Java style while demonstrating Java.next language features. With that groundwork in place, it is time to start using idiomatic Java.next. In the next installment of the Java.next series, we will look at how the Java.next languages support Domain-Specific Languages.Notes This series is taken from the JVM Language Shootout talk. Check the schedule for a talk near you. Suggestions for improving the code samples above are most welcome. Thanks to Jason Rudolph, Glenn Vanderburg, and Greg Vaughn for reading an earlier draft of this article. Footnotes I took the Swing application example from the JRuby samples, and ported it to the other Java.next languages. Clojure’s proxy creates classes as necessary behind the scenes. In Java.next, the dichotomy of class and object is not constantly center stage. Revisions 2008/08/14. Updated Clojure example and prose per Rich Hickey‘s suggestion. Updated Groovy example to include pointer to SwingBuilder, per Andres Almiray. Updated JRuby example and prose based on suggestions from Nick Sieger and Ola Bini. Updated Scala example per Tony Morris’s suggestion. Thanks for all the improvements! Software Development