Good News! We have just open sourced trackr so you can play around with it as you like. Read the full announcement here:

I want to share some insights from our recent project at techdev, trackr. trackr is a web application used to track our working times, create reports and manage vacation requests. The goal was to have a live application for internal use on one hand and an innovative technology stack to evaluate on the other. I will give you an overview over some technologies we used, the architecture, the build process and the problems or successes we had with all of that.

This article is not meant to be an in-depth guide to the technologies we used. If you have questions feel free to ask me.
I’ve decided to split my post into three parts for improved readability. This post obviously contains the first part, the others are soon to follow. But first, let me give you some general information.

Architectural overview
The base architecture of the application is fairly simple. We started developing the first client, which is a web application based on AngularJS. Data is delivered from a REST-like backend written in Java. The service allows future development of other applications, e.g. an Android app.

Other architectural aspects
As some sensitive data is delivered and changed through the service a role-based security had to be implemented.
The REST service should be discoverable, i.e. resources contain the hyperlinks to their linked resources (cf. HATEOAS). We wanted to use our Google accounts to access the service.

trackr is a tool that we use to track all kind of things such as our employees‘ working times or holiday requests. Supervisors can extract the billable hours out of that data. In the future, travel expenses will also be managed via trackr.

Part 1 – The REST service

Part 1 is about the backend service. Although as always it basically started as a simple access layer to the database, the technologies/frameworks involved and growing requirements make it more interesting.

With Java 8 just being a few days away from launch (at the time we started working on trackr) we wanted to try out building an application with it to get a grasp of the new features. As framework we chose Spring 4. To build the application we stepped away form the old beloved Maven and wanted to test Gradle.

As container we use Tomcat 8 in a Servlet 3.0 environment (we wanted to abstain from XML files), PostgreSQL was chosen for the database.

A first task was to set up the whole project in Gradle. So I added a new Gradle project in my IDE which created a basic build.gradle which is the equivalent of Maven’s pom.xml. You will immediately notice how small a Gradle build file is as all the XML boilerplate is gone.

So, to tell Gradle we have a Java project with the standard src/main/java maven layout we just add apply plugin: 'java'. A dependency only takes one line (readable, of course you can cram the XML in one, too). Since we’re building a web application I just needed to add apply plugin: 'war' and I will have a war task at hand.

When starting the Gradle tasks from the command line I noticed that the boot time from Gradle is slower than Maven’s. But as this does not scale when the project grows larger (the additional boot time is constant) it does not matter that much.

The IDE support, at least in my favorite IDE IntelliJ IDEA, is not as good as for Maven. Autocomplete is more or less non-existent. Sometimes IntelliJ will mark lines with a warning although everything works fine and is according to the docs. I guess that’s just the Groovy plugin.

Gradle suggests to use the Gradle wrapper. You have to check in a small jar file (usually I don’t like that, but well..) along your source code and gradlew scripts for UNIX/Windows. Whoever pulls the code does not have to install Gradle, the wrapper script is a replacement that will download Gradle in the background. I think this is a nice idea.

The Gradle build file is written in Groovy. For people who don’t know much about Groovy, this sometimes leads to some confusion. Take this task for example:

Line 2 is a function call while the other are variable assignments. Sometimes I had to use calls, sometimes assignments. I didn’t dive too deep into it but it seemed kind of inconsistent to me.
But speaking of tasks, as you can see they are quite small. Compare that to a exec maven plugin configuration. At our current stage our build.gradle file has 155 lines, including empty ones and comments.

JavaConfig for Spring
One of the old gripes with Spring was the need for large XML files to set up the application context. As of Spring 3 these are not required anymore, there is an alternative way. Additionally, when using a servlet 3.0 container not even a web.xml is needed, so trackr does not contain a single XML file. I used the AbstractAnnotationConfigDispatcherServletInitializer (Spring class names are always fun!) to load my configuration classes and boot up a dispatcher servlet. Actually I have two dispatcher servlets, but that is not important.

A nice thing about JavaConfig is that some Spring projects provide base classes for configuration classes that do some setup for you. One can interfere by overwriting methods. Here is an example, an early version of the security configuration:

As you can see we extend a base configuration class, override some methods and define some beans. This is basically a replacement for some special XML tags in the good old Spring configuration files.
The nice thing about JavaConfig is that you have code completion in all IDEs that support Java code completion. With XML based configuration you either had none or only in some IDEs like IDEA Ultimate or the Spring Toolsuite.
Yet JavaConfig is sometimes not as mature as the old school XML files. In the above example the method that configures the HttpSecurity has only one chained call in all examples. But this did not compile in our use case. Luckily multiple statements work, too.

