The surprise of Spring Boot

I am a long time Java programmer. It was what I used to write my final year project at university, and it was my first, second and third jobs.

That third job lasted more than a decade and, alongside a huge amount of other things, I got to deliver a number of projects in both PHP and Ruby. PHP was interesting and I’d happily work in it again, but Ruby was fun.

Terse, expressive, powerful and (mostly) lightweight in nature, it feels like a blessing of a language.

The time came to change job again though, and although I looked for some Ruby roles, I’d been a bit too hands-off to be able to be seriously considered and so I got another Java role. But! What a surprise! Whilst I wasn’t looking, Java frameworks learned some lessons from their “convention over configuration” brethren, and those lessons are mostly reflected in Spring Boot by Pivotal Software. Here is a complete Hello World web application in Spring Boot:

@RestController
class ThisWillActuallyRun {

    @RequestMapping("/")
    String home() {
        "Hello World!"
    }

}

This is borrowed from the Quick Start example, and is in Groovy, so there’s no other requirement for imports, classpaths etc. Just use the Spring Boot command line tool to run it, and you’re done!

The Getting Started guides cover a wealth of activities to do almost anything you can imagine, but the framework is perfect for writing microservice-based applications with very little configuration required beyond adding some annotations to your classes and methods.

It makes writing Java a pleasure again, and an experience far from the heavyweight EJB and Spring2 I was recoiling from a few years ago!

Logging database content changes in a Play Framework app

To do this we use Hibernate Envers.

There are 3 easy steps to adding change logging to the data in your existing Play Framework app (I am using 1.2.4 – version 2 may well be different):

  1. Add the library
  2. Add the standard configuration
  3. Add an annotation to each class where you want to track data changes

Add the library in conf/dependencies.yml

require:
    - play
    - play -> crud
    - org.hibernate -> hibernate-envers 3.6.1.Final:
        exclude:
            - org.hibernate -> hibernate-tools 3.2.0.ga
            - org.beanshell -> bsh 2.0b4
            - freemarker -> freemarker 2.3.8
            - org.hibernate -> jtidy r8-20060801
            - ant -> ant 1.6.5

Add the Envers configuration to conf/application.conf

# Hibernate Envers Auditing Library conf
hibernate.ejb.event.post-insert=org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener
hibernate.ejb.event.post-update=org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener
hibernate.ejb.event.post-delete=org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener
hibernate.ejb.event.pre-collection-update=org.hibernate.envers.event.AuditEventListener
hibernate.ejb.event.pre-collection-remove=org.hibernate.envers.event.AuditEventListener
hibernate.ejb.event.post-collection-recreate=org.hibernate.envers.event.AuditEventListener

Add an annotation to each class you want to audit

...
import org.hibernate.envers.Audited;
...

@Entity
@Audited
public class Book extends Model {
  public String title;
  public String author;
  public String description;
}

If you run up your app and make a change to an entity you will see a new table appear in your database. If your entity table is BOOK your new table will be BOOK_AUD. It contains a version reference (a normalised reference to a new revinfo table containing the timestamp of that audit entry) and the values of all the fields on the entity after the changes were saved.

You can go wild on the config by auditing only particular fields on an entity (just add @Audited to those fields), or adding new fields to the audit log (like who made the change or what method was called to do it), and change the name of table suffix.

It’s also quite simple to retrieve the list of versions, and this has been written up quite clearly by Matthieu Guillermin (it’s in French but Google Translate does a good job, and you can read the code anyway).

All of this information had already been written in several places, but hopefully this has brought it together in a useful way.

My config changes are from https://gist.github.com/1148850 and https://gist.github.com/1148852 by Marc Deschamps.

Setting up the Play framework on Google App Engine

The Play framework is the most fun I’ve had developing Java web applications. It’s fast, natural, comes with a rails-like scaffolding for CRUD operations on your model, has built-in Selenium testing as well as unit and functional tests, and most importantly Just Works.

It also deploys natively onto Google App Engine, but this isn’t described very well in the official documentation so here are the basics:

Get started

  1. Get yourself a GAE account and set up an application. you will need the ID.
  2. Download a recent nightly of the stable 1.0 branch (1.0 final doesn’t work with GAE, and Play needs to sort out its versioning system here)
  3. Unzip
  4. Download the GAE SDK for Java
  5. Unzip
  6. Create your app (although use Siena rather than JPA if you want to persist to the GAE data store) and configure it to use the GAE module
  7. Add your GAE application ID to myapp/war/WEB-INF/appengine-web.xml

Deploy to a local dev GAE environment

  1. run play war myappname -o myappname-war
  2. run APPENGINE_SDK_DIR/bin/dev_appserver myappname-war

Deploy to the GAE server

  1. run play war myappname -o ../myappname-war
  2. run APPENGINE_SDK_DIR/bin/appcfg update myappname-war/
  3. log in to your app engine console and check out your application!

Java makes me passionate

Seriously.

I really like Java, it’s a fundamentally great language. Verbose at times, but great.

However, web application development in Java is painful. Additionally, the compilation and deployment of Java webapps completely suck. I mean, they’re terrible.

