Eclipse vs. IntelliJ, an empirical rant

When I tell people how strongly I feel about my IDE preferences they are often surprised and go all "haters gonna hate" on me. Being all into empirical software engineering, here's a post on the little things that make all the difference between Eclipse and an IDE that actually puts effort into trying to understand people who write code (Java in our case).

A tail of 2 IDEs

Eclipse is a long time veteran in the IDE department, no doubt about it. It's been around forever, and is probably a synonym for 'a Java IDE ' for people who spent enough time working with it and haven't had a chance to take IntelliJ for a spin.
I believe it was circa 2012 when Eclipse started falling behind on both stability and features. I even remember posting a few times about what it was that finally made me switch to IntelliJ for good and never look back.

As fate would have it, I recently had to cross-path with Eclipse once again as part of an endeavour to develop an Eclipse plugin, no less. While interesting, the gory details of what that plugin was supposed to do are not the point of this post, instead, I will focus on the experience I had using Eclipse for roughly a month.
Being an IntelliJ enthusiast and evangelist (the kind that doesn't get paid by JetBrains) for more than a few years, the bias is true, I did however try to be as open minded as I could. I even picked up a shortcut or two!
That said, and that's a spoiler alert, my Eclipse experience was rather poor, only this time around, instead of resorting to arguments like 'Eclipse is ugly', I actually have empirical evidence to back my points (not that Eclipse is ugly though, other points).

Next time you get into one of those #what-IDE-is-better debates keep this post in mind so you can have some arguments ready.

Code completion



Seriously? "private" is only the 4th option?
It is because creating a stub method called "priva" looks like the most probable choice given that my caret is placed at the beginning of an almost complete method signature?

IntelliJ doesn't even give you options, it just silently completes this with "private" as if saying "sure thing man, anything else?".


Code Navigation

Go to type

In Eclipse, navigate to class (type) requires either typing in an exact prefix. Typing in characters that appear in the middle of the type name will not get you where you wanted to go unless you use wildcards (i.e., the "*" character). Now this is just annoying. Having to type in "*Tree*" when you want to go to "SpectraTreeVisitor" is sooo 90's.

The folks at JetBrains understand that the 90's were awesome but it's time move on, and not only are you shown matching results when you type in any consecutive substring (not just the prefix) of the type's name, you can also type in the camel case letters (e.g., "TEH" for "TestEventHandler") to get the matching results.

Edit: following a comment by a keen reader (and a short experiment) Eclipse supports the camel notation in 'got to type' as well. Cool!

Go to file

Same goes for the "file name" lookup, or "open resource" as Eclipse likes to call it. Another thing the smart folks at IntelliJ realized is that people often switch between looking for a type and looking for a file name, so when you have one of them open, hitting the shortcut for the other one just switches you over, which is what you would expect to happen. What you would NOT expect to happen in this case, is you having to first hit ESC, in order for the other shortcut to work. This kind of UX shenanigans was something people were used to in the early 2000's, nowadays when user experience is measured in click-distance, adding an entire click for nothing may result in users going WTF.

Let's talk about strackstraces. You know those "ResourceUtils.java:43" locations they give you, pointing to places of interest where exceptions were thrown?
Being the sophisticated AI machines that we human-beings are, it feels natural to take that "file-name.java:#lineNumber" string and paste it right into the "open file" or "open resource" search boxes. In IntelliJ this will actually bring you to the specified file and line number.
Eclipse will go "Ugh?!" right after it sees the semicolon in this string.

Edit: following a comment by another keen reader, the "Ugh?!" just turned into "Aha!".
Look at the stacktrace, now back to me, now back at the stacktrace, copy "ResourceUtils.java:43" into your clipboard (CMD + C), now back to me.
Look at Eclipse, hit SHIFT + CMD + V (a.k.a "open from clipboard""), where are you now?
You're at "ResourceUtils.java:43"!

Debugging

(The lack of) Variable inspection

In case you are not a Google employee who write perfect code even on paper, your are probably no stranger to debugging. As part of debugging, people often wish to see what certain variables hold. In Eclipse this is called "inspect", and if you ever get it to work - tell me how.
There seems to be a bug that prevents this dialog from showing in Eclipse Oxygen and every time an attempt is made, it shows for a second and disappears. Inspecting variables is debugging 101 so I'm not sure how an IDE can afford dropping the ball on something that important.

Ephemeral breakpoints

Conditional breakpoints are a great thing to have in your debugging toolbox, state a boolean expression and whenever it evaluates to true the breakpoint will be triggered. These boolean conditions can sometimes be tricky to get right and when you do it's a satisfying feeling. Which in Eclipse will not last long, since upon changing code that may very well be unrelated to your breakpoint, your breakpoint simply disappears. Not disabled, not invalid - gone. Experiencing your beloved breakpoint disappear after all the hard work you'd put into it is very disappointing.
Speaking of click-distance, before you can enter a condition expression you have to mark a checkbox that says "Conditional".


Step into my method

Sometime method calls are chained and you have a statement of the form "a.foo().bar();". At some point IDEs realized that it can be a good idea to let you step into "bar()" without making you first go through "foo()".

This is how it looks like in IntelliJ:



Eclipse has this feature too and it's called "step into selection". When I tried to use it the debugger hanged in a state described as "stepping":

Shortcuts

One of the things I like about IntelliJ is that shortcuts are kept consistent across different menus and contexts. For example, cmd + N means 'create new'. When you are in the editor this shortcut will suggest creating new methods, when you are in the project explorer view it will suggest creating new files and packages, etc'.
Running unit tests (ctrl+shift+R) will work both from the code editor and from the project explorer view when you select a test class or a package that has test classes.

I really missed that consistency in Eclipse, where the whole approach to the shortcut theme is quite different.


People who play the piano might not understand why I'm making such a fuss about it, but for me hitting alt+cmd+x+t using one hand is quite the challenge, and I'm not really game with a two hand shortcut for something as common as running unit tests. Ok, so change the binding one might think to himself.
Enter the key binding menu, let's search for "run test".... hmm - nothing.



ok, just type "run Junit test" and do it slooowly.


Turns out the approach that was chosen here is the opposite of consistent, and you can configure shortcuts for actions performed in different contexts. While I'm not a big fan of this, I guess I can understand the rational behind it.
What I cannot understand is how did anyone at Eclipse think that showing this to users is the way to go:



If you don't like the current key binding just change it, yeah and also feel free to specify what context this binding will be active in, out of these gazillion options.  Smooth.

Bottom line

I feel pretty comfortable dropping the IMHO and saying IntelliJ is by far the leading IDE for Java at the moment. 
Cynicism aside, I have a lot of respect for Eclipse as an institution, but as an IDE it has a lot of catching up to do. Seriously.

Comments

  1. While those are all valid points which could be reported as bugs or enhancement request to https://bugs.eclipse.org/bugs/enter_bug.cgi?product=JDT , there are a few things that are misunderstood or misleading:
    * The shortcut you see isn't the combination of 4 keys, but a combination of 3 keys and then 1 key. It makes things easier
    * I cannot reproduce the issue you see about Inspect popup failing, it works for me (I'm not on a mac though), but it really is a bug and should be reported as such
    * The issue you see with conditional breakpoints disappearing is a major bug, which should be reported as such. Again, I didn't manage to reproduce this one.

    ReplyDelete
    Replies
    1. Also, Camel Case is allowed and works in Eclipse IDE "Open Type" and "Open Resources" dialogs.

      Delete
    2. Thanks for the tip regarding the camel case notation in the go to type dialog!
      I've updated the post accordingly.
      (I'm ashamed to admit it didn't even occur to me to give it a try)

      Delete
    3. Btw, thanks for trying to reproduce some of the stuff I mentioned.

      While I'm not sure how to pinpoint the other UI quirks (inspect popup), I did manage to correlate the disappearance of the breakpoint(s) with having the google code formatter on and configured to kick in when saving files.

      In fact every time I hit CTRL+S the following happens:
      1. The code gets formatted.
      2. All breakpoints, conditional or not, are removed.

      I'm not sure who's at fault here (Eclipse, google formatter, or both) but perhaps this info could be helpful.

      Delete
    4. Thanks for this investigation Stas, that's quite helpful!
      May I try to convince you to report it on https://bugs.eclipse.org/bugs/enter_bug.cgi?product=JDT for more investigation ;) ? As an experimental workaround, I suggest you try disabling the google formatter and see whether things are better; but it could be a bug in Eclipse JDT dropping breakpoints when too many lines change at once (and that would qualify as a bug)

      Delete
    5. My last bug report to eclipse took place in 2011 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=361279) still waiting for it to be resolved... :)
      (not really)

      Anyhow, here it is - https://bugs.eclipse.org/bugs/show_bug.cgi?id=531186, hope it helps!

      Delete
  2. Regarding your "Go to File" example of "ResourceUtils.java:43": In Eclipse, you don't even need to open the "open file" or "open resource" search boxes first. You can directly paste "ResourceUtils.java:43" in Eclipse using Ctrl+Shift+V (Cmd+Shift+V in macOS) to invoke the "Open from Clipboard" command which will actually bring you to the specified file and line number. ;-)

    ReplyDelete
    Replies
    1. I did not see that one coming :)
      Thanks for the tip!
      (Updated the post to help spread the word)

      Delete
  3. Thanks for naming the things that bother you in the Eclipse Java IDE.

    I agree with you on some points, e. g. it should be possible to switch between the Open Resource and the Open Type dialog without hitting ESC. In the mentioned case of code completion, I disagree that "te" should be typed and suitable templates should be hold back. To use code completion for typing two characters doesn't sound like a time saver to me. In the Open Type dialog "*" is not needed at the end and it's a matter of taste whether you want to have subword matching with the disadvantage that you need something like "^Tree" for "starts with 'Tree'". No wildcards are required for example in "j.l.SB" to find "StringBuilder" and "StringBuffer" in the "java.lang" package.

    Eclipse can also be used as platform for desktop application. Parts of the Eclipse IDE can also be found in other applications: the Eclipse Java compiler, JGit, the OSGi framework Equinox or the help system, just to name a few examples. Even if you hate and don't use the Eclipse IDE, you will benefit from it. By the way, IntelliJ is shipped with the Eclipse compiler. ;-)

    ReplyDelete
    Replies
    1. Thanks for the comment.
      I have updated the post with a screenshot of IntelliJ's stance on code completion in our particular case. I even raised the stakes and only typed "p", so now it saves 6 characters, which is a 300% increase :)

      My main argument here was that Eclipse did not really get what was going on. The context of where the caret was provided enough information to conclude that I was probably going to change the access modifier rather than generate a new method conveniently named "priva".

      As far as looking for a type goes, I think that looking for a type you don't remember the name of is a kind of distress, and an IDE should help you out of this distress by being as flexible (and supporting) as it can, at least IMHO.
      Also, based on some experiments I did, it seems that when you type a string in the search-for-type dialog in IntelliJ, it ranks types that begin with that string higher than the ones containing it so you don't have to worry about "^Tree".

      Cool, I wasn't aware that the Eclipse compiler was included in the out-of-the box version of IntelliJ :)
      (I think that javac is till the default though)

      Delete
    2. Thank you for updating your post, but you missed "*tree" instead of "*Tree*".

      Depending on your programming style, you have different expectations of what should be proposed. For example, if you do test-driven development, you do not start writing a private method but generate it via "Extract Method" (Alt+Shift+M). Also if you can write quickly (e. g. by using touch typing), you won't want the code completion to propose keywords to you. At "p", the proposal to overwrite the "hashCode" method does not meet my expectations, to say the least (I would rather type "hash" for that). In your example, none of IntelliJ's proposals make sense to me. Let me explain it with another example: in Eclipse you type "main" to generate the main method via code completion, whereas in IntelliJ you have to type "psvm" as shortcut for "public static void main". If I can remember "psvm", I can type it myself. Also at "Navigating by name"/"Open Type/Resource" we seem to have different preferences.

      Yes, javac is the default compiler in IntelliJ. Several javac bugs have been found and fixed with the help of the Eclipse compiler. So even not using the Eclipse compiler you will benefit from it. Probably you also have used JGit in other applications without knowing it. I wouldn't be surprised if IntelliJ would also use JGit in the future, just like NetBeans already does today.

      Delete
  4. One thing that annoys me with IDEA is that it doesn't use common shortcuts (eg. Ctrl-N and Ctrl-O) as all other apps do.

    ReplyDelete

Post a Comment

Popular posts from this blog

Reflecting on reflection in Scala and Java