Saturday, August 07, 2010

Code Generation with Xtext

Recently I attended a local rheinJUG meeting in Düsseldorf. While the topic of the session was Eclipse e4, the night’s sponsor itemis provided some handouts on Xtext which got me very interested. The reason is that currently at work we are developing a mobile Java application (J9, CDC/Foundation 1.1 on Windows CE6) for which we needed an easy to use and reliable way for configuring navigation through the application.
In a previous iteration we had – mostly because of time constraints – hard coded most of the navigational paths, but this time the app is more complex and doing that again was not really an option. First we thought about an XML based configuration, but this seemed to be a hassle to write (and read) and also would mean we would have to pay the price of parsing it on every application startup.
Enter Xtext: An Eclipse based framework/library for building text based DSLs. In short, you just provide a grammar description of a new DSL to suit your needs and with – literally – just a few mouse clicks you are provided with a content-assist, syntax-highlight, outline-view-enabled Eclipse editor and optionally a code generator based on that language.

Getting started: Sample Grammar

There is a nice tutorial provided as part of the Xtext documentation, but I believe it might be beneficial to provide another example of how to put a DSL to good use. I will not go into every step in great detail, because setting up Xtext is Eclipse 3.6 Helios is just a matter of putting an Update Site URL in, and the New Project wizard provided makes the initial setup a snap. I assume, you have already set up Eclipse and Xtext and created a new Xtext project including a generator project (activate the corresponding checkbox when going through the wizard). In this post I am assuming a project name of com.danielschneller.navi.dsl and a file extension of .navi.
When finished we will have the infrastructure ready for editing, parsing and generating code based on files like these:

Friday, August 06, 2010

[SCR] Found components with duplicated names inside their bundle!

Today I was briefly confused by an error message issued by the OSGi Equinox runtime’s Declarative Services runtime which I did not understand immediately. For your – and my own – reference find the solution here.
First, this was the error message I got:
1281104579615=1::[SCR] Found components with duplicated names inside their bundle!
 This component will not be processed: Component[
    name = networksimulation
    factory = null
    autoenable = true
    immediate = true
    implementation = com.danielschneller.sim.network.NetworkStateSimulation
    properties = {devicevendor=DanielSchneller, simulation=true}
    serviceFactory = false
    serviceInterface = [com.danielschneller.network.NetworkState]
    references = {
        Reference[name = LOG, interface = org.osgi.service.log.LogService, 
        policy = static, cardinality = 0..1, target = null, bind = null, unbind = null]
    }
    located in bundle = com.danielschneller.sim.network_1.1.0.qualifier [49]
]
Apparently the component name networksimulation was used by two components in the same bundle. Well, that’s why you are encouraged to use package-name like identifiers; however this was not the problem. Changing it to com.danielschneller.sim.net.simulation which was guaranteed to be unique in my case still left the error the same:
1281104579615=1::[SCR] Found components with duplicated names inside their bundle!
This component will not be processed: Component[
    name = com.danielschneller.sim.net.simulation
    factory = null
    ...
To make it short, this is what happened: I had added this component’s description to a bundle that already contained some more using the Eclipse wizard for new service components.
That very fine wizard dutifully added the new filename to the Manifest is the Service-Component: line. Unfortunately in this case it led to:
Service-Component: OSGI-INF/*.xml, networksimulation.xml
At launch time apparently the wildcard was expanded, already including the new file, and then added at the end again. Apparently there is no sanitizing done (like adding the filenames to a Set instead of a List), which results in a second attempt of registering the same component a second time. I will go and file a bug with Eclipse for this, There already is a filed, but unfixed bug for this (Eclipse Bug #278540) but till then just make sure that when you use wildcards in the Service-Component Manifest header it does not cause any duplicates.