In my previous post: I18n with GNU Gettext utilities, I covered the basis of GNU gettext utilities. In this new post, I’ll explain how to use gettext to internationalize .java files.

Gettext Commons is Java library that makes use of GNU gettext utilities. It will enable us to mark texts to be localized in source code as well as taking care of retrieving localized strings. So, we can think of Gettext Commons as a bridge between our project and MO (Message Object) files generated as result of a gettext workflow.

Gettext Commons comes as .jar. There’s even a Maven repository for it. So, if you’re running a Maven2 project, add the following lines to your POM file:


<!– Add Gettext commons repository –>

gettext-commons-site
http://gettext-commons.googlecode.com/svn/maven-repository


<!– Add Gettext commons dependency –>

org.xnap.commons
gettext-commons
0.9.6

Apart from gettext-commons.jar library, there’s also a Gettext Maven plugin. This plugin comes apart from the .jar library, and it’s not necessary for using gettext from Java.

Unfortunately Gettext Commons website documentarion is a bit outdated, lacking information about how to setup the plugin, latest version, and parameters for every goal. For installing the plugin add the following lines to your POM file:


<!– Add Gettext Maven plugin repository –>

gettext-commons-site
http://gettext-commons.googlecode.com/svn/maven-repository


<!– Add Gettext Maven plugin –>

org.xnap.commons
maven-gettext-plugin
1.2.0

${project.build.sourceDirectory}/../resources/i18n
i18n.Messages
-k_


Let’s check first how the plugin works. Gettext Maven plugin is basically a wrapper  of some GNU gettext commands: xgettext, msmerge and msgfmt. Run the following maven goals from command line to:

  • mvn gettext:gettext, parses .java files and generates keys.pot file.
  • mvn gettext:merge, executes previous command plus generates locale files (es.po, pt.po, jp.po, etc).
  • mvn gettext:dist, executes previous command plus generates a MO (Message Object) file, Messages_XX.class, for every locale file.

Each goal accepts a different range of parameters. Set parameters under ** tag. In the example above, I’ve set up three parameters:

  • poDirectory, directory where to place locale files (.po files) as a result of executing mvn gettext:merge. ${project.build.sourceDirectory} is a predefined constant that points to the root folder of our project source code, usually src/main/java.
  • targetBundle, java package where to place MO files as a result of executing mvn gettext:dist. Bear in mind that a MO files are binary files, or in case of working with Java, .class files. The name of resulting MO files have the following format: Messages_XX.class, and they are stored at target/classes directory.
  • keywords, list of keywords used to mark texts in source code. In my case, I’ve used _ as a marker.

There’s even more parameters, but unfortunately I couldn’t find any piece of documentation which covered them. If you want to find out more, consider downloading the source code or take a look at it online. On the contrary, it’s well documented and easy to understand.

Notice that you don’t neccessary have to use gettext-maven-plugin to parse source code and generate MO files, you can still use GNU Gettext command-line utilities to do that. In addition, running mvn gettext:merge fails if target .po file doesn’t exist. Remember that:

msgmerge -U es.po keys.pot

just updates msgids *from *.pot file to .po file, it never creates a target .po file. For doing that you must run msginit (you can also copy .pot file to locale .po file, but you should remember to adjust the header to your needs, pay attention particularly to attribute charset).

So, basically in this post I’ve covered how to setup Gettext Commons library and Gettext Commons Maven plugin and how to use the latter in a Maven2 project. In my next post, I’ll focus exclusively on how to use Gettext Commons for i18n .java files.