Saturday, October 27, 2018

Spring Boot, Spring Data JPA, jackson-dataformat-xml

At work, we had a RESTful web service application implemented in Groovy/Grails.  This probably started out as a SOAP web service and was then ported to Grails 1.1.1 (2009).  It worked, but had become almost unmaintainable due to the archaic tech stack.  Also, there was a desire to move away from Grails, which not many of the team knew, in favor of Java 8 and Spring.

This was about a one month project.  It built on the experience I got doing RESTful Web Service in Spring.

Since I was using Spring Boot, this web application could have run as a stand-alone Java app using the embedded servlet container support, and this is how I was debugging it at first, but the requirement was to have a drop-in replacement for the old Grails WAR file running in Wildfly, so that was an additional wrinkle.

The original service, which my program had to emulate closely, did not use HTTP methods in a RESTful manner, but instead mostly used GET and POST for everything.  This alone ruled out the use of Spring Data REST, so I needed to write controllers.

I started by creating a suite of integration tests which could be pointed at either the old or the new service.  This was invaluable for verifying that the new service performed identically to the old one.  Many problems in my implementation were exposed in time for me to correct them as a result of running these tests.

The application consists of a collection of endpoints, each providing read/write access to one table in the Oracle database.  Spring Data JPA really shone here.  I rarely needed to give much thought to the database access part and in the one case where I needed to do something outside of the method-name based query model (next value from an Oracle sequence), the native query escape hatch was there.  I think I like this better than GORM.  GORM tries to make everything easy for you but I always wound up spending a lot of time resolving issues with transactions, sessions and cascading... these issues just seem clearer and less hidden in Spring Data JPA.

For rendering the responses in XML, I used jackson-dataformat-xml.  See How to write an XML REST service.  At first I tried using the same classes for the database entities and the POJOs to be rendered into XML in the response, but the complexity of that soon got out of hand and I resorted to creating a separate set of DTO classes for the response POJOs.  This was the most unsatisfying part of the task for me, having this whole array of DTO classes with conversion methods ('from' and 'to')... it added a bunch of just infrastructure coding that had nothing to do with the business logic.

Going into Wildfly was mostly straightforward.  The one exception was authentication/authorization.  We had a custom Wildfly security domain which accessed LDAP for user data and Oracle for group and role data.  I was not able to find a generic way to support any Wildfly security domain with Spring Security.  I think the way to do this is with a custom authentication provider and user details service but the clock ran out on me and we went with something much simpler.

In the Wildfly environment I also needed to switch to using JNDI to resolve an Oracle data source configured in the container, but this is a breeze in Spring boot with

spring:
  datasource:
    jndi-name:    JNDI name of your data source here

in the application.yml file... this didn't take more than half an hour to figure out and make the change.

I had some difficulty at first getting the logging to work the way I wanted it to with the application deployed into a container.  I started out trying to keep the original Log4j 1.2.x configuration, but that doesn't seem to be very well supported in Spring Boot, and eventually I gave up and used Logback with a logback-spring.xml file.  This is one of those areas where there are a hundred different ways to do something and it's not always clear how to proceed.

Similarly, when it comes to configuring your Spring Boot application, there's such a wealth of features to support this, it's not always obvious what's the best way to meet a given requirement.  I wound up with two sets of application-(profile).yml files, one for running the application and one for running the integration tests

The service has been running in production for 3-4 weeks now.  This is the most ambitious Spring Boot and Spring Data project I have tackled and also marks an important milestone in our team's adoption of this technology.

Sunday, August 19, 2018

Java 11

I worked through this example:

It’s time! Migrating to Java 11

It was mostly pretty straightforward.  One thing I couldn't figure out, while trying to run my modularized Spring Petclinic JAR, I was getting this error:
Two versions of module javafx.base found in target/modules (javafx.base-11.0.0-SNAPSHOT-win.jar and javafx.base-11.0.0-SNAPSHOT-linux.jar)
I looked in target/modules and discovered what looked like 3 platform-specific versions of the JavaFX JAR.  I removed them manually
rm target/modules/javafx.base-11.0.0-SNAPSHOT-win.jar
rm target/modules/javafx.base-11.0.0-SNAPSHOT-linux.jar
rm target/modules/javafx.base-11.0.0-SNAPSHOT-mac.jar 
and then I was able to run the JAR.

