Learning to Appreciate IntelliJ

Nov 22, 2018

I'm a big fan of Eclipse, both the IDE and the foundation - I like how organized they are, I like that they're stewarding Jakarta EE, I'm ostensibly a committer, and I even have an Eclipse T-shirt. I'm all in!

However, I have to admit that the IDE has been grating on me for a lot of my work lately. The two big ways are the ever-present troubles when working with OSGi projects and its surprising UI slowness when working with a lot of projects in the workspace. Though it's sitting on top of an eight-core Xeon, it just drags - expand/collapse animation is slow, the editor freezes up frequently when trying to autocomplete, and it's just a dog. I had high hopes that Photon's push for speed would alleviate this, but it's still a drag. I think it's probably faster on Windows, but that's just not worth contemplating.

Moreover, my work with Darwino involves Android apps, and Android development in Eclipse just completely lost steam after Google switched to IntelliJ. The Andmore project aimed to keep it alive, but you can see how far that went just by looking at the release list. It can still kind of work, but it's very much swimming against the current.

So I've been on the lookout for alternate IDEs for some or all of my work. Visual Studio Code has been a strong contender. I've already switched to it for most JavaScript work and it has decent support for Java projects by way of the Java Language Server. However, despite that project being run by Eclipse, it doesn't support Tycho projects, and so I can't use it for full OSGi development. Moreover, though it's very capable, Java support clearly isn't its main focus, and so it won't cover all the same bases as a "proper" Java IDE.

But looming in the corner the whole time has been IntelliJ IDEA. I'd used it here and there for Android apps, and it was okay, but it always rubbed me the wrong way. Part of that is just muscle memory from Eclipse - any different IDE is going to be inherently annoying in some way just because it's different. Some of it was also runoff resentment from working with Android, so I could discount that too. It doesn't help that the UI is written in Swing, and so, even with its Mac-ish coat of paint, it still feels like running some kind of weird Linux app. Eclipse isn't exactly fully Mac-like either, but SWT carries it much further along.

But still, I figured I should give it a real shot. Lots of people swear by it, especially as converts from Eclipse, so it has to do something right. As it turns out, it does quite a bit right.

Speed

So far, I've found it to be significantly snappier than Eclipse for the kind of work I'm doing, and without all the UI blocking that's been plaguing the latter for me for a while. Autocomplete happens quickly and consistently and doesn't freeze the UI, project import processing happens quietly on background threads, and everything just feels smooth.

Java Intelligence

IntelliJ's Java support carries quite a bit of cleverness, and JetBrains made great selections for what to enable by default. It's particularly good at what Eclipse refers to as "code mining", where it will inspect your code and add little visual annotations to make what you're doing more clear. For example, I love what it does with "stream-style" chained code:

It has all sorts of little niceties like this, and does pleasant things like compressing pre-lambda functional-interface calls to look like lambdas even in Java 6 projects. And another favorite: pseudo named parameters, automatically showing when it's most useful for clarity:

It's also pretty good at recognizing legal-but-inadvisable idioms and offering in-place conversions. For example, if you write this:

This sort of thing isn't unique to IntelliJ (Eclipse has some of this and there's no shortage of code-linting tools), but it does a particularly good job integrating it in a useful and non-obtrusive way.

OSGi

Though Eclipse is something of a flagship user of OSGi and so much of the IDE is geared around plug-in development, it sure does make it a real PITA to use sometimes. In particular, the single active Target Platform per workspace, configured manually in the preferences, is a huge hurdle when dealing with multiple diverging OSGi projects.

IntelliJ handles this much better for my needs. Primarily, it does this by letting its OSGi plugin (dubbed Osmorc) construct the platform per-project from whatever the project's dependency mechanism is. In the case of Tycho, this means that it will pick up on any p2 repositories specified within the project (such as the ${notes-platform} one commonly used for XPages libraries) and find the dependencies in much the same way that Tycho itself does. This means you don't have to worry about hand-holding the IDE to make it do a job that the build system already knows how to do.

I think that you wouldn't want necessarily want to use this to run and debug full-fledged Eclipse RCP applications, though I imagine you could via Maven goals if nothing else. For my needs, though, it seems like it hits exactly the right level of support.

External Annotations

I became a convert to null analysis a while ago, and I like to stick with it as much as possible. One of the things that makes it a little awkward, though, is that the core JDK classes - String, etc. - don't have any annotations. Most checking tools, Eclipse included, support the concept of "external annotations": a separate definition file that can tell the compiler that, say, String.valueOf(...) will always return a non-null value without having to modify the compiled classes.

Where IntelliJ's pleasantness comes in is that automatically applies a set of external annotations to the JDK, whereas Eclipse is more of a bring-your-own sort of thing. I never bothered figuring out the right way to do it in Eclipse, and so it's great to just have that set up for me without having to think about it.

JavaScript/TypeScript/etc.

I haven't worked too much with JavaScript apps in IntelliJ yet, but I know that WebStorm is highly regarded, and I sprung for the Ultimate edition, so it's sitting there for me anyway. Just a quick glance shows that it's much more comfortable than Eclipse: I have npm-based JS projects wrapped in Maven projects, and it picks up on both aspects just fine. I can open up a JSX file and it properly builds the class hierarchy, finds dependencies, and all that. Eclipse, on the other hand, hasn't seemed to update its JavaScript editor since about 2001, and the third-party plugins are a mess of limited functionality, incompatibility, and extra cost. It would sure be nice if I can use IntelliJ for my JS dev instead of having to hop between it and VS Code (as nice as VS Code is).

The Future: Plugin Development

I'll go into this more in my next post, but my trial-run project to get comfortable with IntelliJ was to port the run-from-workspace aspect of the XPages SDK to IntelliJ, and I did so successfully. It turns out that the plugin mechanism is characteristically clean and straightforward, at least for what I need to do, and I expect I'll be doing similar work for Darwino.

So, as much as possible, I think I'm going to try living in IntelliJ for a while and see how it treats me. So far, so good, in any event.

Since my recent blog post about JVM heap size, I enabled the preference to display that in Eclipse. I've noticed the heap size quite a bit higher than in Notes.

The one project I downloaded and used IntelliJ for had a dependency on Lombok. That's available out-of-the-box on IntelliJ. I'm not sure it would work in a Domino OSGi plugin, but it is very nice for shorter class definitions. It's possible to install ombok on Eclipse, but a much ore manual process.

I look forward to your next post.

Nov 22, 2018

Jesse Gallagher

Lombok's not too bad for me in Eclipse, and it's easy enough to add for normal Maven projects. It's trouble in Tycho-based Maven projects, though - it takes some extra external configuration to get it added into the compilation process, which is a bit sad.