Posts Tagged ‘Java’

Harnessing Java VarArgs on Non-VarArgs Methods

Friday, September 11th, 2009

Var-Args in Java can often make a particular algorithm appear much cleaner, simply by allowing the developer to omit array-box syntax altogether. So, for example – here is a method call for setting up a fictional date-input validator with acceptable inputs:

1
2
3
4
5
public boolean validateDateField(String field, DateFormat[] formats) {
    boolean validates = false;
    // Do something here.
    return validates;
}

… and here is how you could call it:

1
2
3
if(!validateDateField("myField", new DateFormat[] { new SimpleDateFormat("MM/dd/yyyy") })) {
    // Didn't validate!
}

Quite a mouthful. In Java 5 this can be simplified quite a bit by simply turning the method into a var-args receiver:

1
2
3
4
5
public boolean validateDateField(String field, DateFormat... formats) {
    boolean validates = false;
    // Do something here.
    return validates;
}

… which allows the caller to do this:

1
2
3
if(!validateDateField("myField", new SimpleDateFormat("MM/dd/yyyy"))) {
    // Didn't validate!
}

But what if you are working with a library that wasn’t converted post-Java-5 to support varargs-style parameters, you don’t have the source to be able to change it, and you’d rather not tack on a bunch of array construction syntax? Or, what if the portion of a method that accepts an array is not the last parameter (or there are multiple array parameters)?

In these cases, we can still leverage varargs and type-inference (as a caller) to make our syntax shorter and a little more expressive. With the method-level type-inference of Java 5 along with varargs, you can create a method like this:

1
2
3
public <T> T[] array(T... types) {
    return types;
}

This method is just a convenience array-construction method, but it is very reusable because it can construct an array of any type via varargs syntax. Even though generic types are erased by runtime, because Java constructs an array on-behalf of you for var-args (the compiler does, specifically), you don’t need to know the type at runtime. Normally this would be a problem, because unlike a generics-list (which only has type information at compile-time), arrays have type information at runtime, and as such can’t be constructed with generics paramters (in other words, you couldn’t say new T[] – the compiler no-likey).

This method can now be used to shorten the calling of the non-varargs variant of this method quite a bit:

1
2
3
4
5
public void testMethod() {
    if(!validateDateField("myField", array(new SimpleDateFormat("MM/dd/yyyy")))) {
        // Didn't validate!
    }
}

Not quite as nice as the varargs version, but at least it’s very clear what is happening – and it sure beats the new DateFormat[] {...} line. Additionally, if we change the original method signature slightly (let’s say it’s a method for validating multiple fields):

1
2
3
4
5
public boolean validateDateFields(String[] fields, DateFormat[] formats) {
    boolean validates = false;
    // Do something here.
    return validates;
}

We can still use our varargs tool on both method parameters:

1
2
3
4
5
public void testMethod() {
    if(!validateDateFields(array("myField1", "myField2"), array(new SimpleDateFormat("MM/dd/yyyy")))) {
        // Didn't validate!
    }
}

Brackets in Java Annotation Parameters

Thursday, September 10th, 2009

Just a quick note for anyone using annotations – I was going through a bunch of code today, where I saw someone using the @SuppressWarnings annotation (which you are probably using if you have generics in your code), and it quickly became clear that the person wasn’t aware of the single-argument support in annotations. (more…)

Taking Advantage of Java in JRuby

Wednesday, September 9th, 2009

Tom Enebo and Charles Nutter have posted a couple of entries over at the EngineYard Blog on accessing Java libraries from JRuby.

For those who may not be familiar, Tom Enebo and Charles Nutter were full-time Sun employees until late July when they switched companies to Engine Yard. As many others have said, it’s a different experience (and in my opinion, a very good one) seeing JRuby posts show up on the EngineYard blog.

You have to make a decision at some point when developing a JRuby application as to whether or not you are going to hide the ‘Java’ in your JRuby application from the main bulk of your code. Obviously, if you are developing a Swing GUI, it’s pretty much a foregone conclusion that it’s a JRuby app, and JRuby alone. On the other hand, it’s very possible now-a-days to code a Rails app that can run concurrently on JRuby, MRI, and any other compliant platform.