Googling the error yielded no matches.  Why does this non-graphical, server-side application even have any dependency on JavaFX?  What's up with 4 separate versions of this JAR?

Monday, July 30, 2018

Still breathing

I changed jobs about 13 months ago and there hasn't been much time for blogging since then but I think I'm going to start making the effort again.

The new technologies I'm learning fall into 2 categories.  On the one hand, there's Big Data stuff like Hadoop, Scala and Spark.  On the other, there's client-side web development with AngularJS.  So these things are my learning priorities for the moment.

Almost all the Java programming we do is with Spring 4.3.  I was trying really hard to get into an environment where I'd be working in Spring all the time, so that worked out good.  My employer is running a couple of years behind the latest and greatest from Pivotal so I've done some training sessions there about Spring Boot and Spring Data and I think we're getting close to the critical mass where everyone sees the value of these innovations and the team as a whole is ready to adopt them.

JHipster is a technology I've got my eye on right now, seems like it might be a good match for what we are doing at work once we've adopted Spring Boot.

Automated testing has been a focus of my career for the last 8-9 years and we're currently making a priority of improving code quality, so there has been fertile ground for these ideas.  I've been working a lot with one of the other developers who is also passionate about testing.  We have done a few presentations and I'm also exploring some techniques I hadn't found the opportunity to use such as Spring Embedded databases.

We use Wildfly, so I got to renew my love affair with JBoss, sort of.  This decision was made to take advantage of Wildfly's support for JMS, but IMO the company would be better off separating the servlet/JSP container and the messaging server.

I'm trying to get up to speed on client-side automated testing tools like Karma, Jasmine and Protractor.  I'd have to describe my progress today as 'not over the hump yet'.  I've written a few tests in both Karma and Protractor but they don't come rolling off my fingertips.  It's still a big effort.

The Angular version we use at work is AngularJS (i.e. Angular 1).  Last time I looked, Angular was on version 6, so that's a bit frustrating.  I really need to focus on mastering what we use at work first, but there's a slight sense of wasted effort coming up to speed on a legacy framework.

The IDE we use is IntelliJ IDEA.  It's been fun using this and I have to say I now feel like this is the best Java IDE I've used, but I feel a bit guilty using a non-free tool.  I've played around a bit with Visual Studio Code and could see investing more time in that.  It seems pretty fast and powerful and will also support Spring Tool Suite 4.

The cool stack for Big Data these days seems to be Scala on Spark on Hadoop.  I was briefly interested in Hadoop after an NFJS presentation a while back but haven't really kept up with it.  Our direction before this was Cassandra and I learned a bit about Cassandra before this.

I'm about 2/3 of the way through a Coursera class called Functional Programming in Scala.  I would say the Scala language itself isn't especially hard but doing absolutely everything with functional programming will tie your brain up in knots like a pretzel.  I thought I was good at this from years of being a Lisp guy but what I quickly realized is what I used to do is use recursion where recursion seemed comfortable and procedural techniques where they seemed comfortable.  Pure functional is harder.

Comparing what I'm doing now with my Learning Priorities of 2015, Cloud Foundry and Gradle have fallen by the wayside.  We use Maven at my current employer and I don't think any of the places I considered before that were looking for Gradle.

'More Spring' was a good bet.  I've always been a bit skeptical about certifications, but in restrospect I feel the Spring Certification was a good move that got me back up to speed on the Spring basics and a few new developments at a time when I was getting rusty.

We were starting to use Docker a little at my previous job and it plays a small role where I'm working.  I would say this is good stuff to know but hasn't yet been critical for me.

Jenkins and CI were important at my previous job.  Now I'm a user of the Jenkins CI server but I'm not responsible for it as before.

TextMate, meh.  It was OK.  I used it for a few months but eventually went back to The One True Editor.

Currently reading: Soft Skills.  Keep up on what I'm reading at Goodreads.

I'm generally feeling like my career is back on track and it's a great time to be an active developer.