Thoughts on handling Translations and Views on Source Code

One of my recent java projects was to be used by users with three different languages. We went with the standard java approach of using properties files for messages. In intellij there is decent tool support for that.
However it seems a bit odd to have a strongly typed language and then rely on string keys for text lookup. At some point we introduced enums representing the keys, but as they were not automatically generated they involved a lot of repetition. Also you are never quite sure how many arguments a message needs.

So I had this idea of using interfaces to represent resource bundles. Each message could be represented as a method, with parameters representing the arguments to the placeholders. It would look somewhat like this:

public interface ExampleMessagePool {
    String sayHello(String name);
    String bye(String name);
    String warning();    
}

From the clients point of view it would works as follows:

var factory = new MessagePoolFactory<ExampleMessagePool>(ExampleMessagePool.class);
 
 
ExampleMessagePool english = factory.getLanguageSource("en");
 
assertEquals("Hello Matthieu!", english.sayHello("Matthieu"));
assertEquals("Good bye Felix!", english.bye("Felix"));
assertEquals("Attention!", english.warning());
 
 
ExampleMessagePool french = factory.getLanguageSource("fr");
 
assertEquals("Bonjour Matthieu!", french.sayHello("Matthieu"));
assertEquals("Au revoir Felix!", french.bye("Felix"));
assertEquals("Attention!", french.warning());
 
 
ExampleMessagePool german = factory.getLanguageSource("de");
 
assertEquals("Guten Tag Matthieu!", german.sayHello("Matthieu"));
assertEquals("Auf Wiedersehen Felix!", german.bye("Felix"));
assertEquals("Achtung!", german.warning());

The interesting point here is that I get completion and also a hint as of which arguments a particular message takes. The MessagePoolFactory takes care of creating instances for the respective languages. The next question is obviously, where these messages do come from. One way would be to use annotations:

@MessagePool(languages={"en", "de", "fr"})
public interface ExampleMessagePool {
    @Translations(
            entries = {
                @Entry(key = "en", value = "Hello {0}!"),
                @Entry(key = "de", value = "Guten Tag {0}!"),
                @Entry(key = "fr", value = "Bonjour {0}!")
            }
    )
    String sayHello(String name);
 
    @Translations(
	        entries = {
	            @Entry(key = "en", value = "Good bye {0}!"),
	            @Entry(key = "de", value = "Auf Wiedersehen {0}!"),
	            @Entry(key = "fr", value = "Au revoir {0}!")
	        }
	)
	String bye(String name);
 
    @Translations(
	        entries = {
	            @Entry(key = "en", value = "Attention!"),
	            @Entry(key = "de", value = "Achtung!"),
	            @Entry(key = "fr", value = "Attention!")
	        }
	)
	String warning();
}

This approach is very sexy in so far as it allows to refactor method and parameter names. Also the implementation is trivial not least because java deals with unicode source files. On the other hand making your translators edit the java sources is probably a bit of a challenge. However you could provide a narrow view on that source code. The eclipse platform lends itself to that kind of experiment, so I actually did a bit of spike. Which I am demoing here:

Whilst this is very cool, it’s an entirely static approach. Especially with translations I find it beneficial if they are stored in a database so that they can be edited at run-time. Ideally some key users can then maintain translations, which are part of their domain anyway. Then the interface could be annotated with some sort of GUID, that could later be used at runtime to identify entries in the database:

public interface ExampleMessagePool {
    @Id("21850286-A914-4C13-88BA-75ACA2248B71")
    String sayHello(String name);
 
    @Id("DA3CD6BE-64E8-4501-A674-0789043CBD6F")
    String bye(String name);
 
    @Id("38211D99-BA2A-4572-9C23-976AC64181D8")
    String warning();    
}

This way the refactorability would be preservered. Also tools support could be provided. Annotating elements with GUUIDs seems to be an interesting concept. Just imagine your database mapping being immune to name changes.

There is definitely some more thinking required here, but it strikes me that the default mechanisms in java are very rudimentary. Much less than a talented developer can dream up in a rainy afternoon.
Further developments could include static or, if you go for the runtime approach, dynamic tools to analyse, whether translations are present, or whether there are duplicates in message pools.

Posted in Software Development | 2 Comments

Don’t Play with Yourself

Some two years ago I had the pleasure of working with a code base that relied heavily on the spring SimpleForm framework. The thing I didn’t like about this framework was the whole controller class hierarchy. Essentially there is about ten super classes and calls get delegated up the whole chain. In theory this is all good OO. So I struggled a bit understanding why I didn’t like it. And as so often when you are struggling a bit of sketching goes a long way:

This sequence diagram degenerated into a christmas tree shape. What is the problem with that? Well these methods operate on different layers. In the case of the SimpleFormController there is methods dealing with Requests and then there is methods dealing with FormBackingObjects. Different levels of abstraction get mixed into a single object (even if they are structured by the inheritance hierarchy). Also this is a point where I struggled a lot with idiomatic smalltalk code. This kind of code might be fine if you are a genius. If you are just a simple developer like I am, probably somethings like this might be much more intelligible to you:

Here each object lives only in a single layer. The same argument can also be used in the long standing debate over private methods, because the receiver of private methods is also self. Now I think there is definitely a case for calling some methods on self, but having a single instance more than twice or three times on your call stack is probably a bad thing.

Posted in Software Development | 1 Comment

Getting Real with Enumerable.java

Two weeks back I posted a video explaining how to get started with Enumerable.java. While this might have been enough information to start playing, there is a lot more to consider when going with Enumerable.java for production use.

Over the past few weeks I went through that experience on my project and here are some of the practices that we found useful. Håkan also released version 0.3.0 that incorporates some of our learnings.

When working in the IDE we used the javaagent to weave the lambdas. However there were a few caveats. In version 0.2.4 you could only black list packages to prevent them from being weaved. In most cases it is easier to specify explicitly for which package to enable weaving. Also when using contemporary java goodness there is other parties doing byte code magic. We experienced these problems with spring’s scoped proxies, therefore we introduced another parameter to filter out classes by a regular expression applied to the full classname. Proxy classes usually come with a lot of dollar signs in their names.
So the vmargs we are using in development are:

-javaagent:lib/deploy/enumerable-agent-0.x.x.jar  
-Dlambda.weaving.included.packages=felix.application 
-Dlambda.weaving.exclude.pattern=\$\$

If you are using eclipse you can specify these parameters as default vm-parameters in your JRE definition:

While using an agent in the ide is acceptable it gets messy, when deploying the application. Essentially all the JVMs on the way to production including your application server would need the agent. What we did instead is, we instrumented our class files in our build using the AOT lambda compiler. So this is a single step after the compilation. If you are using ant it could look somewhat like this:

<target name="lambda" depends="compile">
        <java fork="true"
              classname="lambda.weaving.LambdaCompiler"
              failonerror="true">
 
              <sysproperty key="lambda.weaving.debug" value="true"></sysproperty>
                  <classpath>
                      <path refid="prod"/>
                  </classpath>
              <arg value="prod.jar"></arg>
        </java>
    </target>

Important: The lambda weaver needs debug information on local variables and also you need to encode your source files as utf-8 to get the fancy lambda letter, so perhaps you have to change your compile target like this:

<javac srcdir="src/java" 
            destdir="${basedir}/tempCompile" 
            classpathref="prod"
            encoding="utf8"
            debug="on"
            debuglevel="lines,vars,source"
/>

From a technical point of view this is all you need to do. However there is also the question of how to use the new feature “responsibly”. In our code base we used the generic CollectionUtils to filter and transform Collections. While they are elegant from a theoretical point of view, they are quite an insult to the eye, so our aim was to replace all these with Enumerable.java. Functional operations on collections are very well understood (the method names used in Enumerable.java go at least back to Smalltalk-80, that’s thirty years).

So the advice introduce your team the following methods and aim to restrict the use of lambda expressions to those:

  • select
  • collect
  • find
  • inject
  • groupBy
  • While there is remarkable support for arrays and primitives, try to stick to
    Collections and proper Objects.

I think these alone justify the investment.
Things you should avoid or do only in after proper consideration:

  • Do not declare parameters of function types
  • Do not declare local variables of function types
  • Do not declare fields of function types
  • Do not modify enclosed state from within the closure, i.e. local variables or fields
  • Generally avoid side effects

The typical transformation we did, looked something like this:

    private Set<Order.Status> retrieveOrderStatuses() {
        Set<Order.Status> statuses = new HashSet<Order.Status>();
        if (orders == null) return statuses;
 
        for (Order  order : orders) {
            statuses.add(order.getStatus());
        }
        return statuses;
    }

becomes:

    @LambdaParameter private static Order o;
    private Set<Order.Status> retrieveOrderStatuses() {
        if (orders == null) return emptySet();
        return  collect(orders, ?(o, o.getStatus())).toSet();
    }

