Projects must use ICU4J if they wish to participate in the Galileo release of Eclipse, due this summer. Though such a requirement may make good sense in theory, in practice adopting ICU4J is painful. Not only does this policy stifle innovation for questionable gain, such a burden makes participating in the Eclipse ecosystem less attractive.

ICU4J is designed to be a drop-in replacement for Java classes that perform poorly or behave incorrectly. The idea is that you change your import statements, recompile and everything works. In applying this technique to Mylyn WikiText, I’ve discovered that it’s not that easy.

Mylyn WikiText makes use of two classes that are to be replaced by ICU4J equivalents: MessageFormat and ResourceBundle.

ResourceBundle

ResourceBundle conversion should be easy, right? ICU4J provides UResourceBundle, which extends ResourceBundle.... wow, that’s great. All I should have to do is replace ResourceBundle.getBundle() with UResourceBundle.getBundleInstance()... easy peasy. Unfortunately, not so easy.

Previously I had used the JDT ‘Externalize Strings’ wizard to externalize strings in my plug-in. The JDT nicely created a utility class Messages.java alongside the resource bundle messages.properties. This worked really well and has been in use for some time. Unfortunately after converting to ICU4J UResourceBundle throws a NoClassDefFoundError because of the presence of the Messages class. It seems that UResourceBundle cannot handle a resource bundle alongside a class by a similar name. While I’ve logged bug 272166 to track this issue and have it fixed, it doesn’t help me. Even if the bug gets fixed in time for Galileo, Mylyn WikiText must work on Eclipse 3.3 and 3.4 as well.

It gets worse. Mylyn WikiText is already translated to German and Japanese. Resource bundle message keys must remain relatively stable in order to avoid losing those translations. JDT creates message keys containing dots ‘.’, and the Eclipse externalized string pattern cannot have dots in message keys... so I cannot convert over to the Eclipse externalized string pattern without losing these translations.

MessageFormat

MessageFormat evolved for Java 5: it’s format() method became a var-args method, meaning that you can pass a variable number of arguments to it. WikiText makes extensive use of this method, so you’ll see code such as this:


MessageFormat.format(messageTemplate,arg1,arg2)

ICU4J does not have a var-args method equivalent — it seems that ICU4J has not evolved for Java 5. To adopt ICU4J’s MessageFormat, all calls had to be converted as follows:


MessageFormat.format(messageTemplate, new Object[] { arg1, arg2 })

While the conversion can be achieved using regular expressions, the resulting code is less readable and more prone to bugs. Localization is hard enough as it is without having to jump through age-old languageisms.

Summary

While converting all plug-ins to ICU4J may make sense for some, making it a requirement for Galileo participation has caused me and presumably others a lot of work. From what I can see ICU4J brings little or no value to the users of my project. This is one case where good intentions with policy have a substantial negative impact. In my case, the time I’m spending converting to ICU4J could have been used to innovate or improve the quality of WikiText. Instead I’m jumping through hoops with no apparent benefit for me, my project or my users.