I want to share some insights from our recent project called 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.

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, version 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.

apply plugin: 'Java'
sourceCompatibility = 1.8
version = '1.0'
repositories {
dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
task wrapper(type: Wrapper) {
    gradleVersion = '1.10'

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:

task gruntTest(type: Exec) {
    workingDir 'src/main/webapp/WEB-INF/app'
    executable = 'grunt'
    args = ['test']

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:

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

    protected void configure(HttpSecurity http) throws Exception {
            .antMatchers("/", "/app/bower_components/**").permitAll() //the login page should be able to access CSS and JS files


        formLogin() //this is only for the admin account
            .loginPage("/") //redirect to / if no authenticated session is active
            .loginProcessingUrl("/login/admin") //form has to post to /login/admin

    public RoleHierarchy roleHierarchy() {
        RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
        roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_STAFF > ROLE_EMPLOYEE");
        return roleHierarchy;

    public RoleVoter roleVoter() {
        return new RoleHierarchyVoter(roleHierarchy());

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 REST

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.

curl http://localhost:8080/api/
  "_links" : {
    "credentials" : {
      "href" : "http://localhost:8080/api/credentials{?page,size,sort}",
      "templated" : true
    "projects" : {
      "href" : "http://localhost:8080/api/projects{?page,size,sort}",
      "templated" : true
    "employees" : {
      "href" : "http://localhost:8080/api/employees{?page,size,sort}",
      "templated" : true

curl http://localhost:8080/api/projects/
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/api/projects/{?page,size,sort}",
      "templated" : true
    "search" : {
      "href" : "http://localhost:8080/api/projects/search"
  "_embedded" : {
    "projects" : [ {
      "id" : 0,
      "version" : 0,
      "identifier" : "1001.1",
      "name" : "Project 1",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/api/projects/0"
        "company" : {
          "href" : "http://localhost:8080/api/projects/0/company"
        "debitor" : {
          "href" : "http://localhost:8080/api/projects/0/debitor"
    "page" : {
      "size" : 20,
      "totalElements" : 1,
      "totalPages" : 1,
      "number" : 0

curl http://localhost:8080/api/projects/search
  "_links" : {
    "findByNameLikeOrIdentifierLikeOrderByNameAsc" : {
      "href" : "http://localhost:8080/api/projects/search/findByNameLikeOrIdentifierLikeOrderByNameAsc{?name,identifier}",
      "templated" : true
    "findByIdentifier" : {
      "href" : "http://localhost:8080/api/projects/search/findByIdentifier{?identifier}",
      "templated" : true

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.

Spring Security

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.

public interface VacationRequestRepository extends CrudRepository {

    @PostAuthorize("hasRole('ROLE_SUPERVISOR') or ( isAuthenticated() and principal.id == returnObject.employee.id )")
    VacationRequest findOne(Long aLong);

    @PreAuthorize("hasRole('ROLE_SUPERVISOR') or ( isAuthenticated() and principal.id == #employee.id )")
    List findByEmployeeOrderByStartDateAsc(@Param("employee") Employee employee);

    @PostFilter("filterObject.employee.id != principal.id")
    List findByStatusOrderBySubmissionTimeAsc(@Param("status") VacationRequestStatus status);


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!

public void updateAllowedForAdmin() throws Exception {
    Project project = projectDataOnDemand.getRandomObject();
        put("/projects/" + project.getId())
        .andExpect(jsonPath("id", isNotNull()));

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.

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 java.util.stream.Collectors.

List worktimes = ...;
        mapping(CustomWorkTime::valueOf, toList())

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:

//instead of this
Principal principal = new Principal() {
    public String getName() {
        return "admin";
Principal principal = () -> "admin";

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.


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.

Stay in the Loop

If you would like to receive an email every now and then with new articles, just sign up below. We will never spam you!