Modern Java Development is Fast
Tags: java, spring, testing, beginners
Published: 2017-08-25 22:43:30

---
title: Modern Java Development is Fast
published: true
description: 
tags: java,spring,testing,beginners
---

*Originally posted on [return.co.de](https://return.co.de/blog/articles/java-development-fast/)*

Java Development is fast - and fun. Believe it or not. 

I hear a lot of Java bashing in podcasts, mostly by developers that never did professional Java development and think about Java as the crappy Java browser plugin or ugly cross-platform desktop apps. 

But that's not what I am talking about. What I mean is, you can nowadays write high quality production-ready code in Java in very little time. So here is an overview about the tools and frameworks I use every day.

This next section is a bit about my background and the issues I had with Java in the past. But feel free to skip it and jump to "A new Hope".

# The XML Hell

A couple of years ago, I was almost done with Java. I did years of development with Java ME (Using Java 1.3 which is not fun at all) as well backend development in Java SE with Spring 2. Plus, there were some legacy system I had to maintain running struts for the front end.

```xml
<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id = "helloWorld" class = "de.co.return.HelloWorld">
      <property name = "message" value = "Hello World!"/>
   </bean>
</beans>
```

A true beauty, isn't it?

I was basically sick of Spring 2 and Struts with its pile of XML that made refactoring a hell and was hard to read. 

So I started the next backend project with plain Java SE. I did it completely test-driven. I was pretty fast, using IntelliJ to generate all the boilerplate code. I really took the DI "thing" very serious an over-engineered it. I had an interface for almost every class even if there was only one implementation. I did not use any mocking framework because I had some bad experience, too - with EasyMock and even PowerMock (do not use that!) and wrote all mocks by implementing the interface in a test if I needed it. I also had huge master bootstrap class that actually created the production instances and did the actual injection. That was a 500loc monster. 

```java
MyConfiguration config = loadConfiguration();
FirstClass firstClass = new FirstClass(config);
SecondClass secondClass = new SecondClass(config, "someParam");
ThirdClass thirdClass = new ThirdClass(firstClass, secondClass);

(...)

OneHundredTwelfthClass oneHundredTwelfthClass = (...)
```

Thanks to very good test coverage, this application was working from the first moment on after putting it into production. The only place that I did not cover and that therefore had bugs was the SQL queries which, you guessed it, I wrote using plain JDBC.

All manually. And all because I had such a bad experience in the past using any kind of Framework. 

I learned a lot but I didn't want to do that the rest of my life. So I was looking for some niche jobs like Erlang Backend Developer (I still love that language). I actually rejected a pretty good offer for a Java Dev position because they they told me in the interview that they were doing Spring. Finally, I was hired by a big company that was set on Java.

# A New Hope

I was part of a new team that could chose the technologies we wanted to work with. We experimented with plain Java, Camel, Java EE, vert.x and then there was Spring 4 and Spring Boot and some other amenities that opened my eyes.

## Spring - The Magic is Happening

### Spring Core

With [Spring](https://spring.io/) core, I was obviously able to replace such an ugly bootstrap class with its `@Autowire` magic and, most importantly, without any XML necessary:

```java
@Service
public class FooService {

    private final FooRepository repository;

    @Autowired
    public FooService(FooRepository repository) {
        this.repository = repository
    }
}
```

This is the core of Spring: Dependency Injection. It's practically the butler, that gets you all the stuff that you need on a silver plate. You just have to call for it. Spoiler: This gets even better with Lombok, see below.

I actually dropped my "interface for each class" pattern completely except for places where I needed more than one implementation. 

### Spring Web MVC - Gimme Some REST

I did not need any Webserver setup or configuration, I could easily write a `@Controller` that returns a Java class instance that gets serialized as JSON, no code necessary. 

```java
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {

    private final AppointmentBook appointmentBook;

    @Autowired
    public AppointmentsController(AppointmentBook appointmentBook) {
        this.appointmentBook = appointmentBook;
    }

    @GetMapping
    public Map<String, Appointment> get() {
        return appointmentBook.getAppointmentsForToday();
    }

    @GetMapping("/{day}")
    public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
        return appointmentBook.getAppointmentsForDay(day);
    }

    @PostMapping
    public String add(@Valid Appointment appointment) {
        appointmentBook.addAppointment(appointment);
        return "redirect:/appointments";
    }
}
```

The code above publishes a new rest endpoint `/appointments` as well as two `GET` endpoints to retrieve all appointments and all appointments for a day as well as a `POST`endpoint to create a new appointment. The class `Appointment` might actually be a persisted entity that gets automatically serialized as JSON. You'll get path variables properly decoded and fed into types method parameters. No additional code necessary.

See [here](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html) for reference.

### Spring Data

For very simple CRUD interfaces, I could use [Spring Data](http://projects.spring.io/spring-data/) repositories and even [Spring Data REST](http://projects.spring.io/spring-data-rest/) to directly create a REST interface for my entities. 

```java
public interface OrderRepository extends CrudRepository<Order, Long> { }
```

> For this repository, Spring Data REST exposes a collection resource at `/orders`. The path is derived from the uncapitalized, pluralized, simple class name of the domain class being managed. It also exposes an item resource for each of the items managed by the repository under the URI template `/orders/{id}`. *

*See [here](http://docs.spring.io/spring-data/rest/docs/current/reference/html/#repository-resources) for reference.

Again, a lot of magic but but pretty cool though. While scanning the classpath for Spring managed classes, it finds the interface and creates an implementation for the repository on the fly, that you actually use to fetch entities from the data base (and all the CRUD operations as well) plus it will create a REST controller that will serve requests to that repository. 

### Spring Integration Tests

Using [Mockito](http://site.mockito.org/) to mock objects in tests works like a a charm, [AssertJ](http://joel-costigliola.github.io/assertj/) for test assertions and even all-set-up integration tests using `@SpringBootTest` with Real HTTP mock servers and in memory data bases running a complete application test without any external resources.

```java
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private MyService service;

    @Autowired
    private MockRestServiceServer remoteServer;

    @Test
    public void exampleTest() {
        this.remoteServer.expect(requestTo("/greet/details"))
                .andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
        given(this.remoteService.someCall()).willReturn("world");

        String greeting = this.service.callRestService();

        assertThat(greeting).isEqualTo("hello world");
    }
}
```

As you see, there is a lot happing in this code. First, an actual Web Server called is started `MockRestServiceServer`that will respond once `/greet/details` is requested. Then the service `RemoteService` of you application is mocked which is assumed to be called by the class under test `MyService`. When the method `someCall`is called, it will return "world". At the end, a verification using [AssertJ](http://joel-costigliola.github.io/assertj/) is done.

### Spring Security

The only downside was using [Spring Security](https://projects.spring.io/spring-security/) which does authentication and autorization. It comes with a variety of ready to use implementations as well as the option to write your own `AuthenticationProvider`. Unfortunately, IMHO it is designed badly (from the usability perspective) and even worse documented. Once you're starting to customize it the slightest bit, It never works as you would expect and you'll end up spending hours and days fixing it by trial and error. Simply put, Spring security sucks most of the time. I hope there is some overhaul done soon.

### Spring Boot

> Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.

* See [here](https://projects.spring.io/spring-boot/) for reference.

Spring boot puts together all bits an pieces, applies a sensible default configuration and your good to go.

If you want a very funny and very good live coding example, I highly recommend Josh Long's video ["Bootiful" Applications with Spring Boot](https://www.youtube.com/watch?v=HCyYEVRZISk) - Wow, such great!

## JPA / Hibernate

When I once used Hibernate years ago, there was also that XML configuration hell I described earlier. But with recent JPA, you just do

```java
@Entity
public class Customer {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String firstname;
  private String lastname;

  // … methods omitted or replaced by Lombok
} 
```

See [here](https://spring.io/blog/2011/02/10/getting-started-with-spring-data-jpa/) for reference.

and together with the Spring Data Repositories, you can access your entities easily. That means, that you're simply describing the data you are working with and you don't have to deal with how to get them.

The best thing is, you do not need to write any SQL. Hibernate is very good at creating optimized queries. It will pull the data from the database and maps it onto the `@Entitiy` class. If you you have some ugly names for tables or columns, you can simply annotate the fields. The above class expects a table `CUSTOMER` with columns ÌD`, `FISRTNAME` and `LASTNAME`. You can customize everything you want if you need to access a legacy DB, e.g..

## Lombok - No More Getters 

When Java 8 came out, I was pretty impressed on how this old language was able to evolve. However, two things were missing from my point of view: Pattern Matching and a way to get rid of getters and setters.

We still do not have pattern matching (as e.g. in Erlang), but - and this is truly amazing - we can get rid of getters and setters by using a library. A lot of frameworks rely on the existence of getters and setter, Hibernate, Jackson and Spring itself.

When I first saw [Lombok](https://projectlombok.org/) I thought this must be some code generation magic or - even worse - some runtime reflection trick. Plus, the website looked like it was from the 90ies. But when I checked it out, it turned out I was completely wrong. They are using a `javac` feature, compile-time annotations. So during compilation, Lombok's code is executed and generates additional byte code which generates no additional runtime overhead (compared to writing getters and setters manually) and no intermediate Java code.

Remember the `FooService`from above. Using `@AllArgsContructor`, Lombok generates a constructor for all members.

```java
@Service
@AllArgsConstructor
@Sl4j
public class FooService {

    private final FooRepository repository;
    private final MyProperties properties;

    public getUri(String path) {
        log.debug("Building uri from base Url {} and path {}", properties.getSomeUrl(), path)
        return properties.getSomeUrl() + path;
    }
}
```

Using `@Sl4j`, we get a free logger (instead of doing `Logger.getLogger(...)`) and there is more good stuff like generating `@ToString` and `@EqualsAndHashcode`.

With [Spring 4.3](https://spring.io/blog/2016/03/04/core-container-refinements-in-spring-framework-4-3), you can even drop `@Autowire` completely.

```java
@Configuration
@ConfigurationProperties(prefix = "my.app")
@Getter 
@Setter
public class MyProperties {

    private String someUrl;
    private Integer someTimeout;
}
```

The above code can be used as spring properties to configure the application. You might argue that this snipped has more annotations than code and that's true. But I'd still prefer it over writing all the boiler-plate code myself.

It allows you to write a YAML file like the following an drop it next to the jar to change configuration:

```yaml
my.app:
  some-url: http://foo.bar
  some-timeout: 5000
```

Yes, it will automatically allow you to use proper naming like `some-timeout` still know how to map that onto `someTimeout`. You'll get type safe configuration for you application for free. You can even add `@Validated` together with e.g. `@Max(1000)`.

## Maven

Maven is *the* library management tool. Ok, Maven is a lot of XML, ok but it just works like a charm. I've worked with Ant and it was so painful to get the same result. 

I was looking forward to use Gradle in an Android project and oh my gosh, this really bad. You'll need to write executable scripts that can do anything (and do do anything, especially in cases where you don't want it). You never know if its a method you're calling or if its configuration. I ended up spending hours and days printf-debugging my build script until it did what I wanted.

Just because of XML, Maven is well-defined and and you're almost not able to break stuff in a way that was not intented. Maven is library  dependencies done right, especially when you compare it to other "package manager" that are loading code, build it (XCode, Erlang) or crap like NPM and Bower. Maven is just an integrated part of you build process, there is no need to download a library upfront like in `pip` (Python), you'll always get the exact version of that lib for that very project you're building.

## Java

As mentioned above, Java 8 comes with some functional features and Lambdas are pretty handy although they aren't necessarily functional. Streams look great at first but most of the time you'll end up with spaghetti code that no one (not even you after one week) can read. Most often, you're better off with a good old for loop. 

But generally, it try to write functional code (which was possible since the first version of Java) as much as possible. That means, a method should always return a value (not void) and it should always return the same value for the same parameters. This requires to

- Not use system calls (like `currentTimeMillis()`)
- No interaction with files, DBs etc.
- Use class variables

Obviously, if you do that a 100%, you're application is completely worthless because you have neither a way to control it nor to get any output. So what I try is to keep my core business logic as clean as possible and move the side-effects as far outside as possible. This benefits testing a lot.

## IDE

I actually transistioned through a lot of IDE in the past, starting from QBasic, Turbo Pascal, Visual Studio, Eclipse, NetBeans, XCode and even `vim`. But I lost my heart to [IntelliJ IDEA](https://www.jetbrains.com/idea/) which is just the single best IDE I've ever used. It starts with beeing beatiful and fast, supporting very good and intuitive keyboard short cuts, you can auto-type and auto-filter all menus, even context menus. It allows to use powerful refactorings and generating code for you. I supports very good debugging as well as showing code coverage in line.

You might be happy with your IDE right now, but you should have at least tried IDEA once and watch a video about the features. 

Especially when I used XCode for an app project I did, I felt like in the stone age compared to IntelliJ. Unfortunately, even JetBrains AppCode still requires XCode for some things.

## It's the Eco System

So, it's not about the language. Its not about the IDE or the build tool. It's every thing together that makes Java development fast and fun.