Friday, March 22, 2013

Working With JSON Data From Java

I am preparing excercises for the Xtend tutorial Sebastian and I will be giving on Monday at EclipseCon.  For one excercise we parse an itunes music library in JSON format in order to execute different queries on that data. Of course the data is well structured, so why not adding a thin typed facade over the generic JSON objects?   I've built a little active annotation which let's you do the following:

Step 1: Find some Data

Let’s take data from Yahoo as an example. The data contains the most popular new album releases. Here's the first album:

{
 "query": {
  "count": 24,
  "created": "2013-03-21T20:13:42Z",
  "lang": "en-US",
  "results": {
   "Release": [
    {
     "UPC": "602527291567",
     "explicit": "0",
     "flags": "2",
     "id": "218641405",
     "label": "Streamline/Interscope/Kon Live",
     "rating": "-1",
     "releaseDate": "2009-11-23T08:00:00Z",
     "releaseYear": "2009",
     "rights": "160",
     "title": "The Fame Monster",
     "typeID": "2",
     "url": "http://new.music.yahoo.com/lady-gaga/albums/fame-monster--218641405",
     "Artist": {
      "catzillaID": "0",
      "flags": "115202",
      "hotzillaID": "1810013384",
      "id": "58959115",
      "name": "Lady Gaga",
      "rating": "-1",
      "trackCount": "172",
      "url": "http://new.music.yahoo.com/lady-gaga/",
      "website": "http://www.ladygaga.com/"
     },
     "ItemInfo": {
      "ChartPosition": {
       "last": "1",
       "this": "1"
      }
     }
    },
.... 
}

Step 2: Copy the example data into a @Jsonized annotation:

@Jsonized('{
 "query": {
  "count": 24,
  "created": "2013-03-21T20:13:42Z",
  "lang": "en-US",
  "results": {
   "Release": [
    {
     "UPC": "602527291567",
     "explicit": "0",
     "flags": "2",
     "id": "218641405",
     "label": "Streamline/Interscope/Kon Live",
     "rating": "-1",
     "releaseDate": "2009-11-23T08:00:00Z",
     "releaseYear": "2009",
     "rights": "160",
     "title": "The Fame Monster",
     "typeID": "2",
     "url": "http://new.music.yahoo.com/lady-gaga/albums/fame-monster--218641405",
     "Artist": {
      "catzillaID": "0",
      "flags": "115202",
      "hotzillaID": "1810013384",
      "id": "58959115",
      "name": "Lady Gaga",
      "rating": "-1",
      "trackCount": "172",
      "url": "http://new.music.yahoo.com/lady-gaga/",
      "website": "http://www.ladygaga.com/"
     },
     "ItemInfo": {
      "ChartPosition": {
       "last": "1",
       "now": "1"
      }
     }
    }]
   }
  }
}')
class MusicReleases {
  // empty
}

Step 3: Enjoy statically-typed accessor methods!

The annotation will create getters and setters derived from the example data. It's just a super thin layer and you have full access to the underlying JsonObject if you want to go more dynamic. If you want to learn how to do such things, you should come to our tutorial. It's going to be fun!

Wednesday, March 20, 2013

Xtend 2.4 now available!

The committer team behind Eclipse Xtend is proud to announce the availability of Version 2.4. The new release has over 300 bug fixes. The most important enhancements are:

Active Annotations

They are Lisp-like macros for Java (or Xtend). You declare an annotation and explain to the compiler how annotated elements should be translated to Java source code. The compiler will find those annotations on the classpath and execute them during compilation. The IDE and the compiler are fully aware of how annotations contribute to the compilation process, such that content assist, navigation, linking and error messages all reflect the changes appropriately.
You have to see it in action, it is code generation like it should be! Read More

New Type System

Xtend 2.4 has gotten a whole new type system implementation, which not only improves the compilation performance but fixes many many outstanding typing issues. Also the type inference algorithm has become much smarter and even takes the control flow into account for type inference. Xtend can even infer types where other languages such as Scala fail.

Android Support

Xtend is a perfect match for Android development as it relies on the JDK and comes with very little extra dependencies. The new version has special support for debugging Android emulators and some other goodies.

New Language Features

Xtend 2.4 allows to turn local variables and parameters into extension providers, comes with a neat literal syntax for immutable collections, many new operators and some other enhancements.

New IDE Features

The Eclipse plug-in now supports formatting, more quick fixes, more refactorings, better content assist and more little gems which let you get into a smoeeth development flow.

Read the full release notes and get the release

Many Thanks

... to all the committers and contributors who have put this together: Sebastian Zarnekow, Jan Köhnlein, Dennis Hübner, Moritz Eysholdt, Holger Schill, Sebastian Benz, Knut Wannheden, Natalia Ossipova, Anton Kosyakov, Christian Hülsmeier, Stefan Oehme, Ed Merks, Benjamin Schwertfeger, Lieven Lemiengre, Hendrik Eeckhaut, Christoph Kulla, and many more!

Saturday, March 16, 2013

Fun With Active Annotations: My Little REST-Server API

These days I've been playing around a lot with Xtend's new language feature addition, called Active Annotations. It's so exciting want kind of things you can do with them. Today I prototyped a nice little REST-API (code can be found at github):

@HttpHandler class HelloXtend {

  @Get('/sayHello/:name') def sayHello() '''
    <html>
      <title>Hello «name»!</title>
      <body>
        <h1>Hello «name»!</h1>
      </body>
    </html>
  '''
 
  @Get('/sayHello/:firstName/:LastName') def sayHello() '''
    <html>
      <title>Hello «firstName» «LastName»!</title>
      <body>
        <h1>Hello «firstName» «LastName»!</h1>
      </body>
    </html>
  '''

  def static void main(String[] args) throws Exception {
    new Server(4711) => [
      handler = new HelloXtend
      start 
      join
    ]
  } 
}

This is a single class with no further framework directly running an embedded Jetty server. The interesting part here is, that you don't have to redeclare the parameters, as the active HttpHandler annotation will automatically add them to the method. See the method is overloaded but both declare zero parameters? That's usually a compiler error, but here they actually have five resp. six parameters, because my annotation adds the parameters from the pattern in the @Get annotation as well as the original parameters from Jetty's handle method signature. Just so you can use them when needed.

Not only the compiler is aware of the changes caused by the annotation, but so is the IDE. Content assist, navigation, outline views etc. just work as expected.

This is how it works

The HttpHandler implements org.eclipse.jetty.server.handler.AbstractHandler and adds a synthetic implementation of the method handle(). The effective code it adds to the class we've seen above is :

// generated, synthetic Java code
public void handle(final String target
                 , final Request baseRequest
                 , final HttpServletRequest request
                 , final HttpServletResponse response) throws IOException, ServletException {
  {
    Matcher sayHelloMatcher = Pattern.compile("\\/sayHello\\/(\\w+)").matcher(target);
    if (sayHelloMatcher.matches()) {
      String name = sayHelloMatcher.group(1);
      response.setContentType("text/html;charset=utf-8");
      response.setStatus(HttpServletResponse.SC_OK);
      response.getWriter().println(sayHello(name, target, baseRequest, request, response));
      baseRequest.setHandled(true);
    }
  }
  {
    Matcher sayHelloMatcher = Pattern.compile("\\/sayHello\\/(\\w+)\\/(\\w+)").matcher(target);
    if (sayHelloMatcher.matches()) {
      String firstName = sayHelloMatcher.group(1);
      String LastName = sayHelloMatcher.group(2);
      response.setContentType("text/html;charset=utf-8");
      response.setStatus(HttpServletResponse.SC_OK);
      response.getWriter().println(
          sayHello(firstName, LastName, target, baseRequest, request, response));
      baseRequest.setHandled(true);
    }
  }
}

Of course there's some room for optimizations :-) but I hope you get the idea. The implementation of the @HttpHandler and its processor is added below :

@Active(typeof(HttpHandlerProcessor))
annotation HttpHandler {
}

annotation Get {
 String value
}

class HttpHandlerProcessor implements TransformationParticipant<MutableClassDeclaration> {
 
  override doTransform(List<? extends MutableClassDeclaration> annotatedTargetElements, 
                       extension TransformationContext context) {
    val httpGet = typeof(Get).findTypeGlobally
    for (clazz : annotatedTargetElements) {
      clazz.extendedClass = typeof(AbstractHandler).newTypeReference
      val annotatedMethods = 
          clazz.declaredMethods.filter[findAnnotation(httpGet)?.getValue('value')!=null]
  
      // add and implement the Jetty's handle method
      clazz.addMethod('handle') [
        returnType = primitiveVoid
        addParameter('target', string)
        addParameter('baseRequest', typeof(Request).newTypeReference) 
        addParameter('request', typeof(HttpServletRequest).newTypeReference) 
        addParameter('response', typeof(HttpServletResponse).newTypeReference)
    
        setExceptions(typeof(IOException).newTypeReference
                    , typeof(ServletException).newTypeReference)
    
        body = ['''
          «FOR m : annotatedMethods»
            {
            «toJavaCode(typeof(Matcher).newTypeReference)» matcher = 
                «toJavaCode(typeof(Pattern).newTypeReference)»
                .compile("«m.getPattern(httpGet)»").matcher(target);
              if (matcher.matches()) {
                «var i = 0»
                «FOR v : m.getVariables(httpGet)»
                  String «v» = matcher.group(«i=i+1»);
                «ENDFOR»
                response.setContentType("text/html;charset=utf-8");
                response.setStatus(HttpServletResponse.SC_OK);
                response.getWriter().println(
                    «m.simpleName»(«m.getVariables(httpGet).map[it+', ']
                    .join»target, baseRequest, request, response));
  baseRequest.setHandled(true);
              }
            }
          «ENDFOR»
        ''']
      ]
  
      // enhance the handler methods
      for (m : annotatedMethods) {
        for (variable : m.getVariables(httpGet)) {
          m.addParameter(variable, string)
        }
        m.addParameter('target', string)
        m.addParameter('baseRequest', typeof(Request).newTypeReference) 
        m.addParameter('request', typeof(HttpServletRequest).newTypeReference) 
        m.addParameter('response', typeof(HttpServletResponse).newTypeReference)
      }
    }
  }

  private def getVariables(MutableMethodDeclaration m, Type annotationType) {
    // parses the pattern in @Get and returns the variable names
  }
 
  private def getPattern(MutableMethodDeclaration m, Type annotationType) {
    // replaces the variables in the pattern with (\\w+) groups, so we can use it as a regex pattern.
  }
}

Friday, March 01, 2013

Xtend's New Type System

"We are almost at a stage where only double PhDs in math & comp.sc can qualify for Java compiler writers !"

(Srikanth S. Adayapalam (from Eclipse JDT) on the complexity of type inference in Java 8)

As Xtend implements Java's typesystem, we have to deal with exactly the same amount of complexity ... oh wait it's even better as Xtend has

  • advanced type inference,
  • sugared feature calls for properties,
  • operator overloading,
  • an implicit 'it' and
  • extension methods (which are not only static as in C#)
  • etc.
So you better add a couple more PhDs to the mix.

Write once, run ...

We are used to writing key parts of our software twice (at least!). The old type system did its job in the beginning but as we added more and more corner cases and complex type inference scenarios with lambdas and such it started to become too slow and too complex to be further enhanced. Good we have a solid test suite so we actually noticed the point at which even harmless looking changes broke existing tests... To make a long story short: Last year in April we decided to rewrite it from scratch.

The Lonesome Hero

Sebastian had some very promising ideas around a completely different architecture which would not only improve performance but also would allow everyone to better understand and debug the code again. We couldn't afford stopping all other developments and maintenance so one team member had to take the journey while the others were working on cool new features. Almost a year ago Sebastian started work on a complete rewrite. We discussed language semantics from time to time and such things but I rarely looked at the actual code. Most of the semantics were clear as it is based on the Java Language Specification and could be proved with the different Java compilers. So he was climbing this huge mountain all alone.
I know it was super risky and that it's not a good idea to rely such an important part of a project on just one person. If he had failed we had wasted a year. But I knew he would do it (And if he couldn't I don't know who else could).

It has been a long time and we even had to postpone the release which was initially planned for December. Finally by the end of January the new type system implementation was in a state that it could be activated and replace the old one. The switch was super smooth. It just worked.

Here is the corresponding bugzilla, which has been closed just yesterday. It blocked 95 downstream bugs! Most of them are now fixed, we just had to go through them and test, verify and close them. Not only that, the performance was already as good as the old one in the beginning without any further profiling and improvements. With just a little optimisation we were already able to improve the performance by 25%.

Also worth noting is, that the whole team was able to start working in the new code base after just two days of introduction. The code definitely is much easier to grasp and to debug yet covers much more of the essential complexity. Also we have an even more comprehensive test suite now. With over 20.000 unit tests you can confident that you don't accidentally break something. All tests run against the lower version bounds as well as the upper version bounds of our dependencies. There's no way software like this can be maintained and evolved without such a test suite.

The new type system is an incredible piece of engineering and a huge success. It's the basis for an awesome upcoming release of Xtend with many cool new features and enhancements.
Sebastian, I owe you one and so does the growing Xtend community!

Monday, December 17, 2012

Java 8 vs. Xtend

As you might know Java 8 will finally bring an important new feature to the Java programming language :
Lambda Expressions, a feature already supported by many other languages, such as Xtend

Xtend is a statically typed JVM language that translates to readable Java source code. It's very different to other JVM languages in the sense that aims to be a better Java by better supporting existing Java idioms and fully supporting the existing ecoystem. Xtend doesn't force you to rewrite your existing Java apps or drop your beloved and well-proven frameworks, but instead allows for using existing Java APIs in a much nicer way without any interoperability issues. In contrast to e.g. Scala or Clojure it is more like an extension to Java than a replacement.

Identifying and supporting existing Java idioms is not too hard given the huge existing code base but what about the future? Will Xtend also be a better match for the upcoming Java 8 libraries which were explicitly defined for the new Java 8 lambda syntax?

To find out I simply looked at Brian Goetz’s latest version of State of the Lambda : Libraries Edition and translated the contained Java code examples to Xtend.

In the following you see the code for Java as written by Brian and the translation to Xtend. Both are using the exact same Java 8 APIs and contain the same amount of static type information!

Example 1

Java 8:
shapes.forEach(s -> { s.setColor(RED); });
Xtend:
shapes.forEach[color = RED]

This first example already reveals most of the important differences.

First the general syntax for a lambda expression in Java is using an arrow (->), while Xtend uses squared brackets (like smalltalk). Also in Xtend a lambda expression doesn't need to be passed using braces. Although you could write shapes.forEach([color = RED]) you don't need to.

In Java 8 the body of a lambda is either a block or a single expression. So whenever you need to use a statement you have to add the curly braces and semicolons. In Xtend everything is an expression and the lambda itself is already a block expression.

In Xtend you can omit the declaration of a parameter name. In that case the parameter is called 'it' and is implicit (similarly to 'this'). If you want to give it a name you do it like this : shapes.forEach[ s| s.color = RED]

Unrelated to Lambdas but interesting in this case: Xtend allows to use assignments to call setter methods.

Example 2

Java 8:
shapes.stream()
      .filter(s -> s.getColor() == BLUE)
      .forEach(s -> { s.setColor(RED); });
Xtend:
shapes.stream
      .filter[color == BLUE]
      .forEach[color = RED]

Not too much new stuff in here. Xtend lets you omit empty parenthesis and you can call a getter using the property's name.

Example 3

Java 8:
List<Shape> blue = 
    shapes.stream()
          .filter(s -> s.getColor() == BLUE)
          .into(new ArrayList<>());
Xtend:
val blue = 
    shapes.stream
          .filter[color == BLUE]
          .into(new ArrayList)

Here we see type inference in action. While you can use the diamond operator in Java, you can leave it out in Xtend. Also the variable doesn't need to be explicitly typed as the type can be fully inferred from the right hand side.

Example 4

Java 8:
Set<Box> hasBlueShape = 
    shapes.stream()
          .filter(s -> s.getColor() == BLUE)
          .map(s -> s.getContainingBox())
          .into(new HashSet<>());
Xtend:
val hasBlueShape = 
    shapes.stream
          .filter[color == BLUE]
          .map[containingBox]
          .into(new HashSet)

Note how readable the lambdas get when you can leave out all the cryptic clutter. Let's compare a last example from a later section of the document:

Example 5

Java 8:
List<Album> sortedFavs =
    albums.stream()
          .filter(a -> a.tracks.anyMatch(t -> (t.rating >= 4)))
          .sorted(comparing(a -> a.name))
          .into(new ArrayList<>());
Xtend:
val sortedFavs =
    albums.stream
          .filter[tracks.anyMatch[rating >= 4]]
          .sorted(comparing[name])
          .into(new ArrayList)

Although the libraries as well as the examples have been written for Java 8, the Xtend code is still much less cluttered with symbols and therefore significantly more readable. Yet the type information is exactly the same! Xtend is just a bit smarter with type inference and is syntactically less rigid.

Besides that and the fact the Xtend compiles to readable Java 5 code, it has many other important features to offer.

Thursday, November 15, 2012

Active Annotations Explained - JavaFX Properties

Today I'd like to give a more detailed example of how active annotations can be used to solve real world problems. Active annotations are an upcoming language feature for Eclipse Xtend, which allow you to participate in the translation step from Xtend code to Java using annotations.

JavaFX Properties

JavaFX comes with a very nice binding and properties framework, which allows for easy connection of model properties and widgets. It even has support for expressions, like String concatenations, which are reevaluated automatically, when a property changes.

I have used it in a login screen, such that the welcome message get's updated when you type in the user name.

Unfortunately defining JavaFX beans is not so nice, as it requires a lot of boilerplate. Michael Heinrichs, technical lead of JavaFX Properties, recommends the following pattern in his blog:

// Java boilerplate
public class Login {

  private String userName = "";

  private SimpleStringProperty userNameProperty;

  public String getUserName() {
    return (this.userNameProperty != null)? this.userNameProperty.get() : this.userName;
  }

  public void setUserName(final String userName) {
    if (userNameProperty != null) {
      this.userNameProperty.set(userName);
    } else {
      this.userName = userName;
    }
  }

  public SimpleStringProperty userNameProperty() {
    if (this.userNameProperty == null) { 
      this.userNameProperty = new SimpleStringProperty(this, "userName", this.userName);
    }
    return this.userNameProperty;
  }

  // ... same pattern for the password goes here

}
  
That's a lot of code. Given that we usually have to map a lot of properties to the UI, you don't want to write and maintain that.

Code generation to the rescue?

The typical solution in those scenarios is to come up with a little DSL and a code generator. In Java land we really know how to do that and there is easy to use technology available to build ... yet another entity DSL. And it's definitely a much better approach than maintaining above's code by hand, but ...

The big advantage of frameworks such as Xtext is the flexibility they provide. You can build all kind of tooling and choose the right syntax for the problem. No compromises. However, there are certain classes of DSLs which really don't need or use the syntactic flexibility since they are close to class-like structures : Entities, Services, etc.

In addition building an external DSL introduces a bit of an extra complexity in the development turnarounds: You'll have to maintain an Eclipse Plug-In and deploy it synchronously with the rest of your framework to all developers in your team. And just like everything else in your project, the DSL and the code generation evolve over time. So you have to keep everything in sync and deploy and install new Eclipse plug-ins every time your DSL enhances.

Don't get me wrong there are many situations where the additional flexibility of Xtext is extremely useful, but for a certain class of DSLs you are better off with active annotations.

JavaFX Beans with Active Annotations

So let's see how we can replace JavaFX beans like the one shown above with a more readable and maintainable variant.

First we replace the Java class with the following Xtend class:

@FXBean class Login {
  String userName
  String password
}

Next we define the referenced annotation, like so:

@FXBean for class {

  process each {
    inDerivedJavaClass(it) [
      for (f : declaredFields.toSet) {
        //TODO create property field
        //TODO create getter
        //TODO create setter
        //TODO create property accessor
      }
    ]
  }
}

The syntax is a bit different from Java's since we are convinced that reusing the keyword interface for an annotation, as Java does, is surprising at least. Also the annotation target (class in this case) is a first class syntax construct and is not encoded in another annotation.

The important part is the 'process'-hook, which will be called by the Xtend compiler, for every class that is annotated with @FXBean. Therein we state that we want to iterate over the declaredFields in the context of the derived Java class.

In the following we are going to replace the individual TODOs to make the compiler create a real JavaFX property from just a single field declaration.

We start by declaring a couple of local variables we'll use in the following:

process each {
  inDerivedJavaClass(it) [
    for (f : declaredFields.toSet) {
      val fieldName = f.simpleName
      val fieldType = f.type
      val propName = f.simpleName+'Property'
      val propType = f.type.toPropertyType(this)

  ]
}

The extension method toPropertyType() is not shown here, but it's really just a small utility method I built, which will return the JavaFX property type for the field's type. E.g. when asked with the type String the extension method returns the type SimpleStringProperty. Such utility methods simply reside on the classpath just like the annotation itself.

Let's now create the field.

process each {
  inDerivedJavaClass(it) [
    for (f : declaredFields.toSet) {
      val fieldName = f.simpleName
      val fieldType = f.type
      val propName = f.simpleName+'Property'
      val propType = f.type.toPropertyType(this)
      
      // create a field for the JavaFX property type
      field(propName, propType)
    }
  ]
}

The method field(String, Type) adds a field to the class in context using the given name and type. We could also change existing Java information here, like visibility and so on and also have an initializer or add annotations. You can even create new Java classes interfaces, etc.. Basically everything you can do in Java, can be done here.

Next up we create a 'getter'-method:

process each {
  inDerivedJavaClass(it) [
    for (f : declaredFields.toSet) {
      val fieldName = f.simpleName
      val fieldType = f.type
      val propName = f.simpleName+'Property'
      val propType = f.type.toPropertyType(this)
      
      // create a field for the JavaFX property type
      field(propName, propType)
      
      // getter
      method ('get'+fieldName.toFirstUpper, fieldType) [
        body = 
          'return (this.'+propName+' != null)? 
               this.'+ propName +'.get() : this.'+fieldName+';'
      ]
    }
  ]
}

Nothing special here. The square brackets are a lambda expression wherein you can customize the created method. We assign a body in this case.

The other two methods are created similarly:

@FXBean for class {
  
  process each {
    inDerivedJavaClass(it) [
      for (f : declaredFields.toSet) {
        val fieldName = f.simpleName
        val fieldType = f.type
        val propName = f.simpleName+'Property'
        val propType = f.type.toPropertyType(this)
        
        field(propName, propType)
        
        // getter
        method ('get'+fieldName.toFirstUpper, fieldType) [
          body = 
            'return (this.'+propName+' != null)?
                 this.'+ propName +'.get() : this.'+fieldName+';'
        ]
        
        // setter
        method ('set'+fieldName.toFirstUpper, type('void')) [
          param(fieldName, fieldType)
          body = 
            'if ('+propName+' != null) {
               this.'+propName+'.set('+fieldName+');
             } else {
               this.'+fieldName+' = '+fieldName+';
             }'
        ]
        
        // property accessor
        method (fieldName+'Property', propType) [
          body = 
            'if (this.'+propName+' == null) { 
               this.'+propName+' = 
                 new '+propType.identifier+'(this,"'+fieldName+'",this.'+fieldName+');
             }
             return this.'+propName+';'
        ]
      }
    ]
  }
}

And that's it. What you can't see here, is that everything gets updated and recompiled instantaneously on safe. Also important to note, is that you don't need any additional compiler configuration. Just have your active annotation on the classpath (e.g. distributed via jar or in the some project) is enough to use it and have the compiler applying it. And this of course works wherever you compile Xtend code (Command Line, Eclipse, Ant, Maven, etc.).

Naturally the IDE and the compiler is aware of what you do in the processing so, you'll for instance get the expected content assist proposals, ca use the typical navigation features and see the synthetically derived methods and fields in the outline view.

The following screen cast shows everything in action:

Tuesday, October 30, 2012

Become an Xtext consultant!

I'm in a very lucky position because I am able to work on cool frameworks and help people make good use of them. Being an Xtext consultant is a lot of fun, because you can prototype impressive stuff with just a few lines of code and its open architecture allows for solving almost every problem easily. We are involved with many interesting projects from all kinds of industries and our clients are always very satisfied and treat us with great appreciation. As part of itemis I have access to a great network of experienced software developers, which help each others and share existing solutions.
So all in all it's the combination of nice customers, helpful colleagues and cool technology which makes us love our job so much. But there's a tiny problem ...

We have more customers with interesting projects than we can deal with.

That's why itemis is looking for language and IDE experts experienced in Xtext specifically.


Being an Xtext consultant

As an Xtext consultant you should be able to really counsel our customers (and you should know that that's not the same as just building everything they are asking for). We want to deliver simple yet powerful and sustainable solutions. You need to be an experienced software developer with a good feel for API and language design. You should speak english and german (at least understand german), be empathic and a good listener. You should know that not every problem is a technological problem or needs to be solved with technology. It's important that you understand that Xtext is just a tool (and that there are other possibilities, which might be more appropriate at times).

Finally you should like meeting new people in interesting places throughout the world. And of course having fun always helps.

Job Description

During the first couple of months you will work in Kiel, where Xtext and Xtend are being developed. You will help the team with solving bugs, adding new features and also already do some work for customers. After a couple of months when you feel confident in your new position and are well connected within itemis you can work from any branch (we have several throughout Germany, one in Switzerland and two in France). You could of course also stay in Kiel (surf-city!) if you like it there.

itemis Kiel office
Consulting jobs will be throughout the world (we even have customers in Hawaii, which is almost as nice as Kiel) but there are also many possibilities near our branches. So traveling is not necessarily too extensive if you don't want to.

If you are interested or have further questions, just send me a mail.