For Spring-Security one thing wasn’t configurable at all with JavaConfig – the OpenIdAuthenticationFilter. I will show why this was a problem for us in a later part of this series.

Core Spring
As Spring-Security and Spring-Data-Rest covered most our needs we didn’t have to use much core Spring features. The most interesting part would be the requirement to be fully internationalized. This means not only providing translations for the frontend (which is fairly simple) but also live switching of Hibernate validation messages. I hope I will be able to cover this in detail in another post.

Spring-Data is a great way to access your domain model in a database. Spring-Data-Rest takes it one step further and exports your repositories to a REST service. Many things are done automatically without the need to configure things or add stuff, e.g.

  • GET, POST, PUT, PATCH, DELETE of resources
  • Pagination and sorting
  • Links to other resources
  • Discoverability of the REST service

Some examples of what Spring-Data-Rest will generate for you:

All I have in Java is the domain model for project and a standard Spring-Data repository with two finders. This makes bootstrapping a REST service ridiculously easy.
Of course there’s some configurability. Via some annotations resources and methods can be excluded from the export.

But there are shadows, too. It started out all easy and fast, but when getting to the next requirement, security, it got a little bit uglier. Here are some common requirements for security:

  • An employee may query him/herself but not others
  • A supervisor may edit projects but he’s not allowed to create new ones. He’s also not allowed to change the company the project belongs to.
  • A supervisor may GET all vacation requests but they must not contain his own

Now, Spring-Data-Rest allows all of these requirements to be fulfilled, but it got more complicated. For some use cases the Spring-Data-Rest event handlers had to be used. One can define methods that will be called on certain events, e.g. „employee created“, „employee updated“, „some link of a company changed“. I think these were designed to provide a way to validate the data or do other stuff on events but one can use the events for security checks too. More in the Spring-Security chapter.

Another downside is that you lose some separation of concerns. A single interface is suddenly responsible for database access and is exposed to the web. Also it does not help if you want to expose a different domain model to your REST service than your database has.

Recall, we have some security requirements for our REST service. Not everyone is allowed to do everything. We decided to go with a simple role-based decision system, i.e. we have three roles: admin, supervisor and employee in that order. The simple requirement is: If someone is not allowed to do something via the REST service return an HTTP code of 403 and don’t do anything. Luckily Spring-Data-Rest defines Spring-Web exception handlers to handle AccessDeniedExceptions in exactly that way and thus we can just use Spring-Security internally.

Spring-Security comes with a few very useful annotations. These annotations are in the context of GlobalMethodSecurity. One can annotate methods with PreAuthorize which takes a Spring expression language expression that defines who can access this method. Example:

This is actually fairly self-explanatory. @PreAuthorize checks before the method is called if the security requirement is met. So in the second method only supervisors may access this finder and employees only if they search for themselves. The employee id is saved in the principal object after login. @PostAuthorize helps if the method arguments don’t have all the data to decide if one can access the method. In this case the employee id is needed to decide but the vacation request id does not contain it. The last method is used on a page where supervisors can approve or decline vacation requests but they shouldn’t be allowed to approve their own requests. So this method filters them out.

Of course there are downsides, too. Our security requirement was coupled to the REST service, i.e. the web layer. Now it’s coupled to the data access layer. As soon as there is a security configuration in the application context, a principal is needed to access the methods. This is bad for automatically running jobs or internal access to resources – in some cases rights have to be elevated internally to admin while executing a REST call.
Testing all the security requirements is extremely important. If someone deletes the annotation no integration test for the repository will fail, but lowering security may be a large risk. More in the next section.

As every good programmer knows, a large and reasonably written test suite is very important for a changing application. While trackr has some unit tests, and testing if the Spring-Data repository methods do what you had in mind isn’t bad the main thing was to test the REST service. Luckily, Spring provides MockMvc in their test package. With MockMvc one can test a Spring MVC application programmatically without relying on a browser (e.g. Selenium tests). It even integrates with JsonPath to check the response!

I tested every exported web method with this approach. As said before, there will be no compilation error if someone deletes a Spring-Security PreAuthorize annotation – but the results could be fatal. Security requirements are not met anymore. Since no part of the application relies on a REST method call returning an HTTP 403 code a test must be written to prohibit accidental deletion.

We’ve created a small DSL to pull of the testing in trackr – you can read about the details here