I dread to think how many frameworks exist in Java to ease web app development – each one claiming it’s the best and will solve all your woes, yet none come anywhere close to the ease of development in Rails, Django, or any of the PHP frameworks.

I remember being introduced to JSF at ApacheCon Europe 2006. I came back declaring that we would never use JSF for our internally-developed applications. When there was masses of hype, and everyone was claiming JSF was amazing, I got a few questions in the office.

Two years on and there’s finally some acceptance that JSF 1.0 was horrible for developing web applications, with some defensively claiming that JSF 2.0 will solve all the problems. Right, because that always works.

See the recent discussion:

Anyway this means I try and keep a close eye on things like JRuby and Grails but we’ve been pretty reluctant to use them at work because we tend to have large monolithic applications which require maintenance by different people over time which means code homogenisation is good.

To this end, our last couple of projects have been in Struts2+Spring+JPA+Hibernate. This is a nice combination, with a number of well-understood components working well together, especially since we’ve used the Zero Configuration plugin which allows us to drop tens of lines of XML in favour of a few lines of annotations. The Zero Configuration stuff is as buggy as hell and there’s no concrete date for Struts 2.1.2 where it should be fixed, but that’s by-the-by. For me, the fact that we haven’t had to be editing XML almost makes it worth it 😉 Also, Struts2 is highly testable which fits in nicely with our existing testing process.

But when you have a framework you’re (mostly) happy with for development, it highlights the other pain points you may have. For us, this was definitely the deploy/test cycle. We were already using TDD in the compile cycle so there’s a level of confidence about the backend code – tests always run after a successful compile, but when you’re amending the web interface either for small cosmetic changes or for larger changes of data representation there’s a long recompile, redploy, retest cycle that drives me insane. Obviously there are ways around it if you’re using something like Eclipse and have a web application in the structure it needs but we tend to have a number of files which are built at compile-time by Ant. Also, I don’t like being tied to an IDE for tooling purposes – I’m very happy with my current editor thank you very much. The only real missed opportunity was AppFuse – we remembered about it too late; any other Struts2 projects will probably start with it though.

All of this is why I was pleased to see Play! . It’s a just-in-time compilation framework where the controllers and model are pure Java and the view is Groovy; excellent!

This means that we can reduce the time taken to learn (we only need to learn one component – the view – plus config) whilst leaving all the business logic in a state maintainable by anyone in the team. It serves up locally through Apache Mina whilst also being deployable to a more conventional container like Tomcat or JBoss. Changes to both business logic and template are instant, and you can still test it to your heart’s content !

Unfortunately the latest stable version (1.0-stable3 at writing) doesn’t contain critical features like, um, if..else in the template language. Everything seems to be in the nightly, but having been burned with the Zero Configuration Struts plugin (which had the notice “This is experimental. Feedback is appreciated!”) I wouldn’t like to commit any real effort to writing an application in it. As soon as they have that core stuff nailed down though – I’m there.

Struts2 + Hibernate + Spring

At work we’re playing with creating a personal-homepage application in the style of iGoogle and others. We’re a Java shop, using pretty basic JSP+servlets+Hibernate as our standard application development structure. Since when we formed we were quite a varied team in skillset this has meant that everyone is now more or less equally versed in core Java web app development.

We’ve used this opportunity of writing a new application to try out a number of ways of reaching that goal – specifically we broke in to three teams of two, wrote up a very basic requirements spec (“drag and drop panels and remember the positions”, “show an RSS feed”, “use single-sign on”), gave ourselves three days for implementation and chose three methodologies. In fact, we chose three different languages!

One team looked at using Symfony, another team looked at Ruby on Rails and a colleague and I looked at using “a Java framework”. I didn’t want to choose anything too complicated or with too-steep a learning curve (we had to be able to actually achieve our requirements!) and went very quickly through about six or so before settling on Struts2 as looking like a clean, well-separated development framework. This turned out to be the right choice for the job.

The quickstart application we downloaded from the wiki came with everything we needed to get going. It uses Hibernate as an EJB3 persistence layer (using POJO annotations) and uses Spring to inject the session management whenever it’s required. It also came set up as an Eclipse Tomcat project which deployed instantly.

We only really scratched the surface of what’s possible, but overall I was very impressed with this combination of tools and additions like the REST plugin. In particular, using annotations to power the persistence was a revelation, as previously I’ve maintained the hibernate.cfg.xml and mapping files, which are terrible. This does mean that we no longer get support from Hibernate tools like hbm2ddl, but it’s a small price to pay.

Using GAlternatives is fun, tasty

G Alternatives screenshot

If you’ve got a raw Ubuntu box it probably came with gij, the GNU Java runtime interpreter. If you’ve installed Sun’s JDK using sudo apt-get install sun-java5-jdk then you’ll now have Sun’s runtime but gij will still be the default. This is maintained by the alternatives system. You can either go and fix it yourself or you can sudo apt-get install galternatives followed by galternatives to run it (I haven’t noticed it in any menu although of course you can add it yourself).

This gives you a nice GUI onto all of the currently set commands in /etc/alternatives and what they can be set to. If you scroll down the list you’ll need to change the settings for jar and java.