On pointless Java 8 embellishments, or an exercise in simplicity

While performing a code review, I stumbled upon this little gem:

Long num = someFunctionThatNeverReturnsNull();
if(Optional.ofNullable(num).orElse(0l) > 0) {
  // ...

The salient part, of course, is the if-statement. It’s rare to come across a single line with so many layers of wrongness.

  1. First, let’s talk about 0l. Depending on your font, that might look like zero one, zero el, o one or o el. By convention in Java, this should be zero EL: 0L. This is easier to read, and the suffix L makes it clear that we’re dealing with a long instead of an integer. That would look something like this:
    if(Optional.ofNullable(num).orElse(0L) > 0) {
      // ...
  2. Second, what’s going on with these data types? 0L is now obviously a primitive long which will be auto-boxed to a Long object. num is a Long object. And then there’s the dangling 0. Which is a primitive integer (int). For one reason or another. Now, I admit that casting to long or int is pretty cheap. This is never going to be a performance issue. But consistency is a good thing. You probably want to compare like with like.
    There’s also a bit of weird auto-(un)boxing going on here. 0L will be auto-boxed to Long. But the result of the orElse() bit will be unboxed to a primitive long. The comparison will then be comparing a long to an int, which causes the int to be widened to a long.
    There isn’t much we can do about the auto-(un)boxing in this case, considering the comparison we want to perform. But we can at least ensure we’re using consistent data type width. So this:

    if(Optional.ofNullable(num).orElse(0L) > 0L) {
      // ...
  3. And lastly, why the fuck are they using Optional in the first place? Never mind the fact that num can’t even be null here. The “plain”, non-embellished form of this statement would have been shorter and easier to read. That would look something like this:
  4. if(null != num && num > 0L) {
      // ...

Here is the “corrected” version:

long num = someFunctionThatNeverReturnsNull();
if(num > 0L) {
  // ...

I can’t fathom why anyone would write garbage like this. It’s pointless. It’s hard to read. It’s ugly. And it’s bloody inefficient.

Endless Locale Bugs

This isn’t the first time I’ve ranted about Locale related issues. It probaly won’t be the last, either.

Currently my biggest gripe is with convenience methods in Java which rely on platform defaults, and are thus platform-specific. For instance, the venerable System.out.println() will terminate your line with whatever your platform thinks a line ending should be. Printing dates or numbers will try to use your platform Locale. Writing a string to a file will default to platform encoding.

Some of these defaults can be controlled at run time, others require JVM startup options. This is all horribly wrong. This results in all kinds of unexpected behaviour. It’s error-prone. None of this should be allowed to happen. Any method that assumes platform-specific magic should be deprecated. Which is exactly what I’ll do, as soon as I can figure out how to write a Sonar plugin to detect all this nonsense.

Character sets, time zones and hashes

Character sets, time zones and password hashes are pretty much the bane of my life. Whenever something breaks in a particularly spectacular fashion, you can be sure that one of those three is, in some way, responsible. Apparently the average software developer Just Doesn’t Get It™. Granted, they are pretty complex topics. I’m not expecting anyone to care about the difference between ISO-8859-15 and ISO-8859-1, know about UTC‘s subtleties or be able to implement SHA-1 using a ball of twine.

What I do expect, is for sensible folk to follow these very simple guidelines. They will make your (and everyone else’s) life substantially easier.

Use UTF-8..

Always. No exceptions. Configure your text editors to default to UTF-8. Make sure everyone on your team does the same. And while you’re at it, configure the editor to use UNIX-style line-endings (newline, without useless carriage returns).

..or not

Make sure you document the cases where you can’t use UTF-8. Write down and remember which encoding you are using, and why. Remember that iconv is your friend.

Store dates with time zone information

Always. No exceptions. A date/time is entirely meaningless unless you know which time zone it’s in. Store the time zone. If you’re using some kind of retarded age-old RDBMS which doesn’t support date/time fields with TZ data, then you can either store your dates as a string, or store the TZ in an extra column. I repeat: a date is meaningless without a time zone.

While I’m on the subject: store dates in a format described by ISO 8601, ending with a Z to designate UTC (Zulu). No fancy pansy nonsense with the first 3 letters of the English name of the month. All you need is ISO 8601.

Bonus tip: always store dates in UTC. Make the conversion to the user time zone only when presenting times to a user.

Don’t rely on platform defaults

You want your code to be cross-platform, right? So don’t rely on platform defaults. Be explicit about which time zone/encoding/language/.. you’re using or expecting.

Use bcrypt

Don’t try to roll your own password hashing mechanism. It’ll suck and it’ll be broken beyond repair. Instead, use bcrypt or PBKDF2. They’re designed to be slow, which will make brute-force attacks less likely to be successful. Implementations are available for most sensible programming environments.

If you have some kind of roll-your-own fetish, then at least use an HMAC.

Problem be gone

Keeping these simple guidelines in mind will prevent entire ranges of bugs from being introduced into your code base. Total cost of implementation: zilch. Benefit: fewer headdesk incidents.

What bugs me on the web

2013 is nearly upon us, and the web has come a very long way in the ~15 years I’ve been a netizen. And yet, even though we’ve made so many advances, it sometimes feels like we’ve been stagnant, or worse, regressed in some cases.

Each and every web developer out there should have a long, hard think about how the web has (d)evolved in their lifetime and which way we want to head next. There’s an awful lot happening at the moment: web 2.0, HTML 5, Flash’s death-throes, super-mega-ultra tracking cookies, EU cookie regulation nonsense, microdata, cloud fun, … I could go on all day. Needless to say: it’s a mixed bunch.

In any event, here’s a brief list of 3 things that bug me on the web.

Links are broken

Usability has long been the web’s sore thumb, and in spite of any number of government-sponsored usability certification programmes over the year, people still don’t seem to give a rat’s arse. Websites are still riddled with nasty drop down menus that only work with a mouse. Sometimes they’re extra nasty by virtue of being ajaxified. At least Flash menus are finally going the way of the dinosaur.

Pro tip: every single bloody link on your web site should have a working HREF, so people can use it without relying on click handlers, mice, javascript and so people can open the bloody thing in a new tab without going through hell and back.

Bonus points: make your links point to human-readable URLs.

Languages, you’re doing it wrong

The web is no longer an English-only or US-only playing field, and companies all over are starting to cotton on to this fact. What they have yet to realise, however, is that people don’t necessarily speak the language you think they do. If you rely on geolocation data to serve up translated content: stop. You’re doing it wrong. The user determines the language. Believe it or not, people do know which language(s) they speak.

Geolocation, for starters, isn’t an exact science. Depending on the kind of device this can indeed be very accurate. Or very much not. Proxies, VPNs, Onion Routers etc can obviously mislead your tracking. Geolocation tells you nothing. It doesn’t tell you why that person is there (maybe they’re on holiday?). It also doesn’t tell you what language is spoken there. This might be a shock to some people, but some countries have more than one official language. Hell, some villages do. Maybe you can find this data somewhere, and correlate it with the location, but you’d be wrong to. Language is a very sensitive issue in some places. Get it right, or pick a sensible default and make clear that it was a guess. Don’t be afraid to ask for user input.

Pro tip: My favourite HTTP header: Accept-Language. Every sensible browser sends this header with every request. In most cases, the default is the browser’s or OS’s language. Which is nearly always the user’s first language, and when it’s not, at least you know the user understands it well enough to be able to use a browser..

Bonus points: Seriously, use Accept-Language. If you don’t, you’re a dick.

Clutter is back

Remember how, back in 1999, we all thought Google looked awesome because it was so clean & crisp and didn’t get in your face and everyone copied the trend? Well, that seems to have come to an end.
Here’s Yahoo in 1997. (I love how it has an ad for 256mb of memory.)
Here’s Yahoo now.

The 1997 version was annoying to use (remember screen resolutions in the 90s? No? You’re too young to read this, go away) because it was so cluttered.
The 2012 version is worse and makes me want to gouge my eyes out.

Even Google is getting all in your face these days, with search-as-you-type and whatnot. Bah. DuckDuckGo seems to be the exception (at least as far as search engines go). It offers power without wagging it in your face.

Pro tip: don’t put a bazillion things on your pages. Duh.

2013 Wishlist

My web-wishlist for 2013 is really quite simple: I want a usable web. Not just people with the latest and greatest javascript-enabled feast-your-eyes-on-this devices. For everyone. Including those who use text-to-speech, or the blind, or people on older devices. Graceful degradation is key to this. So please, when you come up with a grand feature, think about what we might be giving up on as well. Don’t break links. Don’t break the back button. Don’t break the web.

Bad Press for Agile

So .. Agile’s been getting some bad press of late. Now, these guys are just quacks, and I probably shouldn’t feed the trolls here, but I never could resist.

Saying “agile doesn’t work” or “agile is only out to sell services(training,certification etc)” is obviously a bogus claim. The same could be said of any software methodology. Many waterfall projects have failed, and many have had the help of process improvement engineers and whatnot. Some projects will always fail. A sound development methodology & culture can help you realise imminent failure earlier, or it can help reduce chances of failure. But no methodology is a guarantee for success. A team of idiots run by idiots will always produce crap. No matter how many buzzwords they fit in their job titles or marketing blurbs.

Agile is many things, but no one has ever claimed it to be a silver bullet. As for for it being “for lazy devs”: all developers are lazy, it’s part of the job description. It’s why we automate shit. It’s why we focus on code and not on hot air.

My recommendation to you: use whatever works for you. And in doing so, you’re already on your way to being Agile :-).

OutOfMemoryError while running Maven Surefire tests

Imagine you have a project which works perfectly fine and well. All tests pass, each and every time. Then one day you commit a couple of new classes with related tests. Of course you ran all tests before committing, and everything worked just fine. Then, a minute or so later, you get a mail from Hudson (or whatever you’re using for CI) saying that there are test failures. “Maybe I forgot a file”, I thought. Checked the test results on Hudson. About a dozen tests were failing, unrelated to anything I touched. Odd. OutOfMemoryErrors all over the place. Most odd. Hudson’s tomcat has 1G, which should be plenty. Same with each build’s MAVEN_OPTS.

Apparently, someone who wrote the Maven Surefire Plugin thought that it would be a GREAT idea to ignore things like MAVEN_OPTS and other memory settings. The plugin seems to start a new JVM instance to run the tests. Without any of the arguments you so carefully selected. No. Apparently you have to explicitly tell the Surefire plugin that maybe, just maybe, it would be a good idea to use the memory settings you already provided elsewhere.

Anyhoo, this fixed it:


DRY, you say? Not so much, eh.

Maven 3 resource filtering weirdness

Maven 3 is all nice and fast(er) and shiny, so I decided to upgrade a Maven 2 project to Maven 3. It (cl)aims to be backwards-compatible, so my consternation was pretty great when my build failed straight away. That’s to say, my tests failed. For some reason, my resources were no longer being filtered. Yup, ${property.keys} weren’t being replaced by values.

This struck me as being somewhat odd, because it worked fine with 2.2.1. A bit of debugging led me to the cause of the problem:

<!-- @Transactional can now be used as well -->

… apparently, the @ symbol is an escape character of sorts.

Considering that blurb on their website doesn’t even qualify as English, I’m not sure if this is a feature or a bug. But whatever. Removing that comment fixed the problem. Whoever came up with that bright idea (especially in an age where @annotations are as rampant as the black plague in the 14th century) probably deserves a spanking.