Sunday, April 30, 2017

Spring Data REST

Last week I blogged about doing a RESTful Web Service in Spring.  Towards the end of that post I mentioned that there's another module in Spring Data which can automate some of this work called Spring Data REST.

Following through on that idea, I rewrote essentially the same service here using Spring Data REST.

From what I've seen so far, Spring Data REST helps you in two different ways.  It relieves you of having to write a controller, at least for basic CRUD methods, and it also enables Hypermedia As The Engine Of Application State (HATEOAS).

When I started trying to get my Spring MVC Test Framework integration tests working again, the first thing I noticed was the following test failing:

My test was expecting application/json but it's now returning the HATEAOS mime type application/hal+json.

Spring defines these in the MediaType class.  They don't seem to have one of those for application/hal+json.  I considered just not checking the mime type... But I googled a bit more and found Configuring Spring Data REST and Basic settings for Spring Data REST in the documentation.  I used the following configuration to change the default mime type of the JSON responses back to application/json:

The next thing that was different has to do with the argument to methods which operate on an existing entity.  My original code used a String "name" to identify the entity, but the Spring Data REST methods all use the "id" field.  Here's how I wrote the controller method to get a single entity by name:


But I'm not writing the controllers any more... Spring Data Rest creates a 'GET' endpoint taking an 'id' value, and it also creates one for my findByName() method in the Spring Data JPA repository interface.  Here's my tests for these two cases:


I rewrote the remaining tests to just use the id instead of the name.

One other change was needed... since Spring is now automatically generating a REST endpoint from the findByName() method in the repository interface, instead of me just calling it from the controller method, I needed to give that an annotation to instruct it how to handle the HTTP request parameter as its input:


Spring Data REST strikes me as a huge win for green field development situations where you just drop a dependency in the POM file (or Gradle build file) and, whoosh, instant REST endpoints for all the domain classes.  It might be more problematic to use this in a legacy app where the Spring Data REST endpoints might not match the conventions of the existing endpoints.  Also, the HATEOAS stuff, yeah, it's the semantic web wave of the future, but it is a bit different and might take some getting used to if this is your first exposure to it.

Friday, April 21, 2017

Java 8

Back around November, I started working problems at Hackerrank.  One of my goals was to learn and get better at Java 8.

Frequently in these problems I had a need to print out an array of integers.

Before we get started in Java, the programming language I've mostly used at work for the last 3 years or so is Groovy, doing application development in Grails, writing Jenkins jobs, and just for general scripting.  Here's how you print an array of integers (int[] a) in Groovy:

It's super-easy and concise.

When I was still working in Java 7, I wrote something like the following code:

Hackerrank sometimes uses huge arrays, like 50K or 200K, so I'm efficiently using StringBuilder.  But the whole thing is super-verbose.  Java 7 lacks anything like the join operator so I'm reduced to implementing it myself, more or less.  There's five lines of code here devoted to adding a space before every character but the first.  The Groovy solution is so concise, it hardly makes sense to write a method for it, but here it would be crazy not to.

Java 8 String.join() finally gives us a string join method like the one I was using in Perl over 20 years ago.  Cool!  Here's the way I was doing this in Java 8 for a while:

That's not bad.  It's a big improvement over Java 7.  It's actually a one-liner, though the line is kind of a long one.  It's basically doing the same thing as the Groovy code, except I need to explicitly shepherd the output through a series of type conversions.

There's still a way to make this a little bit better, though.  In order to come up with the second argument to String.join(), I'm converting my array to a stream, then doing another conversion to get a Collection.  It turns out that the Java 8 team provided a reduce method Collectors.joining() which eliminates the need for String.join().  This makes it possible to do everything in a stream instead of the awkward series of conversions I had before.

And it's a bit more concise, too.

It might be tempting to look at this one example and say 'Groovy wins.'  Well, after all, Groovy is built on top of Java such that the new features of Java 8 are available in Groovy, so, yeah, Groovy does win 😎.

My initial reaction to Java 8 lambdas was 'oh, Java is finally catching up to something Groovy has had since, what, 2007?'  But it's important to understand that streams and the implementation of the filter-map-reduce abstraction implemented by Java 8 is a new thing that didn't exist in Groovy before.  In recent years we've seen a lot of interest in languages like Scala and Clojure which support a functional style of programming in which the creation of mutable state is avoided for the sake of concurrency.  This is what the streams feature of Java 8 is all about, parallelism.

Thursday, April 20, 2017

RESTful Web Service in Spring

I've been spending a lot of time at Hackerrank lately, also getting up to speed on Java 8, but I suddenly realized I hadn't done much with Spring for a while.

So, this is maybe about an 8 hour effort over the course of 2 weeks or so.  It's a RESTful web service for Pokemons.

Writing a RESTful web service in Spring these days is not quite as easy as in Grails, but it's really pretty easy.  I just used MVC and @RestController.

