Wednesday 20 April 2016

The Facebook Experiment

So after years of denying my need for this little website, I finally joined Facebook. The main reason was that here in the UK it seems to be an even more integral part of society than it already is in Germany. Particularly smaller organizations seem to use it as their primary communications channel. One of these is our daughter's pony club. For the first few months I denied a need to open a Facebook account - after all, my beloved wife already had one and was making good use of it. However, at some point I realised there may be a benefit in being notified directly without her having to act as relay.
So now I'm on Facebook. I already added a few people I came across in my life - in some cases they had sent me invitations years ago, and FB had still stored these!
My first impression is not to good though.  I've been on LinkedIn and GooglePlus for several years now, and I must say that I absolutely miss a practical way of categorizing my connections. When it started, Plus war praised for its "Circles". LinkedIn offers the option of associating connections with "tags" - not quite as user friendly as the circles, but still works quite well. And this makes a lot of sense. All of us are part of different groups that most often share only one individual as their common denominator - yourself. I think the sociological term for this is "peer groups". I wouldn't want to share a pony club story with everyone I went to school with 20 years ago.
Plus (maybe this is a German thing) I don't think of all of my connections as friends. Many are really only acquaintances that I still like to stay on contact with - not the same as a friend with whom I share more personal things. When you share something with all your Facebook "friends", you may as well just share it publicly. It makes no practical difference.
I know that Facebook has friends lists (and I already started filling them), but these are by far not as easy to use as the Plus circles or the LinkedIn tags. Most of the time, when you think of a person, you associate them with a group through which you know them - not the other way around. On to of that, many of your connections belong to several categories. One example: Over the course of my life, I've been a member of several chess clubs. So, naturally, I met a lot of different people in this way. I have a category for the Werder Bremen Chess department, another one for the Hamburg Chess Club of 1830, one for SC Königsspringer Alzenau and so on. All of these connections are part of the overall category "chess", some are friends, some are close friends, many rather count as acquaintances. So in technical terms your personal connections form an "m:n relationship". Plus and LinkedIn reflect this reality quite closely. Facebook still doesn't - years after Plus went live. I remember that at that time the circles were absolutely hyped - now I understand why. This is really a very basic functionality.
In terms of other aspects, let's just say that I only started over the weekend. However, so far I haven't found anything which makes Facebook superior to Plus - speaking from a functional point of view. (I know the user base is supposedly larger.)
So apart from a decent categorization functionality, I haven't found real difference between Facebook and Plus. Please let me know your opinions on this. And please try to be objective. No fanboy flamewars...

Rediscovering Maven's assembly plugin

Our team was faced with the following (actually quite simple) task: Extract all configuration files from the WAR (or rather the jars inside the war) and deploy them separately, while at the same time allowing the lazy efficient developers to just continue using mvn tomee:run like nothing changed. The reasoning behind this separate deployment was that we want to be able to change the configuration without having to rebuild the war.

Since our project is fully Maven-based, it seemed quite obvious that the solution to this must involve the assembly plugin. Personally, I had only one experience with it from a few years back, and it sure has evolved since then. Effectively, all goals except for one (+ help) have been deprecated. WOW! Nevertheless, it's still extremely powerful. So powerful that reading the documentation can lead to quite a bit of confusion and headache.

Don't get me wrong, I haven't found anything that's really missing. It's just overwhelming, because the assembly descriptor can do so many useful things.
We came up with a solution which I have outlined in a simple demo project in my GitHub account. The basic steps were:

  1. Extract the config files into their own separate maven module.
  2. Add this maven module as dependency with scope test where needed (this will normally be the module they were extracted from). In the example project, this is happening in modularised-webapp-library.
  3. Don't add the configuration as dependency to the war project. Instead, add it as a server library to the tomee plugin as demonstrated here.
  4. Create another maven module only for the assembly which has dependencies onto the war and the configuration module.
  5. In the assembly descriptor, define two separate dependency sets. The one for the configuration module unpacks the configuration module and removes the maven metadata, while the one for the war only copies the war directly.
That's really it. Took us quite some effort to find this solution, but I really like the overall simplicity.

