5 Things to Look for in JRuby 1.4

By Nick Sieger | September 21st, 2009 at 10:09AM

The team has finally wrapped up the long summer of JRuby-related travel, and it’s time to set our sights on a new version of JRuby for the community to lovingly embrace.

The release itself is tentatively planned to enter a round of release candidates at the end of September. Please prepare yourselves, try the release candidates when they are available, and most importantly, report bugs!

So what can you expect in the next release, other than the usual array of bug, performance, and compatibility fixes? Here are the five areas where we’ve been focusing efforts.

1. 1.8.7 is the New Baseline

When Ruby 1.8.7 was first released, we had a false start where we eagerly started to add some of the new additions, only to find that Rails (version 2.0 at the time) was rendered useless by the changes. Now, finally, three minor releases of Rails 2.x later, Rails on Ruby 1.8.7 has finally stabilized, and is now the recommended version of Ruby to use with Rails. Additionally, 1.8.7 is showing up as the default version of Ruby in many operating systems, and we began to see more bug reports about missing 1.8.7 features.

So, in JRuby 1.4, we’ll finally report compatibility with Ruby 1.8.7p174:

$ jruby -v
jruby 1.4.0dev (ruby 1.8.7p174) (2009-09-14 b09f382) (Java HotSpot(TM) Client VM 1.5.0_19) [i386-java]
The patch-level (p174) is based on the version of Ruby where we pulled the updated standard library. We always maintain that patch-level is a “best effort” number, and as such, we cannot promise full feature-for-feature (or bug-for-bug!) compatibility. However, as the RubySpec project has matured, it’s gotten much easier for us to feel confident about this claim. As always, if you spot an area where we differ from Ruby 1.8.7, please do file a bug on the discrepancy, or even better, make sure that RubySpec covers the issue by submitting a patch to RubySpec.

2. Improving 1.9 Compatibility

Even though Ruby 1.9 is still a moving target, the RubySpec project has recently begun to cover many of the new 1.9 features, which gives JRuby an easier, more robust mechanism for tracking how far along the path to 1.9 we are.

We’ve also been following our tried-and-true approach of just trying to get stuff working. In particular, IRB, RubyGems, Rake, and even some simple Rails applications are working with JRuby in 1.9 mode.

Other than a couple of major new features remaining (Multilingualization/encoding, IO transcoding, Fibers), JRuby 1.9 mode should just work. To try out JRuby in 1.9 mode, just pass --1.9 as a leading argument on the command-line:

$ jruby --1.9 -v
jruby 1.4.0dev (ruby 1.9.1p0) (2009-09-14 b09f382) (Java HotSpot(TM) Client VM 1.5.0_19) [i386-java]
If you’ve been writing 1.9 code, we’d love to hear if you can get it working on JRuby: do comment!

3. New YAML Parser

Ok, so a new YAML parser is something you’d probably have to give more than a cursory glance to notice. But our good friend Ola Bini has gone and done it again with Yecht, a new YAML engine. Ola re-implemented YAML support in JRuby to be much closer to the idiosyncracies of Syck, the C YAML parser that MRI uses. With this change, a number of long-standing YAML compatibility issues are fixed. Hopefully this is the last YAML engine that JRuby will ever need!

4. Java Method Selection and Coercion API

For a long time, JRuby Java integration features have been something of a black box, especially the way Java methods are selected and invoked and arguments are coerced. This black box has hindered understanding of how JRuby calls Java, and in the case of overloaded methods, has made some Java methods unreachable. Consider this Java class:

public class Overloaded {
    public static void use(int i) { /* ... / }
    public static void use(long l) { / ... */ }
}
And this JRuby code:
Java::Overloaded.use 10
Which Overloaded method is called? It turns out it’s use(long). JRuby behavior is to coerce Ruby Fixnums into Java longs. Thus, with current versions of JRuby, it’s impossible to call the version that takes an int.

We’d like to make this part of the Java integration layer more transparent and accessible. Here are a few APIs we’re considering:

a. Object#java_send(name, signature, *args)

Like Object#send except it would allow you to identify and invoke a specific Java method by its name and signature. A signature for these purposes is an array of classes, where the first element in the array specifies the return type.

b. Object#java_method(name, signature)

Like Object#method, except it would take an array of Java classes representing a method signature as an additional argument and return a Method object that can be #call‘ed.

c. #coerce_to?(type)

Method convention to allow an object to decide whether it can be coerced to a Java type. JRuby will call this method if it’s available to get hints to aid in choosing a method in the presence of several overloaded methods.