No answer is ‘right’. Each approach has its own virtues, and it really depends on your goals. A Java developer who simply wants to make coding Java apps easier could easily switch to JRuby and sprinkle Java references throughout their app. On the flip-side, you may just choose to deploy an existing Ruby app on JRuby for it’s compelling performance characteristics and its alternative deployment/scalability options; or perhaps your company would rather manage a Glassfish cluster than a Mongrel cluster – there are a variety of possible reasons.

Tom’s article (part 2) delves a little deeper into the influence of Java from an API perspective (as opposed to the basic Java-integration language constructs). His comments on delegation are compelling:

Delegation as a concept is not specific to Ruby, but is worth bringing up. Why decorate a Java class and get all of that Java class’s methods exposed when you can hide them behind another Ruby class that only exposes what you want? This is especially powerful when you want to write a common API that works across multiple Ruby implementations (e.g. JRuby, MRI, and Rubinius), but has different native backends.

In practice, even if you have committed to JRuby as your platform and have Java libraries referenced all over the place, it can still be very valuable to abstract APIs around the original Java implementation – if for no other reason than Java APIs needing some TLC to feel natural in Ruby. Likewise, there are cases where using Java libraries as the driver for a particular component of your application may give you a competitive advantage on JRuby.

In that vein, I was recently working on a high-concurrency component of a JRuby application. In my opinion, the Java libraries for concurrency are much further evolved than those in Ruby; particularly after the advent of java.util.concurrent in Java 5. One of those areas where Ruby is lacking is the existence of a read-write lock. Jonah Burke previously blogged about implementing a read-write lock using the standard Ruby mutex objects. His implementation is simple, well-implemented, and should be quite reliable. However, Java’s ReentrantReadWriteLock is fully integrated into the underlying Java platform, including in the instrumentation libraries (detailed briefly here). To me, if you plan to run on a Java platform, being able to independently monitor locks held by the Ruby runtime is a Good Thing.

Here is a simple JRuby implementation of a ReadWriteLock that uses a Java lock via delegation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
require 'java'

class ReadWriteLock
  include_package 'java.util.concurrent.locks'
 
  def initialize
    @java_lock = ReentrantReadWriteLock.new
  end
 
  def read(&block)
    read_lock = @java_lock.read_lock
    read_lock.lock
    begin
      block.call
    ensure
      read_lock.unlock
    end
  end
 
  def write(&block)
    write_lock = @java_lock.write_lock
    write_lock.lock
    begin
      block.call
    ensure
      write_lock.unlock
    end
  end
end

As you can see, JRuby makes using Java objects and extending them very straightforward.

This particular implementation is not 100% API-compatible with the one provided by Jonah, however with a little manipulation it could be easily (I’ll leave it as an exercise to the reader). This is really more of an example of how Java can provide the underlying engine for Ruby libraries when running on JRuby (this is how the majority of JRuby is implemented, after all) – and if this were API compatible with Jonah’s, it’d simply be a matter of constructing this in an isolated factory method, and switching implementations then becomes simply a matter of flipping a flag.

Note that instead of delegation, you could also simply extend the existing Java object with more goodies. Here is an alternate implementation of these same block methods that simply appends these methods to the Java class itself:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
require 'java'

class java::util::concurrent::locks::ReentrantReadWriteLock

    def read(&block)
    read_lock = self.read_lock
    read_lock.lock
    begin
      block.call
    ensure
      read_lock.unlock
    end
  end

  def write(&block)
    write_lock = self.write_lock
    write_lock.lock
    begin
      block.call
    ensure
      write_lock.unlock
    end
  end
end

In practice this works almost identically to the first example. This implementation has some API-leakage (the Java methods on ReentrantReadWriteLock are available to call by the client code), but also has one less object involved, as the methods are added to the Java lock class itself, rather than provided by a proxy object. Which approach you would use for your particular use-case is really dependent upon the scenario in question, and your goals for the API.

Either way for this example, the core usage of this library is identical irrespective of which implementation you choose:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
lock = ReadWriteLock.new
# Alternatively, the second example would be created this way:
# require 'java'
# import java.util.concurrent.locks.ReentrantReadWriteLock
# lock = ReentrantReadWriteLock.new

# Usage is identical
lock.read {
  puts 'Executing with read lock'
}

lock.write {
  puts 'Executing with write lock'
}