The architect is happy, because he can edit the files as he wishes without redeployment. The developers are happy, because the tomee plugin is still running the way we're used to.

(And I'm happy, because I can show off some knowledge again. ;-) )

What is your experience with building assemblies?

Friday 26 February 2016

JavaFX with Spring (and a few other technologies...)

A few weeks ago I was asked to develop a little software that would solve a real-life issue: A teacher with a worldwide audience, who regularly sends out standard emails reminding his listeners of the next lesson which includes dates and times in different places around the world, asked for a way of reducing the time he spends on creating these emails. So far, he had used one of the many websites out there to convert the date and time in his timezone into the respective dates and times around the world, but always only one at a time - and then copied the results into a standard text (again, obviously, one by one). Due to the mass email service he uses, calendar invites were not an option.
So I spent some time researching and to my own surprise didn't find a free service or software which would help reduce his worktime. Thus, I wrote one myself. The result is visible on my GitHub account. In this post, I'd like to give an overview of how I used what I consider the main technologies for this little project:

JavaFX

No big surprise here, this is the only choice you should make nowadays when using Java for desktop development. Maybe it's the fact that I'm old-school, but I just did everything in pure Java without any FXML. Comes more natural to me. The UI does the job, but can certainly use some improvement - in particular the ZoneIdSelectionDialog. It's way too large and lacks a nice structure. If anyone has some ideas how to improve this, please go ahead and fork me.

Spring

It's a Java SE project, so there's no native CDI. Therefore I added Spring into the mix. The annotations work like a charm. The aforementioned ZoneIdSelectionDialog is also a Spring component - which shows the (from a developer's point of view) only downside of using Spring (or any other Dependency Injection framework) within a JavaFX application:
The lovely Application class follows a very straightforward pattern when launched:
  1. Constructs an instance of the specified Application class.
  2. Calls the init() method.
  3. Calls the start(javafx.stage.Stage) method.
  4. Waits for the application to finish, which happens when either of the following occur:
    • the application calls Platform.exit()
    • the last window has been closed and the implicitExit attribute on Platform is true
  5. Calls the stop() method
So far, so good. So think for a moment: Where would you want to instantiate your Spring beans? Sounds like it should be part of the init(), doesn't it?
The bad news is: This doesn't work when you use Spring (or any other DI framework) to initialize a JavaFX component, because these are only allowed to be constructed on the so-called JavaFX Application Thread. If you've never heard of it, this is where all the UI beauty is actually executed (for Swing veterans like me: It's the equivalent of the Event Dispatch Thread).
So this leaves us no choice but to initialize the Spring context first thing in the start(javafx.stage.Stage) method which seems unnatural, but is a technical restriction. Nevertheless, the gain outweighs this.

The Java Time API

A great addition to Java 8 and probably the one which generated the biggest buzz aside from Lambdas and Streams, I found it nice to use. This application only shows a small portion, but it already highlights a few key advantages over the much older Date and Calendar classes:
  • Instant and the other "value" classes in the package are immutable. This eases their usage and automatically makes them thread safe.
  • The same holds for the DateTimeFormatter - which I consider even more valuable. I've stopped counting how often in my career I stumbled over a strange behavior which I traced back to an unsafe usage of SimpleDateFormat, e.g. as a constant. This is bound to break in a multithreaded environment, as this class isn't thread safe.

Apache Velocity

OK, this library's usage in here is really a no-brainer. I'm using it in a very basic way to replace two tokens with values which are computed in the application. Probably smarter usage is possible, but I wanted to give the user an option of not using a template at all. I know that Velocity can do a lot more, but I really had no need for anything else here.

Lessons learned

  1. Use JavaFX! It's even better than you think.
  2. DI fits in nicely with FX if you keep in mind that you must use it in a slightly "unnatural" way.
  3. The Java Time API is just great. If you haven't done so yet, get acquainted with it. In my view, it's now about time (please excuse the pun) to deprecate Calendar and SimpleDateFormat.
Questions? Criticism? Ideas for improvement? Please feel free to leave any of these in the comments section or as mentioned, fork me on GitHub.