d. #to_java(type)

Method convention to allow arbitrary Ruby objects to control how they are coerced to Java. If a Ruby object responds to #to_java, JRuby will use it to convert the argument before passing to a Java method invocation.

e. #to_ruby(type)

Like #to_java except to be applied to return types and Java objects coming back to Ruby.

All of these APIs are still yet to be implemented, and we could use some good real-world examples of where JRuby falls down to help ensure that we solve those issues.

5. Generate Real Java Classes from Ruby

Since we started writing Ruby2java as an add-on library, we’ve been looking for a way to expose the functionality of creating a real Java class from Ruby in the JRuby core. JRuby 1.4 will have some new experimental APIs for doing this. The example below explains it in code:

require 'java'
require 'jruby/core_ext'

class SimpleTest def equals raise "not equal" unless 1.0 == 1 end end

SimpleTest.add_method_signature("equals", [java.lang.Void::TYPE]) SimpleTest.add_method_annotation("equals", org.junit.Test => {}) SimpleTest.become_java! The effect of this code is the same as writing the following Java code:

package ruby;
import org.junit.Test;
public class SimpleTest {
    @Test
    public void equals() {
        // dispatch back to Ruby code here
    }
}
We are also providing #add_class_annotation and #add_parameter_annotation methods as well, rounding out the ability to shape a real Java class.

These APIs are admittedly verbose and low-level, but they do allow you to easily build higher level constructs using Ruby metaprogramming techniques.

Here’s a more realistic example of implementing a JAX-RS/Jersey resource using Ruby (full source available):

class Hello < RubyJersey::Resource
  GET()
  Produces("text/plain")
  Returns(java.lang.String)
  def hello
    "Hello Ruby Jersey!"
  end
end

Feedback

The release is still a couple of weeks away, so none of this is by any means final. Please send us feedback by commenting here or use the JRuby mailing list for longer discussions, and let us know how the 1.4 release candidates work for you!

Share this post:
  • email
  • Digg
  • del.icio.us
  • Reddit
  • Slashdot
  • StumbleUpon
  • Technorati
  • Twitter
  • Google Bookmarks
  • Facebook
  • LinkedIn
Popularity: 6% |
Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars
Loading ... Loading ...

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

14 Responses to “5 Things to Look for in JRuby 1.4”

  1. kevwil kevwil says:

    Is there a time frame for getting the 1.9 support up to the current patch level, in the same way the 1.8.7 spec is coming into line with that latest patch level? I see 1.9.1p0 and I'm pretty sure that's already out of date.

    Thanks for the great work on JRuby – we might FINALLY be allowed to code in Ruby at work due to JRuby's awesomeness.

    • nicksieger nicksieger says:

      You're right, patch level 0 doesn't say much about the level of JRuby's 1.9 support. This is complicated by 2 reasons: 1) JRuby's own support is still missing a couple major features as mentioned; 2) 1.9 itself isn't fully baked.

      Regarding 2), the RubySpec project has been targeting 1.9.2, and JRuby follows that as a result. Since 1.9.2 is still in preview releases, there is no publicly-known patch level to use anyway. If you think we should display something other than "0", please let us know.

  2. AkitaOnRails AkitaOnRails says:

    I know that you're always striving to achieve better performance in every new release. Any new optimizations in this release? Would be great to hear some comparisons between jRuby 1.3 and 1.4. And congrats, as usual a great work.

    • nicksieger nicksieger says:

      While performance was not a major theme for this release, there's a smorgasbord of lower-level things that may help certain applications. Things like numeric operations in the interpreter, some improvements to Fixnum math operations, and reducing the bytecode limit for JIT'ted methods so that we won't attempt to compile methods that are too big, thus wasting less time during compilation.

      Thanks for the suggestion for a comparison between 1.3 and 1.4. We'll try to have some numbers to show closer to release time.

  3. Some days ago I wrote a little script to help me to run ruby specs to check ruby 1.9 compatibility. I know it's not perfect but it's useful for me and perhaps for you as well, you can take a look at here:

    http://gist.github.com/190948 http://thinkincode.net/2009/9/22/improving-jruby-...

  4. Knodi Knodi says:

    Is fork support in 1.4?

  5. Justin Justin says:

    How easy/difficult would it be to get gdbm working? Would using the JRuby FFI be the way to go?

  6. Jason Jason says:

    Does anyone know if we jRuby allows you upload rails apps as bytecode?

Leave a Reply