Java 8

imageThis article discusses and compares the initial version of Java 8 and C# 4.5.1. I have not used Java 8 and I have not tested that any of the examples -- Java or C# -- even compile, but they should be pretty close to valid.

Java 8 has finally been released and -- drum roll, please -- it has closures/lambdas, as promised! I would be greeting this as champagne-cork--popping news if I were still a Java programmer.1 As an ex-Java developer, I greet this news more with an ambivalent shrug than with any overarching joy. It's a sunny morning and I'm in a good mood, so I'm able to suppress what would be a more than appropriate comment: "it's about time".

Since I'm a C# programmer, I'm more interested in peering over the fence at the pile of goodies that Java just received for its eighth birthday and see if it got something "what I ain't got". I found a concise list of new features in the article Will Java 8 Kill Scala? by Ahmed Soliman and was distraught/pleased2 to discover that Java had in fact gotten two presents that C# doesn't already have.

As you'll see, these two features aren't huge and the lack of them doesn't significantly impact design or expressiveness, but you know how jealousy works:

Jealousy doesn't care.

Jealousy is.

I'm sure I'll get over it, but it will take time.3

Default methods and static interface methods

Java 8 introduces support for static methods on interfaces as well as default methods that, taken together, amount to functionality that is more or less what extensions methods brings to C#.

In Java 8, you can define static methods on an interface, which is nice, but it becomes especially useful when combined with the keyword default on those methods. As defined in Default Methods:

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

In Java, you no longer have to worry that adding a method to an interface will break implementations of that interface in other jar files that have not yet been recompiled against the new version of the interface. You can avoid that by adding a default implementation for your method. This applies only to those methods where a default implementation is possible, of course.

The page includes an example but it's relatively obvious what it looks like:

**public interface** ITransformer
{
  **string** Adjust(**string** value);
  **string** NewAdjust(**string** value)
  {
    **return** value.Replace(' ', '\t');
  }
}

How do these compare with extension methods in C#?

Extension methods are nice because they allow you to quasi-add methods to an interface without requiring an implementor to actually implement them. My rule of thumb is that any method that can be defined purely in terms of the public API of an interface should be defined as an extension method rather than added to the interface.

Java's default methods are a twist on this concept that addresses a limitation of extension methods. What is that limitation? That the method definition in the extension method can't be overridden by the actual implementation behind the interface. That is, the default implementation can be expressed purely in terms of the public interface, but perhaps a specific implementor of the interface would like to do that plus something more. Or would perhaps like to execute the extension method in a different way, but only for a specific implementation. There is no way to do this with extension methods.

Interface default methods in Java 8 allow you to provide a fallback implementation but also allows any class to actually implement that method and override the fallback.

Functional Interfaces