For integration testing I followed the example in Building REST services with Spring.  I had glanced at the documentation for Spring MVC Test Framework before but never really used it, so this part was mostly new to me.  It lets you test MVC requests without bringing up a full Servlet container.

I'm aware of Spring Data Rest.  Here's a pretty good presentation: Advanced Spring Data REST - Oliver Gierke.  I'm getting ready to give this a try but wanted to go through the exercise of doing the REST implementation 'by hand' first.

Saturday, January 7, 2017

Ubuntu MATE 16.04

I was a solid Ubuntu guy from about 2008-2011.  I walked away mostly due to the decision to replace my beloved Gnome 2 with Unity as the default desktop.  I played around with Xubuntu, Lubuntu, even Kubuntu; I tried Gnome 3, nothing satisfied.  I wound up following the same path as a lot of other disgruntled Ubuntu users by switching to Linux Mint whose MATE desktop offers an experience very like Gnome 2.

I've been happily using Mint MATE for about 4 years.  The last Mint 17 upgrade 'Rosa' (17.3) was having some issues on my laptop, though.  The display would lock up once in a while, a condition I could clear by switching to another virtual desktop and back (CTRL-ALT-F1, ALT-F8).  But it was still a nuisance.  Another little thing that was going wrong is this release didn't seem able to support an external HDMI-connected display (worked fine on the same hardware with Windows 8.1).

I heard that Ubuntu 16 was supporting MATE so I decided to give that a try.  I've been running Ubuntu MATE 16.04 for about a month now.
The 2 display issues I was having went away, screen locking up and external display not working
Weirdly, I can change my wallpaper, but user-supplied desktop backgrounds seem to be forgotten as soon as you switch away from them, so adding a bunch of my own backgrounds to the system-supplied ones and having them all available from then on as I am used to doesn't seem to work any more.  (Update: edit wallpapers from Control Center: Appearance: Background and the changes stick).
My laptop has hybrid graphics.  The way this is intended to work is a slower Intel GPU is used most of the time, saving battery life, but for graphics-intensive applications, a faster nVidia GPU is used instead.  After some considerable effort to understand and use this new thing back in 2013, I got Bumblebee configured and learned to use optirun or primusrun for games and graphical apps.

The bumblebee packages are available from the Ubuntu repos, but as far as I can tell the distro just uses the nVidia device for everything by default.  I found that I didn't care that much about the energy savings as I rarely run on the battery for more than an hour or so, so I wound up just leaving it this way.  There is a setting in NVIDIA X Server Settings (PRIME Profiles) that allows switching GPUs on a global basis that seems adequate for controlling power consumption if I needed to.

Overall I'm pretty happy with this distro, but at some point I'll probably give Mint 18 MATE a try, also.

See: Linux Mint MATE 18 Or Ubuntu MATE 16.04

Monday, September 5, 2016

Spring Boot

Last weekend I did a coding exercise creating a small Web MVC app with Spring Boot and Spring Data JPA.  Last year I worked through Spring Boot In Action but this was my first real Spring Boot app that went very far beyond Hello World.  I didn't need to write a single line of configuration.  I'm not just saying no XML configuration, no configuration at all.  Spring Data also does a great job of just getting out of the way and letting you work with your database.  I selected Spring Data JPA and HSQLDB from the start page and it just worked with no persistence.xml, no hibernate.cfg.xml or hibernate.properties, nothing.  This really is a game changer in terms of getting you out of the starting gate and focused on your application without having to go through a lot of Spring ceremony first.

Here's one other little thing I noticed.  With the introduction of @SpringBootTest in Spring Boot 1.4 the configuration for an integration test got a bit simpler.  This change is described here: Testing improvements in Spring Boot 1.4.

Friday, May 20, 2016

Spring Core 4.2 certification

I got my first certification today.  I have not been a big believer in these, but this is what my awesome employer was paying for this year so I took it.

I took the class first week in April and took the test today (5/20/2016).

Java configuration was a big part of this.  It seems like a big complaint people have had about Spring since the early years was the amount of XML needed to configure dependency injection.  The SpringSource/Pivotal people have been working for years to reduce the need for XML, first with annotations, then more recently with Java configuration.  I was fine with the XML and never really got on board with Java configuration, until now.  After learning this new style, well, now I can do it, but I'm still feeling lukewarm about it.  I feel like the motivation for this was more to silence the critics than to actually make the framework better.  I managed to struggle through a full conversion of a web flow application I wrote 2 1/2 years ago.  It's not quite a one-to-one mapping converting XML to Java as things are organized a little differently, and there are still a few things that aren't 100% comfortable to do in Java.

The MVC stuff was pretty familiar to me.

The class devoted quite a bit of time to RESTful web services.  The conventional wisdom in the Spring world is you could use JAX-RS but it's overkill, just implement REST services using MVC @RequestMapping.  I saw it done this way at some NFJS presentation a few years ago and since then they have added a bit more support (@RESTController, REST template).

AOP is a feature of Spring I have not really found much occasion to use, so this was something I needed to brush up on.

