Skip to content
A typesafe generated API on top of l10n/i18n resource bundles
Branch: master
Clone or download



Sofia is a typesafe(ish) layer on top of a properties file. Given a properties file, it will generate a java class providing compile time checks that you’re using values that actually exist in your properties file. It supports multiple locales if you provide them.

A simple example looks like this. For this properties file:'m the first test property need parameters {0} and {1} Property''s date {0,date,full} and now a number {1,number}

@error.another=I'm an error'm just a warning, though.

lonely=I'm only in the default bundle.

a java file will be generated with the following interface:

public class com.antwerkz.sofia.Sofia {
  public static java.lang.String another(java.util.Locale...);
  public static void logAnother(java.util.Locale...);
  public static java.lang.String dateProperty(java.util.Date, java.lang.Number, java.util.Locale...);
  public static void logDateProperty(java.util.Date, java.lang.Number, java.util.Locale...);
  public static java.lang.String me(java.util.Locale...);
  public static void logMe(java.util.Locale...);
  public static java.lang.String lonely(java.util.Locale...);
  public static java.lang.String newProperty(java.util.Locale...);
  public static java.lang.String parameterizedPropertyLongName(java.lang.Object, java.lang.Object, java.util.Locale...);
  public static java.lang.String testProperty(java.util.Locale...);

There are some other details but they’re mostly irrelevant. Feel free to explore the generated file if you’re really interested. What you see here is one method for each property listed in your properties file. Those properties that take parameters result in methods that take parameters as well. Notice that each parameter is typed according to the formatting specified in the properties file. If no formatting is defined, "Object" is used for that parameter type.

Also note that each method takes a Locale…​ parameter. This allows sofia to generate one method per property while supporting an optional Locale to be supplied without having to generate two identical methods or having to pass in a null to a "singleton" parameter. Multiple Locales can be passed in but only one will be used.

So …​ why?

When I worked on glassfish, we’d standardized on a library that did something similar. My biggest complaint about that one is that all the generated methods WERE IN ALL CAPS WHICH MADE READING THE CODE AWKWARD. Also, I’m not really sure where the source for that library is so patching it would be tricky. In any case, it turned out to be a very handy facet to a project which makes use of properties files to manage its messages so I wanted to improve on it where I could.

Great. How do I use it?

Add the following to your pom.xml:


There are a few configuration options:

Value Description Default


The base properties file to use



Generated source location



Use a specific logger (supported: none, jul, slf4j)



Defines the package for the generated class



Change the character coding used when reading property files


If you’d like continuous monitoring and regeneration of your files, there’s also "sofia:watch." Using this target, sofia will watch for changes to your input file and regenerate as needed.

You can’t perform that action at this time.