What I've Learned As A Java Engineer


I’ve recently been working on a project where, as part of my delivery responsibilities, I’ve also been getting hands on with writing some Java code. I’ve been luck to be teamed up with some great Java experts and managed to keep myself out of the critical path, but have managed to get deep enough to be writing API endpoints with database peristence and cucumber tests. Here are my quick thoughts on the experience.

The IDE is King (and sucks)

I’m a vim guy. Well, to be more accurate I’m now a neovim guy. I’ve crafted my configuration over years to allow me to work quickly and consistently in nearly any language… except Java. The language and the concept of IDEs has become completely inseparable and I’m not sure it’s for a good reason.

The theory behind using an IDE is that it gives you some powerful tools right out of the box that are essential with a language that requires as much boilerplate code as Java. Changing the name of a class and having it update everywhere sounds great. Getting project aware autocomplete suggestions also sounds great. The thing is, when it comes down to it, I’ve never had a problem quickly renaming things in vim – running ripgrep across a normal project size does’t take long, and anything I miss gets picked up by failing tests. Autocomplete also sounds great, until you realise that as an inexperienced Java dev all I’m doing is picking the method that sounds like the thing I want to do without any understanding of how it works – that’s not software engineering, that’s being a low rate code factory.

In fact, throughout this project I’ve had vim open the whole time, because despite being on a 2022 Macbook Pro, Intellij feel sluggish. Most of the time spent editing isn’t writing new functions, it’s reviewing what already exists and was just outright faster in vim. But why didn’t I just use vim? Well, the ecosystem is so geared to using an IDE that the only really effective way to work in vim is to run a headless Eclipse instance as a language server, which just doesn’t feel right.

There is one piece of value that I have got out of the IDE and that’s easy access to a debugger. Understanding why some of my code hasn’t been working has at times been faster because of this, and it’s definitely something I’m going to explore using more of in other languages, but that’s not enough to make me move to an IDE.

It’s about the framework

When people talk about writing Java in an enterprise context, most commonly it’s Java Spring Boot. It’s the same difference between saying you can code in Ruby vs Ruby on Rails. Sure you might know the language inside out, but unless you know the specific incantations that the framework requires you might as well be starting from scratch.

I do think there is a crucial difference between this and Ruby on Rails though. Sure, I’ve told junior engineers to just write this ActiveRecord statement and not worry about how it works, but it was only ever a couple of steps to get into the framework code if you did want to understand it. With Spring it’s much more abstract. Firstly, everything is done through annotations – it doesn’t even look like real code, and in essence it isn’t. You’re mostly building software with pre-cast bricks, just providing cement. As long a you know what the bricks are the skill level is pretty minimal. Secondly, there is so much of it that it’s hard to find an easy entrypoint to understand it – and the fact that Google returns absolute junk results for any Java programming related queries makes it even harder.

The end result is that it’s very easy to go down one of two paths – you can either end up cargo culting the annotations, e.g. I used this annotation on a class in the past and it worked so I’ll just use it again, or to miss really simple ways of doing things because you hadn’t happened to come across the incantation before.

The other major difference with Rails is I generally didn’t have to change my design on implementing Rails. The framework was generally flexible enough to accommodate how I wanted to do things, within the general bounds of how a Rails app should work. With Spring I’ve seen multiple small changes across several engineers to tweak the design to how Spring wants to work because stepping off the paved path can lead to massive amounts of code to work around what they think you should do.

It makes sense in a certain context

There appears to me to be something inherent in the process of writing code for Java vs nearly every other language and that has big impacts on what a team looks like for developing it. With every other language I’ve seen teams of people work well together effectively as equals – the time to get idea from head into code is low enough that it makes more sense for all levels of developers to be actively working on code production.

With Java this seems very different. The effort on implementation seems generally to be much higher load than deciding how a problem will be solved, and they start to become 2 distinct skill sets. Whereas a team of Python or Ruby developers may effectivaly be a team of peers under a lead, a Java team works better in a master/apprentice relationship. Similar to how John Williams just sketches out a melody and approach to a piece and then leaves it up to the orchestrators to do the less fundamental work of expanding that out for a whole orchestrator, so a Java team should probably have a single principal that sets an approach and reviews codes, but it’s a waste of their high salary for them to be writing all the multiple layer of DTO, repositoty, DAO, Entity, etc. That work should be taken up by numerous less skilled developers.

And this is where it takes me to the question of does Java mirror Enterprise structure or has Enterprise structured itself around Java. The idea of having specialist architects that dictate approaches actually fundamentally makes sense in a Java context, but only a Java context. It suits the Enterprise where you can hire a small number of skilled architects and a huge number of outsourced bodies to implement, but only when you have tight quality control processes.