Some non-core topics covered in the class and the exam were Spring Data, Spring Security, Spring Boot and Spring Cloud.

I understand the focus on Spring Boot as this is quickly becoming the default way to work in Spring.  All the Getting Started guides are now written for Spring Boot and most of the labs for this class were also written as a @SpringBootApplication 'main' program.

I guess they chose to make Spring Security part of this because it is pretty much indispensable for doing any kind of real-world web development.  It has been around for a while, but my first exposure to this was in Spring Boot in Action last year, so this was a good refresher about 6 months later.

Spring Data simplifies the task of working with relational and NoSQL database so much, once you have started using it you will never go back.  In fact I questioned a little bit that they were spending time on JdbcTemplate but I guess it is part of Spring Core.  JPA is also covered.

Spring Cloud was the most 'out there' topic covered.  I have played around with this a little but some of the other people in the class were totally lost.

Generally I would say this was pretty hard.  The exam focuses on a lot of nit-picky details that you might not necessarily know even if you were working in Spring every day.  Before the class I was thinking 'could I schedule the exam on the last day of the class', but that would have been a disaster.  I spent about 6 weeks re-reading the 900+ page presentation from start to finish, experimenting with changes to my own code, and finally just re-reading selected parts of the reference documentation.  Think memorize-and-regurgitate.

There were about 5 people in the class, so, reasonable class size.  There was one guy who did not even have any Java experience who was slowing things down, and we were running behind right up until the end, but the stuff we didn't get to was not that important anyway (JMS, who uses that any more? and JMX).

The labs were just right for me.  I had to think but they weren't overwhelming or anything and I was mostly able to finish them during the allotted time or at least on the same day after class.

The supported platforms for the class are Windows and OSX.  In particular you do need one of these for the video chat for the online class.  I went to all the trouble of setting everything up in Windows 8.1 but afterwards was able to get Spring Tool Suite and the exercises working in Linux (my preferred environment).

One thing that confused people is the USB drive with the class materials comes with an ancient (3.6.4) version of STS.  That was about 16 months out of date at the time of the class.  So people were getting popups asking did they want to update?  Updating didn't seem to hurt anything, neither did simply importing all the exercises into an up to date STS version.  This was a bit troubling given the emphasis on Spring Boot, since the recent STS versions have added some Spring Boot support (Spring Boot Dashboard) that is not available in the older version.

In order to take the test, you must first take the (expensive!) class.  Taking the class entitles you to a voucher to take the test one time for free, after that it is $150.  Getting the voucher takes 2-3 weeks.  I can't help feeling they are being greedy here not allowing people to just come in off the street and take the test.  The instructor told us 'if you master the material in the lecture notes and the exercises, you will be able to pass the test', which I would agree with.  There were no surprises or anything I thought was unfair in the exam.

The test is fairly high-security.  I had to put my phone, watch, wallet and also empty my pockets(!) into a locker.  You need to sign a statement that you won't reveal the test contents to anyone.  It is 50 multiple-choice questions and the 90 minutes provided are really plenty to get through this.  I went through all the questions and then carefully went through them all again and finished in about 45 minutes.

As far as Spring itself, I'm still feeling very upbeat about this framework.  The future looks bright for Spring IMO.

It's a relief to finally finish and I'm looking forward to spending at least a couple of days not eating, breathing and sleeping Spring during every spare moment.

Thursday, December 31, 2015

Spring Cloud, Cloud Foundry

I returned to part 6 and part 7 of Building Cloud Native Apps with Spring with the idea of deploying the app into my local Cloud Foundry instance instead of IBM Bluemix.

I have to say that once you have got through the ordeal of setting up Cloud Foundry locally, it is a lot less trouble to work with than Bluemix.  I skipped over gobs of instructions about checking things into github, writing little shell scripts and navigating around doing things in the Bluemix web GUI.

All I needed to do to get this working was to register Eureka as a CF service:
cf cups ocr-eureka -p '{"uri": "http://ocr-eureka.bosh-lite.com/eureka/"}'
 and then make the changes described to the application.yml files.

I had a problem with the Hystrix app.  It was giving me a big stack trace about Tomcat failing to start.  This turned out to be the error that was causing the problem:

    java.lang.NoSuchMethodError: javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)Ljavax/servlet/ServletRegistration$Dynamic;

I found some discussion of this at Getting NoSuchMethodError: javax.servlet.ServletContext.addServlet in Spring Boot while running a Spring MVC application.  Checking the dependencies, I found that Turbine had a dependency on servlet-api 2.5.  I tried excluding that in the Hystrix POM:


and that fixed the problem.

Deploying an app into CF seems really slow.  It's doing some big downloads every time (Open Jdk JRE 1.8.0_65, Open JDK Like Memory Calculator 2.0.1_RELEASE, Spring Auto Reconfiguration 1.10.0_RELEASE).  I feel like it would be hard to work this way.  Wondering if there's a way to speed this up?