Java 8
Surprisingly only one library, Javaassist via Hibernate didn’t like Java 8. Upgrading it to a newer version solved this and everything went smoothly.
It would be a waste of time to iterate over all new Java 8 features in this post, there are other sites that do that very well such as the Java 8 Tutorial by Benjamin Winterberg. I used a few features and can tell you how I got along with them.

The new collections/stream API
I have worked with Scala and being a mathematician I’m not feared of functions, so getting into things was easy. I mainly used them for very custom tailored response requirements when the domain model just didn’t represent what the client would expect (now I did this as an experiment, the client could get all the data himself and do the transformation).

For me, the power horse was stream().collect() along with the helpers from

Now what this does is create a map out of the list that has the employee has the key and a list of CustomWorkTime as value. Pretty straight forward, but you need some time to look around said Collectors to get a grasp what’s already there to help you.

Also nice to use is .forEach() along with method references.
IntelliJ proved helpful in discovering the new features and using lambdas. I mainly wrote the method call, then inserted a new and presses cmd+space to create the desired interface, implemented the method and then converted it to a lambda. As soon as I had a better understanding of the signatures of the interfaces the lambdas were for I didn’t need to do it that way anymore.


But one must take a little care when using the new stream API. It’s easy to get a little overambitious and write extremely large expressions that make much sense while writing – but the next day you will have to think again. So I tried to keep it simple.

As much as I wanted to use the new Date API everywhere, Hibernate and Spring-Data did not really support it. So I fell back to use it only when doing more complex date calculations. It’s possible, the converting is cumbersome and to be honest I’m not even sure if I’m doing it right all the time. The API itself I think is awesome, being basically joda-time. It really helps to be able to adjust a date by one day without the need for a calendar.

They are awesome. It’s just a little thing, but when needing a principal in a test I could do:


Authorization and Authentication
As you may have noticed we use Spring-Security-OpenID to login via our Google accounts. This means if you try to access the service unauthorized you will be greeted with a JSP login page. Of course that is not very reasonable for a REST service that you may want to access from locations where displaying a webpage is not feasible. I started evaluating how to use OAuth to secure the service while keeping the OpenID login possible. This means authentication is done via OpenID but after that only our OAuth service is running. This turned out to be very time consuming task. While certainly interesting it was not really needed for our first client app which is a web application so we delayed that.

Go here to read how we’ve added OAuth to trackr

Writing the backend with Java 8 and Spring-Data-Rest was fun and productive. I think for our use case Spring-Data-Rest fit just fine, but if you have lots of custom endpoints in your REST service or don’t want to export the database domain model it won’t work for you. The interaction between Spring-Data-Rest and Spring-Security requires some polishing but was entirely possible. The Spring testing package really helped with testing everything in a sane manner. Finally, Gradle was a nice change from Maven but for this project I think they are very replaceable with each other.

Want to see how we implemented approvals via mail using Spring Integration? Go here or just continue to part II

Join our newsletter – stay in the loop!

  • JT

    The article is very well written and explained. I was wondering if trackr is open source. Thanks.

  • Alexander Hanschke

    Thanks for your comment! We don’t envision open-sourcing trackr for the time being as we’re using commercial components in the frontend prohibiting us from doing so.


  • Pingback: TRACKR: AN ANGULARJS APP WITH A JAVA 8 BACKEND – PART II | techdev Solutions()

  • Maxim M

    Hi, great post, thanks.

    I develop application with similar technologies and encountered a problem. How to work with Hibernate and java 8 date.time.* classes? LocaDate field put in database as a blob. If I use @Type(type = „java.sql.Date“) then I get this exception when calling the Rest-service „Can not set java.time.LocalDate field Domainname.year to java.sql.Date“.

    UPD: Sorry, now I read that Hibernate and Spring Data JPA still do not support Java 8 Date Time API.

  • Pingback: Ubuntu Security Essentials | techdev Solutions()

  • fgarcia

    Hi, first thanks for the post! Very informative!
    Im building an app similar in terms of architecture and the post is very helpful.
    I have a little question, can you explain a little more how you configured Restangular to work well with Spring Data Rest? It would be very helpful for me!
    Thanks again!

    • Moritz Schulze

      Sure. The only additional configuration we made was to add a response interceptor to Restangular since Spring-Data-Rest does not return arrays for getList operations. It needs to be extracted from the _embedded property.

      • fgarcia

        Really really thank you very much!!!

  • techdev_solutions

    Hi everyone, a quick update: we have just open sourced trackr to our GitHub repository. Read the entire announcement here:

  • Chris

    Where can I find the source code of front-end ???

    • techdev_solutions

      Hi Chris,
      the front-end has not been open-sourced, yet. But we are working on it, so it should be available pretty soon.