Because getting the lambda character (you might also want to use the alias fn) is a bit tricky you might want to use this java editor template for eclipse that also sorts out the static import:

?(${impst:importStatic('lambda.Lambda.*')}${cursor})

Sticking to these simple rules actually helped us getting away from the anonymous inner classes and CollectionUtils and that was an easy sell to the mostly mathematically inclined team. In my opinion the fact that lambdas are restricted to expressions is actually a good thing.

Posted in Software Development | Leave a comment

Get Closures for Java Now!

The general state of affairs at Sun/ Oracle is very sad. If you are like me, you cannot take this much longer. Fortunately enough my esteemed colleague Håkan Råberg has invented what is at least a molotov cocktail perhaps even a guillotine to the revolution of java software development. Yes, I am talking about the modestly named Enumerable.java, which brings the Ruby enumerable module and closures to java. Without a special compiler, just by pushing the boundaries and enhancing byte code.

I created this little screencast, that shows how to get up and running with Enumerable.java:

There is also a hi-res version of the videos on google docs (approx. 20M download size).

For more examples and explanation watch Håkan’s blog and read the source.

Now, go, download and, enjoy!

Posted in Software Development | 2 Comments

Contemporary LaTeX Resource

I am currently using LaTeX to produce PDF output for a multilingual (polish characters anyone) business application. I hope to write a proper post about this once I am done. But I have to post the url of this blog which deals with doing nice contemporary typesetting with LaTeX.

Posted in Software Development | 1 Comment

The Gospel

Today’s lesson is from the book of stackoverflow 65,35-21:

It’s a well known fact, that Oracle treats empty strings as null.

I knew about that, but somehow I forgot…

Posted in Software Development | 1 Comment

The Train Build Monitor

On our current project we came up with a model train build monitor. The objective was to have the train move, while the build is green and to stop, when it goes red. The whole thing looks some what like this:

As a USB interface we chose to go for the Velleman K8055, which is available for about forty pounds and provides eight digital and two analogue outputs as well as two analogue and five digital inputs. The analogue outputs are provided as pwm signal.
The outputs are all open-collectors. Being a good developer I did of course anticipate a few more use-cases and hence designed the controller, so we could actually control the speed as well as the direction in which the train in moving. Essentially it uses a transistor to switch the train (using the pwm) and a relay to reverse the direction (yes this is somewhat lame). Also there is two free-wheeling diodes to protect the electronics from the high inductivity of the relay and the trains motor. This is the circuit diagram of the controller that goes between the K8055 and the train:

The K0855-board ships with a DLL to control the IO. Apparently there is a linux driver, which is much better than the windows version, but we are in a bit of a windows shop, so we went with the DLL. It turned out wrapping a DLL in a ruby script is fairly trivial:

require 'Win32API'
 
open = Win32API.new("K8055D", "OpenDevice", ['L'] , 'L')
outputAnalog = Win32API.new("K8055D", "OutputAnalogChannel", ['L','L'],'V')
outputDigital = Win32API.new("K8055D", "WriteAllDigital", ['L'],'V')
inputDigital = Win32API.new("K8055D", "ReadAllDigital", [],'L')
 
open.Call(0)
 
outputAnalog.Call(1, 10) # setting DA channel 1 to 10
outputDigital.Call(128)    # reversing

Future plans include figuring out where the train currently is to stop in the station. The original plan was to use a reed switch, but that proved to be a bit unreliable, so the current thinking involves using a camera and something like hornetseye to get the exact position of the train.

Posted in Software Development | 2 Comments

Wieder einmal ist es die Deutsche Bahn…

…der wir eine, wie ich finde, kleine sprachliche Perle verdanken: Das Wort “Unterwegsbahnhof”.

Posted in Sprache | Leave a comment

Not exactly a consultant hat…

…but still a valuable addition to my professional wardrobe. That helps me being mindful of what I am and what I am not.

13119585-19215581

Posted in Software Development | Leave a comment

What’s missing in Java 7

Assuming Sun manages to get “closures” into Java7 there is still a few things that are lacking. Today I once again ran into the restrictions around annotations. The .Net solution is simply more elegant. The fact that I can’t use arbitrary classes for annotation parameters is arbitrary and promotes widespread abuse of enums. Also that these guys aren’t regular classes with methods and all is quite annoying.

Using arbitrary classes as annotations would actually make the language simpler and is therefore good…

Posted in Software Development | 1 Comment