Dwins’s Weblog


You Don’t Need Java to use the JVM

Posted in Open Source Software by dwins on November 30, 2009
Tags: , , , , ,

Not too long ago I was looking for a decent web application framework for an application we’re working on at OpenGeo. It’s based on GeoServer and maybe some other Java servers, but the team expressed some concerns about being able to quickly turn around and maintain Java code. So I checked out some alternative JVM languages during my search. Here are my thoughts on the ones I looked at, Jython, Rhino, Groovy, and Scala.

Jython

Jython is an implementation of Python that runs on the JVM. It lets you call Java constructors and methods, as well as extend Java classes and interfaces, and it even maps bean properties to keyword arguments on constructors.  However, the interoperability is not entirely seamless in either direction.  When using overloaded Java methods from Python code, the method is selected on the runtime type of the arguments (nulls are especially troublesome here.)  The recommended way to work around this seems to be just to perform the appropriate conversions manually (not particularly problematic.)  In the other direction, things are a bit more of a hassle: since the Python code is not compiled, classes defined in Python do not exist until the script has been run (and disappear once the JVM exits.)  So, there’s a fair bit of boilerplate required to get a hold of an instance of a Python class, and integration with frameworks that rely on reflection (such as Spring) will require even more (a wrapper class to create the Python object and then delegate to its methods).  Additionally, the base types (String, Integer, etc.) used in Python scripts are not the standard Java classes, so occasionally there is an impedance mismatch due to that.  (The interpreter automatically wraps and unwraps the objects so most of the time it is not a problem.)

Rhino

Rhino is an implementation of JavaScript that runs on the JVM. It also allows you to call Java constructors and methods and extend Java classes and interfaces.  There is also some nice sugar:

  • bean properties are mapped to simple properties in JavaScript code (obj.foo = “new value”; instead of obj.setFoo(“new value”); )
  • The method overloading problem is handled by providing access through longer keys which include the type signature, as well as the short name.
  • If a method expects an interface argument and the interface only declares one method, you can pass in a function object instead of explicitly implementing the interface. (var button = new javax.swing.JButton(); button.addClickListener(function(){…}); )
  • Rhino implements the E4X extension for embedded XML literals, so manipulating XML documents is pretty painless.

Rhino has also been around for the longest of any of the languages I looked at and is a fairly robust implementation.  There is a compiler so you can generate real, reflection-friendly classes with it, and, although the JavaScript standard library leaves a bit to be desired, there are projects like Narwhal and JSAN to improve that situation.

Groovy

Groovy is a language designed specifically for use on the JVM, with an eye to interoperability with existing Java libraries, but also providing a more dynamic language.  It provides facilities like optional typing and the “elvis operator” (which works like || in other scripting languages for providing default values in expressions that would otherwise return null):

javascript: var foo = baz.mightBeNull || "defaultFoo";
groovy:     def foo = baz.mightBeNull ?: "defaultFoo";

On the other hand, valid Java code is a mostly valid Groovy syntax, so transitioning an existing codebase is (supposedly) easy.  There are some gotcha’s though.  For example, if you use type checking, it is only implemented at runtime, so you can have the headache of a compile phase followed by a type error.  Again, compiled code is fully accessible to the Java runtime, including reflection and direct instantiation.

Scala

Scala is another language designed with JVM interoperability in mind, although it is much more of a deviation from Java than Groovy.  We’re not using it for the project that inspired this research, but I’ve been working with it on a little side project for some time now.  It is fully interoperable in the sense that Scala classes are Java classes too, but it resorts to some clever compile-time tricks to implement some of its niftier features, like operator overloading and traits (similar to Java’s interfaces, but with the ability to provide default implementations for methods.)  However, it is fully type-checked, using type inference to avoid type declarations all over the code.  It also has a number of features that don’t translate well to Java code:

  • Extractors, used for pattern matching; implemented as functions which return instances of a class from the Scala library.  These are usable from Java, but without Scala’s syntactic sugar for using them, they are much less useful.
  • Classes may have companion objects (which serve as the holder for any “global” methods; the stuff that you would declare static in Java.)  The way that the Scala compiler implements these means that static methods show up in Java code as part of a second class with a $ at the end of its name (ie, Foo would have a Foo$ class with all the static helpers.)
  • Functions as values.  In scala code, calling a function stored in a variable is just like calling a function normally, and there is specialized syntax for function variable types: “var foo: (Int, Int) => Int = (a, b) => a + b”, “foo(1, 2) == 3”.  In Java, such functions show up as instances of scala.Function2<scala.Int, scala.Int, scala.Int> and must be called through their apply() method.

The upshot is that Scala works quite well for working with existing Java code.  But if you are designing a library for use by general Java developers and not just Scala developers, then writing in Scala means that you need to avoid certain language features to avoid making the API cumbersome.

There are, of course, plenty of other languages available for use on the JVM.  JRuby, Clojure, and Jaskell are a few I’ve heard of, but not looked into yet.  However, of the languages I looked at, Rhino and Jython seem better suited as user-facing scripting interfaces, while Scala is a nice alternative to Java for core implementation.  If you are designing a library for consumption by Java developers though, Java itself gives you the best control over the Java classes and method signatures.

For the record, we ended up choosing Django on CPython for the current round of development, with plans to investigate moving to Jython if and when consolidating the code onto the JVM becomes more necessary.

Meme in Scala

Posted in Uncategorized by dwins on November 18, 2009

Sebastian over at Digifesto recently alerted me to a budding meme being pushed by Eric Florenzano.  The original proposal (from here) goes like this:

Rules:

  1. Implement a program that takes in a user’s name and their age, and prints hello to them once for every year that they have been alive.
  2. Post these rules, the source code for your solution, and the following list (with you included) on your blog.
  3. Bonus points if you implement it in a language not yet seen on the following list!

The List:

  1. [Python] http://www.eflorenzano.com/blog/post/trying-start-programming-meme
  2. [Bash] http://aartemenko.com/texts/bash-meme/
  3. [C] http://dakrauth.com/media/site/text/hello.c
  4. [Java] http://adoleo.com/blog/2008/nov/25/programming-meme/
  5. [Python 3] http://mikewatkins.ca/2008/11/25/hello-meme/
  6. [Ruby] http://stroky.l.googlepages.com/gem
  7. [Ruby] http://im.camronflanders.com/archive/meme/
  8. [Lisp] http://justinlilly.com/blog/2008/nov/25/back-on-the-horse/
  9. [Lua] http://aartemenko.com/texts/lua-hello-meme/
  10. [Functional Python] http://aartemenko.com/texts/python-functional-hello-meme/
  11. [Erlang] http://surfacedepth.blogspot.com/2008/11/erics-programming-meme-in-erlang.html
  12. [Haskell] http://jasonwalsh.us/meme.html
  13. [PHP] http://fitzgeraldsteele.wordpress.com/2008/11/25/memeing-in-php-2/
  14. [Javascript] http://www.taylanpince.com/blog/posts/responding-to-a-programming-meme/
  15. [Single-File Django] http://www.pocketuniverse.ca/archive/2008/november/27/florenzano-factor/

For my entry, I put together a script in Scala.

import scala.Console._

var name = readLine("What is your name? ")
var age  = readLine("How many years old are you? ").toInt
(1 to age).foreach { age => println("%2d) Hello, %s".format(age, name)) }

To run, copy the code into a text file named hello.scala and then run: scala hello.scala You can get the scala interpreter from the Scala website, or your distribution’s package manager.