Functional interfaces are a nice addition, too, and something I've wanted in C# for some time. Eric Meijer of Microsoft doesn't miss an opportunity to point out that this is a must for functional languages (he's exaggerating, but the point is taken).

Saying that a language supports functional interface simply means that a lambda defined in that language can be assigned to any interface with a single method that has the same signature as that lambda.

An example in C# should make things clearer:

**public interface** ITransformer
{
  **string** Adjust(**string** value);
}

**public static class** Utility
{
  **public static void** WorkOnText(**string** text, ITransformer)
  {
    // Do work
  }
}

In order to call WorkOnText() in C#, I am required to define a class that implements ITransformer. There is no other way around it. However, in a language that allows functional interfaces, I could call the method with a lambda directly. The following code looks like C# but won't actually compile.

Utility.WorkOnText(
  "Hello world",
  s => s.Replace("Hello", "Goodbye cruel")
);

For completeness, let's also see how much extra code it is do this in C#, which has no functional interfaces.

**public class** PessimisticTransformer : ITransformer
{
  **public string** Adjust(**string** value)
  {
    **return** value.Replace("Hello", "Goodbye cruel");
  }
}

Utility.WorkOnText(
  "Hello world",
  **new** PessimisticTransformer()
);

That's quite a huge difference. It's surprising that C# hasn't gotten this functionality yet. It's hard to see what the downside is for this feature -- it doesn't seem to alter semantics.

While it is supported in Java, there are other restrictions. The signature has to match exactly. What happens if we add an optional parameter to the interface-method definition?

**public interface** ITransformer
{
  **string** Adjust(**string** value, ITransformer additional = **null**);
}

In the C# example, the class implementing the interface would have to be updated, of course, but the code at calling location remains unchanged. The functional interface's definition is the calling location, so the change would be closer to the implementation instead of more abstracted from it.

**public class** PessimisticTransformer : ITransformer
{
  **public string** Adjust(**string** value, ITransformer additional = **null**)
  {
    **return** value.Replace("Hello", "Goodbye cruel");
  }
}

// Using a class
Utility.WorkOnText(
  "Hello world",
  **new** PessimisticTransformer()
);

// Using a functional interface
Utility.WorkOnText(
  "Hello world",
  (s, a) => s.Replace("Hello", "Goodbye cruel")
);

I would take the functional interface any day.

Java Closures

As a final note, Java 8 has finally acquired closures/lambdas4 but there is a limitation on which functions can be passed as lambdas. It turns out that the inclusion of functional interfaces is a workaround for not having first-class functions in the language.

Citing the article,

[...] you cannot pass any function as first-class to other functions, the function must be explicitly defined as lambda or using Functional Interfaces

While in C# you can assign any method with a matching signature to a lambda variable or parameter, Java requires that the method be first assigned to a variable that is "explicitly assigned as lambda" in order to use. This isn't a limitation on expressiveness but may lead to clutter.

In C# I can write the following:

**public string** Twist(**string** value)
{ 
  **return** value.Reverse();
}

**public string** Alter(**this string** value, Func<**string**, **string**> func)
{
  **return** func(value);
}

**public string** ApplyTransformations(**string** value)
{
  **return** value.Alter(Twist).Alter(s => s.Reverse());
}

This example shows how you can declare a Func to indicate that the parameter is a first-class function. I can pass the Twist function or I can pass an inline lambda, as shown in ApplyTransformations. However, in Java, I can't declare a Func: only functional interfaces. In order to replicate the C# example above in Java, I would do the following:

**public** String twist(String value)
{ 
  **return** new StringBuilder(value).reverse().toString();
}

**public** String alter(String value, ITransformer transformer)
{
  **return** transformer.adjust(value);
}

**public** String applyTransformations(String value)
{
  **return** alter(alter(value, s -> twist(s)), s -> new StringBuilder(s).reverse().toString();
}

Note that the Java example cannot pass Twist directly; instead, it wraps it in a lambda so that it can be passed as a functional interface. Also, the C# example uses an extension method, which allows me to "add" methods to class string, which is not really possible in Java.

Overall, though, while these things feel like deal-breakers to a programming-language snob5 -- especially those who have a choice as to which language to use -- Java developers can rejoice that their language has finally acquired features that both increase expressiveness and reduce clutter.6

As a bonus, as a C# developer, I find that I don't have to be so jealous after all.

Though I'd still really like me some functional interfaces.



  1. Even if I were still a Java programmer, the champagne might still stay in the bottle because adoption of the latest runtime in the Java world is extremely slow-paced. Many projects and products require a specific, older version of the JVM and preclude updating to take advantage of newer features. The .NET world naturally has similar limitations but the problem seems to be less extreme.

  2. Distraught because the features look quite interesting and useful and C# doesn't have them and pleased because (A) I am not so immature that I can't be happy for others and (B) I know that innovation in other languages is an important driver in your own language.

  3. Totally kidding here. I'm not insane. Take my self-diagnosis with a grain of salt.

  4. I know that lambdas and closures are not by definition the same and I'm not supposed to use the interchangeably. I'm trying to make sure that a C# developer who reads this article doesn't read "closure" (which is technically what a lambda in C# is because it's capable of "closing over" or capturing variables) and not understand that it means "lambda".

  5. Like yours truly.

  6. Even if most of those developers won't be able to use those features for quite some time because they work on projects or products that are reluctant to upgrade.

Versioned Objects with Hibernate

Hibernate is a persistence framework for Java. Among the many perks it purports to bring to the table is automatic versioning for objects in the database. That is, when saving an object to the database, it increments a version number. Any process that attempts to store a different version of the same object is rejected. This is all extremely flexible and can be added to a POJO using an annotation:

@Version
  private int version;

Nice ... a single annotation takes care of people overwriting each other's data. The exercise of handling the ensuing StaleObjectStateException in the user interface is left up to the reader.

The Trouble Begins...

Now, imagine that we have an object -- call it a Book -- in memory and we render it to a web page. On that page is a button which attaches more information to the object -- say an Author -- then saves and rerenders the same book in the page. The user can add and save authors or change other book properties and save the book to exit edit mode for that book. Though split over multiple page requests, as far as Hibernate is concerned, the following actions occur on that object1:

book.save();
book.addAuthor(new Author(getNameOfAuthor()));
book.save();
book.addAuthor(new Author(getNameOfAuthor()));
book.save();
book.save();
// exit edit mode ...

This does not work. Hibernate raises a StaleObjectException on the second execution of save() because it never updated the version number in the object when it saved it the first time. That is, the automatically managed field version is not synchronized with the object being saved when it is modified in the database. It's not like Hibernate doesn't know how to do this -- fields marked with the @Id annotation are updated as expected.

At this point, there are two things to do:

  1. Dig into the Hibernate source code and see why @Version isn't treated the same as @Id
  2. Figure out a way to work around it in application code

After a bit of initial debugging pursuing choice (1), it became clear that choice (2) would be much more efficient (not least because the line numbers in the accompanying sources didn't match the jar file).

Updating the version

The first step is to search online for this problem, but that was relatively fruitless, as no one else seemed to have had this problem, they didn't regard it as a problem or they didn't notice it yet. With hundreds, if not thousands, of companies using Hibernate, it's hard to believe that this feature is designed like this, or is fundamentally broken. The internet having failed us, we're left to fix this problem ourselves.

As some of you may already have been dying to point out, the quick and dirty way of fixing this is to simply update the version number by hand. At the risk of making any programming purists ill, here's that code:

book.save();
book.setVersion(book.getVersion() + 1);

However, this code assumes that it knows exactly how the automatic versioning feature of Hibernate works (or, rather, doesn't) and how future versions will work. Not liking that solution, we decide that we'll probably need to hit the database again; for that purpose there's the refresh() function.

...aaaaaand, the version number is still zero.

Taking a look at the database shows that the object with this id clearly has a version number of 2. Let's turn on query logging to see what Hibernate is doing when it executes a refresh on our object. In the hibernate.cfg.xml file, set the following property (it's probably set to false in your default configuration):

<hibernate-configuration>
  <session-factory>
    ...
    <property name="hibernate.show_sql">true</property>

This time the console shows that Hibernate does indeed execute a select and does indeed select our version field. It, however, fails to apply that value to the object on which refresh() was called.

That hack solution at the beginning of this section is starting to look mighty good. At this point, we're left with the alternative of reloading the object from the database in order to simulate the seemingly non-functional refresh(). Reloading the object does get the correct version and leaves us with an object that we can use for further editing & saving operations.

book.save();
book = book.refresh();
book.addAuthor(new Author(getNameOfAuthor()));
book.save();
book = book.refresh();
// exit edit mode ...

With this solution, however, we're forced to create a new object, reassigning the reference to book. Though further reading online turned up references to tantalizing tidbits like load(Object obj,Serializable id), it only generated NonUniqueObjectExceptions; no combination of evict() and flushing the session were able to avoid this. After more fruitless investigation in this vein -- and perusal of the Hibernate documentation, which, while good, doesn't link to actual examples of these methods in action -- the "fake" refresh outlined above was accepted as a general solution.

Be aware, however, that any other references to the object represented by book are not updated and will still have the wrong version. In straightforward web applications, where the object is primarily referenced from a single page object, this is less likely to be the case. Applications with more sophisticated operations -- for instance, where the reference is part of a graph of objects being edited -- the refresh() outlined above is not a proper solution.



  1. For the purposes of this discussion, assume that calls to save() and refresh() execute the similarly named functions on the Hibernate session ... these assumed shortcut functions make the code easier to read. Using Java 1.5, Hibernate 3.2

Sorting Generic Collections

One of the features we expect from a collections library is sorting. You should be able to use generic library mechanisms to sort a list of any kind of element. Most libraries include a generic sort function, to which a comparison functor (object or function pointer) is passed. This functor is called repeatedly on pairs of elements until the list is sorted.

Let's define the simple class we'll use in the ensuing examples.

class A {
  String fileName;
  
  function getFileName() {
    return fileName;
  }
}

Now, let's sort a List<A>. Is there a sort function on the list object itself? No. Why not? Legacy reasons. In order to avoid breaking existing code, Java has not made any changes to the List interface. Ever. Therefore, you will have to search for any new functionality in the global function unit masquerading as a class1 called Collections.

There are two sorting functions defined in this class, shown below:

public static <T extends Comparable<? super T>> void sort(List<T> list);
public static <T> void sort(List<T> list, Comparator<? super T> c);

Neither one of these is exactly easy on the eyes and both include the wildcard (?) operator in their definitions. The first version accepts a List<T> only if T extends Comparable directly or a generic instantiation of Comparable which takes T or a superclass as a generic parameter. The second version takes a List<T> and a Comparator instantiated with T or a supertype.

With our simple class A above, it would be pretty easy to implement the interface to give the class a standard ordering. Naively, we might add the following:

class A implements Comparable {
  String fileName;
  
  function getFileName() {
    return fileName;
  }

  public int compareTo(Object _o) {
    return getFileName().compareTo((A) _o.getFileName());
  }
}

The compiler seems pretty happy with it, but actually calling sort() with a List<A> results in a warning:

Type Safety: Unchecked invocation sort(List<A>) of the generic method sort(List<T>) of type Collections

If you're using Eclipse, your "Quick-Fix" trigger finger is probably getting mighty itchy right now, but let's avoid simply adding a @Suppress directive above this function and try to find out why the class compiles, but the function call has a problem.

A quick search through Google Groups turns up Collections.sort() in Java 5, which reminds us that "[t]he Comparable interface takes a generic parameter". Adding in the generic argument (as shown below) fixed the problem and gets rid of the warning.

class A implements Comparable<A> {
  ...

  public int compareTo(A _o) {
    return getFileName().compareTo(_o.getFileName());
  }
}

On top of that, the generic version of Comparable allows us to declare a type-specific compareTo function and get rid of the ugly cast. All's well that ends well, but it would be much nicer if the compiler could tell us that we are misusing Comparable than to have to find out from some guy in a newsgroup.



  1. This class has a private constructor and cannot be instantiated -- you can only use it for its static functions. Using Java 1.5

Wildcard Generics

As of version 1.5, Java has blessed its developers with generics, which increase expressiveness through improved static typing. With generics, Java programmers should be able to get away from the "casting orgy" to which Java programming heretofore typically devolved. The implementation in 1.5 does not affect the JVm at all and is restricted to a syntactic sugar wherein the compiler simply performs the casts for you.

Let's build a class hierarchy and see how much casting Java saves us. Assume that you have defined a generic hierarchy using the following class:

public class DataObject {
  private String name;
  private List<DataObject> subObjects = new ArrayList<DataObject>();

  public String getName() {
    return name;
  }

  public List<DataObject> getSubObjects() {
    return subObjects;
  }
}

Well, now that's an improvement! The class can express its intent in a relatively clear syntax without creating a specialized list class for the private field and result type. Assume further that there are various sub-classes of this DataObject, which want to provide type-specific helper functions for their sub-lists. For example:

public class A extends DataObject {
}

public class B extends DataObject {
  public List<A> getAs() {
    return getSubObjects();
  }
}

Though this is exactly what we would like, it won't compile. It returns instead the error:

Type mismatch: Cannot convert from List<DataObject> to List<A>

In the next section, we'll find out why.

Covariance and Catcalls

For some reason, List<A> does not conform to List<DataObject>, even though A inherits from DataObject. The Generics Tutorial (PDF) Section 3 explains:

In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G is a subtype of G. This is probably the hardest thing you need to learn about generics, because it goes against our deeply held intuitions.

Indeed it is hard to learn and indeed it does go against intuitions. Is there a more specific reason why generics is implemented in this way in Java? Java's competitor, C#, is limited in exactly the same way and the C# Version 3.0 Specification offers the following explanation:

No special conversions exist between constructed reference types other than those described in ยง6. In particular, unlike array types, constructed reference types do not exhibit "covariant" conversions. This means that a type List<B> has no conversion (either implicit or explicit) to List<A> even if B is derived from A. Likewise, no conversion exists from List<B> to List<object>.

The rationale for this is simple: if a conversion to List<A> is permitted, then apparently one can store values of type A into the list. But this would break the invariant that every object in a list of type List<B> is always a value of type B, or else unexpected failures may occur when assigning into collection classes.

The key word here is covariance. Neither Java nor C# supports it (except for return types, where there are no dangers involved) because of function calls that, in the Eiffel world, have long been called "catcalls". Suffice it to say that both Java and C# have elected to limit expressiveness and legibility in order to prevent this type of error from happening.1

Making it work in Java

Since Java has clearly state that it neither condones nor supports what we would like to do, we can choose one of several options:

  1. Be happy with the List<DataObject> and just go back to casting to get the desired <A> when needed
  2. Figure out a way of getting Java to return the desired List<A> without complaining

Since we're stubborn, we'll go with (2) above and dig a little deeper into generics. One solution is to create the list on-the-fly and transfer all the elements over to it.

public List<A> getAs() {
    List<A> result = new ArrayList<A>();
    for (DataObject obj : getSubObjects()) {
      result.add((A) obj);
    }
    return result;
  }

Mmmmm...lovely. It does the soul good and makes the heart swell with pride to write code like this. So clear and understanable -- and such a lovely mix of new-style iteration with old-style casting! Methinks we'll try again. In the first attempt, we returned List<DataObject> from getSubObjects(). Is there another result type we could use?

Wildcards Explained

Java's generics include something called wildcards, which allow a restricted form of covariance, in which the character ? acts as a placeholder for any class type at all. Wildcards are especially useful for function arguments, where they allow any list of elements to be passed. Imagine we wanted to pass in a list of DataObjects to a function to be printed. Using wildcards, we can write the following:

public void printCollection(Collection<?> _objects) {
  for (Object o : _objects) {
    System.out.println(o);
  }
}

The example above takes an collection at all and prints all of them. It only works because the compiler knows that any class that replaces ? must inherit from java.lang.Object, so it can access any methods of that class from within the function. This is extremely limited since we can't access any DataObject-specific functions, so Java also includes bounded wildcards, which allow a wildcard to restrict the types of objects that may be used as the generic argument. Let's rewrite printCollection so that we can access DataObject's members without casting:

public void printCollection(List<? extends DataObject> _objects) {
  for (DataObject o : _objects) {
    System.out.println(o.getName());
  }
}

Whereas this mechanism suffices for the example above, wildcards exact a hidden price: they do not conform to anything. That is, though List<A> conforms to the format parameter, List<? extends DataObject>, you cannot then call add() on it. That is, the following code doesn't work:

public void extendCollection(List<? extends DataObject> _objects) {
  _objects.add(new DataObject());
}

The parameter of _objects.add() is of type ? extends DataObject, which is completely unknown to the Java compiler. Therefore, nothing conforms to it ... not even DataObject itself!

Using the example above, we can recap the different approaches to using generics in Java:

  • Using List<DataObject> as the formal argument doesn't allow us to pass a List<A>
  • Using List<?> as the formal argument allows us to use only those functions defined in java.lang.Object on elements of the list.
  • Using List<? extends DataObject> allows us to pass any list of elements whose type conforms to DataObject, but limits the methods that can be called on it.

Making It Work

Let's return now to our original example and see if we can't apply our new-found knowledge to find a solution. Let's redefine the result type of the getSubObjects() function to use a wildcard, while leaving the result type of the getAs() function, defined in B, as it was.

public List<? extends DataObject> getSubObjects() {
    return subObjects;
  }

However, as we saw in the third case above, this return type uses an unknown (unknowable) generic type and cannot be modified using add() or remove(). Not exactly what we were looking for. Let's instead put it back the way it was and concentrate on using our newfound knowledge to cast (Yay! Casting! I knew you'd be back!) our result to the correct type. Here's a naive attempt:

public List<A> getAs() {
    return (List<A>) getSubObjects();
  }

Ok. From the discussion above, it's clear this won't work and the compiler rewards us with the following error message:

Cannot cast from List<DataObject> to List<A>

Fine, let's try again, this time throwing a wildcard into the mix:

public List<A> getAs() {
    return (List<A>) (List< ? extends PathElement>) getSubObjects();
  }

Sweet! It compiles! We're definitely on the home stretch now, but there's still a warning from the compiler:

Type safety: the cast from List<capture-of ? extends DataObject> to List<A> is actually checking against the erased type list.

This is Java's way of saying that you have done a complete end-run around it's type-checking. The "erased type list" is actually List because the compiler uses a strategy called erasure2 to resolve generic references. The double cast in the example above compiles (and will run), but cannot be statically checked. At this point, there's nothing more we can do, so we admit defeat the Java way and slap a SuppressWarnings annotation on the function and continue on our way.

@SuppressWarnings("unchecked")
  public List<A> getAs() {
    return (List<A>) (List< ? extends PathElement>) getSubObjects();
  }

It's clear that the decision to avoid covariance at all costs has cost the language dearly in terms of expressiveness (and, as a result, type-safety, as evidenced by the casting in the final example). It takes rather a lot of illegible code to express what, at the beginning of the article, seemed a rather simple concept.



  1. Since the Pascal days, it seems that popular, mainstream languages almost always decide for compiler simplicity over programmer expressiveness. Static-typing for languages with covariant parameters offers a more in-depth example of covariance. For more information on this issue and other ways of addressing it -- without putting the burden on the programmer -- see the paper, Type-safe covariance (Type-safe covariance: Competent compilers can catch all cat-calls), which offers both an in-depth look at the "problem" of covariance and offers a concrete solution (which has been since implemented in Eiffel).

  2. This quick overview on Type Erasure, explains the concept. The reason for this relatively naive implementation of generics is -- as almost always in Java -- backwards compatibility: "so that new code may continue to interface with legacy code" Using Java 1.5

Inherited Method Annotations

See Finding Conforming Methods for part one of this two-part article.

The problem we're working on is as follows:

  1. Given an object, a method name and a list of parameters, execute the matching method on the given object.
  2. Determine from the object's class whether the given method can be executed from the given context (web, command-line, etc.)

We will use annotations to mark up methods as callable or not. Given the Method we obtained in part one, it shouldn't be too hard to find its annotations. Simply pass the class of the desired annotation to getAnnotation(); if the annotation was specified for that method, we check its contents to determine whether the method can be called or not.

These are not the Annotations you're Looking For

In part one, calling getConformingMethod( "giveCommandTo", {new Assistant()}, Manager.getClass()) returns the overridden method from the Manager class. Unfortunately, a call to getAnnotations() on this method returns an empty list. Why?

The Java reflection API makes a distinction between annotations that appear directly on an element and all annotations for an element, including ancestors. These two lists can be retrieved from any AnnotatedElement using the following methods:

Annotation[] getAnnotations();
  Annotation[] getDeclaredAnnotations();

The documentation states that getDeclaredAnnotations() returns "all annotations that are directly present on this element", whereas getAnnotations() returns "all annotations present on this element". The key word here is directly, which is to be interpreted as stated above ... for classes. For methods, there is no notion of inheritance per se in the reflection API. That is, if a method in a base class has an annotation and that method is overridden in a descendent, the signature for the method in the descendent returns empty lists for both getDeclaredAnnotations() and getAnnotations().

This doesn't make any sense and directly contradicts the documentation. It seems that the all vs. declared distinction only holds for classes, even though it is defined for all elements. A quick look into the Java source shows that Method inherits from AccessibleObject, which implements the AnnotatedElement interface. AccessibleObject implements getAnnotations() with the following code:

public Annotation[] getAnnotations() { 
        return getDeclaredAnnotations();
    }

Alrighty then! Method itself does not override this method, so it's relatively clear that inherited annotations are not available from a method. In effect, the @inherited keyword only has an effect for classes, which is a shame. A quick check of the documentation for that keyword verifies this claim:

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class.

So, once again, we're on our own and must build the functionality in a custom function. The code below shows how to search a method and its inherited implementations for the Callable interface:

private Callable getCallable(Method m, Object[] actualParameters) {
    result = null;
    if (m != null) {
      Callable result = m.getAnnotation(Callable.class);
      if (result == null) {
        Class<?> parent = m.getDeclaringClass().getSuperclass();
        if (parent != null) {
          Method superMethod = getConformingMethod(m.getName(), actualParameters, parent);
          result = getCallable(superMethod, actualParameters);
        }
      }
    }
    return result;
  }

It's not rocket science, but it involves a lot of digging around in the guts of Java reflection that shouldn't be necessary.


Using Java 1.5

Finding *Conforming* Methods

This is a two part post illustrating some tricks for working with the Java reflection API. Part two is available here.

Java reflection provides a wealth of information about your code. One interesting use of this information is to layer scriptability on top of an application, calling code dynamically. Suppose we wanted to do the following:

  1. Given an object, a method name and a list of parameters, execute the matching method on the given object.
  2. Determine from the object's class whether the given method can be executed from the given context (web, command-line, etc.)

Let's tackle step one first: a logical approach is to get the Class for the target object and call getMethod() with the method name and list of parameters to get the desired Method object.

Sounds pretty easy, right? The Java reflection API puts a few stumbling blocks in the way.

Conforming, not Exact

getMethod() finds only methods whose parameter lists are an exact match for the one given, not methods, which can actually be called with that list of parameters. That is, it ignores polymorphism completely when performing a search.

For the following discussion, assume the following definitions:

public class Person {
  public void executeCommand(String s) {
  }

  @Callable(CallLocation.FromWeb)[^1]
  public void giveCommandTo(String s, Person p) {
    p.ExecuteCommand(s);
  }
}

public class Assistant extends Person {
}

public class Manager extends Person {
  List<Person> underlings = new ArrayList<Person>();

  public boolean getIsInChainOfCommand(Person p) {
    return underlings.contains(p);
  }

  public void giveCommandTo(String s, Person p) {
    if (! getIsInChainOfCommand(p)) {
      throw new RuntimeException("Cannot order this person around.");
    }
    p.ExecuteCommand(s);
  }
}

Managers can only order their own underlings around. We expect to be able to call giveCommandTo() with a piece of text and an Assistant, and Java -- polymorphic wunderkind that it is -- obliges. As mentioned above, getMethod("giveCommandTo", {new String(), new Assistant()})1 returns null because Assistant, though a conforming actual parameter, is not an exact match for the formal parameter.

That's a shame. I'm sure getMethod() is much faster for this optimization, but it doesn't really work for applications that would like to benefit from polymorphism. Any application that wants to search for methods that can actually be executed will have to do so itself. In English, we want to get the list of methods on a class and iterate them until the name matches the desired method. If the matching method has the same number of formal parameters as actual parameters and each of the formal parameter types isAssignableFrom the corresponding actual parameter, we have a winner. The code below does this:2

protected Method getConformingMethod(String methodName, Object[] actualParameters, Class<?> cls) {
    Method[] publicMethods = cls.getMethods();
    Method m = null;
    int idxMethod = 0;
    while ((m == null) && (idxMethod < publicMethods.length)) {
      m = publicMethods[idxMethod];
      if (m.getName().equals(methodName)) {
        Class<?>[] formalParameters = m.getParameterTypes();
        if (actualParameters.length == formalParameters.length) {
          int idxParam = 0;
          while ((m != null) && (idxParam < formalParameters.length)) {
            Class<?> param = formalParameters[idxParam];
            if (!param.isAssignableFrom(actualParameters[idxParam].getClass())) {
              m = null;
            }
            idxParam++;
          }
        } else {
          m = null;
        }
      } else {
        m = null;
      }
      idxMethod++;
    }
    return m;
  }

A call to getConformingMethod("giveCommandTo", {new String(), new Assistant()}) returns a match where getMethod() did not. Now that we have our method, we can check whether it can be called or not. For this, we retrieve the annotations on it.

Continue on to part two.



  1. In most cases, the list of parameter objects will already be available. The manifest array declaration is simply to illustrate the actual parameters.

  2. As you can plainly see from the example, the author hates break statements and any other form of engineering multiple return points out of a function. The style takes a bit of getting used to. Using Java 1.5

Immutable Collections

Java supports immutable collections of all kinds, but not in the way you would expect. A naive implementation would declare the immutable (unmodifiable in Java parlance) interface as follows1:

**interface** UnmodifiableList<T> {
  **function** T get();
  **function** int size();
}

There is no way to modify this list -- the API is simply not available. That done, we can now create the modifiable version of the list as follows:

**interface** List<T> **extends** UnmodifiableList<T> {
  **function** void add(T);
  **function** remove(T);
}

A class can now use these interfaces to carefully control access to a list as follows:

**class** SomeClass {
  **private** List<SomeOtherClass> list;

  **function** UnmodifiableList<SomeOtherClass> getList() {
    **return** list;
  }
}

That would be pretty cool, right? Unfortunately, even if you declared these interfaces yourself, the example above does not work. Java's generics support amounts to little more than syntactic sugar, so List<SomeOtherClass> does not conform to UnmodifiableList<SomeOtherClass>. There are several solutions to this problem:

  • Create a result list of the correct type and populate it with the elements of the private list
  • Perform the typecast anyway, ignoring or suppressing the error. Since Java employs erasure to transform generics when compiled, both would compile down to Array<Object> anyway.2
  • Declare a method in the List interface that returns it as an unmodifiable list. This is probably the best solution, as the code for unmodifiability will be defined in one place, the implementing collection.

So that was fun, but how exactly does it work in Java, then? In addition to the limited generics, Java is further hampered by a legacy of old code. This means that they can't (read: won't) change existing interfaces because it might break existing code. Here's how Java defines the two interfaces:

**interface** List<T> {
  **function** T get();
  **function** int size();
  **function** void add(T);
  **function** remove(T);
}

There is no second interface. All lists have methods for adding and removing elements -- even immutable ones. Immutability is enforced at run-time, not compile-time. Pretty cool, huh? Not only that, but List itself doesn't even have a method to return an unmodifiable version of itself because Sun didn't want to add methods to existing interfaces. Instead, you use a static method on the Collections class to get an immutable version of a list.

**class** SomeClass {
  **private** List<SomeOtherClass> list;

  /**
   * Returns an unmodifiable list (treat as read-only).
   */
  **function** List<SomeOtherClass> getList() {
    **return** Collections.unmodifiableList(list);
  }
}

The type system itself has nothing to say about modifiability. Any calling client can happily add elements to and remove elements from the result without any inkling that what they are doing is wrong. The compiler certainly won't tell them; the Javadoc offers the only clue -- in effect supplementing the type systems with comments! When that code is called at run-time, Java will happily issue an UnsupportedOperationException and smile smugly to itself for a job well done.

Say it with me: backwards-compatibility is king!



  1. I know this won't compile; it's Java-esque pseudo code to illustrate the idea.

  2. I'm not sure exactly which container class Java employs during erasure, so I'm using Array as a placeholder here. Using Java 1.5 and Tapestry 4.0.2

Investigating Cayenne

Cayenne has nice-looking modeling tools and a decent API, but has other interesting limitations in their prefetching

Here are a few things I noticed about the framework:

Their explanation of how many queries it takes to get a list of objects, each with 1-n sublink is confusing, at best. I expect it to take exactly one (1) query ... they say two? ... oh, Lord, check out the lovely syntax they have in the "advanced" section below:

query.addPrefetch("paintingArray").setSemantics(
                PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);

Intuitive and beautiful.

  1. No aliased links ... programmer is advised to avoid this problem ... "To-many relationships should not be prefetched if a query qualifier can potentially reduce a number of related objects, resulting in incorrect relationship list." Transaction support is pretty unwieldy -- it's automatic in most cases, but the "best practices" code creating one on your own and handling it is unwieldy, at best:
Transaction.bindThreadTransaction(tx);

try {
    // do something...
    ....
    // if no failures, commit
    tx.commit();
}
catch (Exception ex) {
    tx.setRollbackOnly();
}
finally {
    Transaction.bindThreadTransaction(null);
 
    if (tx.getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) {
        try {
           tx.rollback();
        }
        catch (Exception rollbackEx) {
        }
    }
}

On the other hand, there is this:

Cayenne ensures that each ObjectContext contains at most one instance of each unique persistent object. In other words if two separate independent queries fetched a row with the same primary key, the same object instance will be used in both results. This behavior (not supported by some other frameworks), is extremely important in maintaining consistency of the object graph.

There is also a good page on Object Caching, which explains how objects synchronization is maintained across JVMs. The only line to cause some worry is this one: "Due to concurrency issues discussed above, if a snapshot version conflict occurs, DataRowStore removes a given snapshot from the cache to avoid dealing with concurrency effects on merging." Does this mean that data is lost?

Drawbacks to Hibernate

The comment, Re: iBATIS vs Hibernate, offers some good advice for when to use iBATIS and when to use Hibernate. The damning sentence for Hibernate follows:

If you try to shoehorn hibernate into a relational model created by a DBA who could care less about objects and thinks in terms of tables, columns, relationships and record sets, then you will get along better with your DBA if you use iBATIS, especially if the model is complex and may entail queries with outer joins and nested subqueries.

Since when did outer joins or sub-queries become "complex"? These are exactly the drawbacks we've discovered in Hibernate, as well. You have to do handstands to get it to do an outer join; once you've got one, the object-structure returned by Hibernate is different than it was before and your processing code is useless. Which takes us to this next sentence:

iBATIS is more flexible, has a shorter learning curve, but can take more time to develop and maintain, since you have to write all your queries and if your object model changes you have to go through all your queries and make sure to make all the necessary changes to reflect the changes in your object model.

With Hibernate, you have to re-adjust how you process the query result if you change something that Hibernate considers significant (like restricting an inner join -- a big no no). Each solution has the downside of requiring maintenance when something changes. iBATIS fails outright when it tries mapping (database) fields to (object) properties that no longer exist. With Hibernate, it's possible that the code keeps running fine -- it just starts reporting 20 objects, where before there were 5 (with 15 children distributed among them).

The article, iBATIS 2.0 Released, provides more information in the comments.