Sunday, July 12, 2009

Bye, Bye Eclipse

I finally had to end a long term relationship. It was a strong one that I was deeply committed to for a long time, but since last summer it had really started to sour. My partner demanded more and more of my time and resources just to keep her functional. I often just couldn't figure out what she wanted, or why she would decide to shut me out sometimes. Plus, I wanted to try new things together, and while she said she would support such things, the support was really halfhearted, at best. And I have to admit, there is someone else I've had my eye on for a while.

Yes, it was time to leave Eclipse and get to know Intellij better. There is a lot to like about Eclipse. It's a very strong java and J2EE development platform. The number and diversity of plugins is truly staggering (in both good and bad ways). But it feels like it's grown almost too big as a base platform. The deciding factors for me were the prolonged lack of solid groovy/grails support combined with my group's shift to maven. (See my previous post on Eclipse's groovy troubles.) The m2eclipse plugin looks pretty good, but there were just too many times when changing a file in some project that was the dependency of many others would trigger a massive rebuild. Combining maven and groovy (both scripts and classes) was just too much to bear. My productive-work to environment-tweaking ratio was going downhill fast.

I spent a few days getting my primary projects setup in Intellij and generally learning the ropes there. Here are my notes for any other Eclipse refuges who decide to make the plunge. They are meant to complement, not replace, the online documentation that comes with Intellij. They don't explain how to do anything that is easy to find in the documentation. The are just semi-random tidbits that I jotted down whenever I thought, "This seems odd because I am used to how Eclipse does it." Much of it centers around configuring maven projects because that is what I have been doing a lot of the past few weeks (and also where existing documentation is a bit lacking). Most points are independent of each other, so you can just cherry pick out what sections are of interest to you.

General Conversion Approach

Intellij has support for import (and even stay synchronized with) Eclipse projects, but I wanted to make a clean break. Since my group just converted all of our primary projects to maven, I used the poms as the starting point for my Intellij projects. This included:
  • 8 utils projects under a common root pom
  • Our main application, an ETL framework, with 6 main components and nearly a dozen extension ones
  • A set of half-a-dozen small, independent projects that the ETL product pulls in
  • A domain-specific set of projects that sit on top of the root ETL framework including an installer, more extensions, and several custom "feeds" that run in the ETL framework. All told, another 10 maven poms.
I was able to get Intellij projects setup for most of these and learn the basics of working in Intellij in about 2 days. I then spent another 2 days customizing my environment, including setting up a single, uber-project that simulates a mini-Eclipse workspace. I didn't bring over everything from Eclipse (I have about 20 other projects that I touch now and then), but I wanted a unified view of the primary projects that I work with on a daily basis. (Note - I later gave up on this combined project. It was just too much of a pain trying to keep all the modules in synch with changes to the maven poms. See the maven notes below for more info.)

Last, I also decided that I didn't want to recreate Eclipse in Intellij. I figured that Intellij's overall feel (including keyboard shortcuts) was put together for a reason. There was no need to force it to feel like an Eclipse wannabe. I still can't figure out the reasoning behind many of the assigned keyboard shortcuts (Ctrl+Alt+L for reformat code? Ctrl+M for the type hierarchy?), but I am slowly committing them to memory.

Helpful Documentation

  • Intellij Eclipse Migration FAQ - Very useful for getting head around primary differences between the apps, as well as little things like how to turn off allowing the placement of the insertion caret after end of a line.
  • Common key shortcuts - Quick list of most commonly used key shortcuts in both Eclipse and Intellij.
  • Full key shortcut reference card - Print it out and memorize it. There are shortcuts for nearly everything.
  • Stackoverflow article - Short thread on things that Intellij can do that Eclipse can't.

Before You Begin

Before creating any projects, open the Settings dialog and make some tweaks:
  • Setup your global "Ignore Files" list in the Settings/Version Control/Ignored Files. Unlike Eclipse where the Ignored Files list is global, once a project is created, it won't pickup any changes to the global list.
  • If you use maven, set the path to your maven home. Intellij is smart enough to pickup your maven settings path if it's the default (i.e. ~username/.m2), but it can't know where your external maven install is located.

Workspace Setup

Intellij doesn't allow quite as much flexibility for where you put various views as Eclipse does. In Eclipse, you can position container panes wherever you want, including stacked next to other container panes. Intellij has more of a set layout for it's view containers, though you can still move individual panes between different containers. One thing that tripped me up was how to move a pane from one container to another. In Eclipse, you grab the tab for a pane and move it. In Intellij, you move the "side bar control button" (that's the term used in the manual) for a pane to some new position on the side bar that surrounds the main Intellij window. Buttons can be clustered at both the top or the bottom of either side, and the left and the right of the bottom button bar. Thus, you can have two different panes visible on either side (and the bottom) at once.



If you want to set up an "uber-project" similar to an Eclipse workspace, see this post in the intellij forum.

Navigation

The main Project pane is similar to the Eclipse Package Explorer. There is no equivalent of the Eclipse Navigator that lets you see files which are not part of project. For example, you cannot see the target/build directory which contains the output from a build. There is a FileBrowser plugin which gets some of that functionality. You also cannot drag and drop files to or from Intellij to your native file manager (e.g. Explorer on Windows). This functionality has been added to Maia (Intellij 9).

I have a nice plugin for Eclipse that will show me the Explorer context menu when selecting a file or directory in the Navigator or Package Explorer. This lets me easily open a command window in the current directory, open Windows Explorer, get file system properties for a file, etc. The Native Neighborhood plugin does most of this. Unfortunately, when I installed the latest version (1.2) via the Settings->Plugins dialog, a file that is required to open a cmd window didn't get installed. I had to download an old archive of the plugin from it's web site, extract the cmd.bat file, and place that in the C:\Documents and Settings\username\.IntelliJIdea80\config\plugins\NativeNeighbourhood\classes\org\intellij\plugins\nativeNeighbourhood\icons\windows directory. No restart was necessary. I just selected a directory in my Project view, hit Alt-Shift-S and it worked. The author knows of the issue and will fix the distribution in the next version.

One thing I miss is an independent Problems view. There is no pane that shows me a single list of all problems/warnings/todos across all files. This is an often requested feature on the community forums. Here is a good post explaining how to get most of the functionality.

Primary Editor

One of the first things I noticed is that there was no button to show the current file you were working on in the editor within the Project view. There is a keyboard shortcut for it though - Alt-F1, then 1.

If you mouse over a field or method, it doesn't automatically popup information like Eclipse does. Hit Ctrl-Q for quick documentation.

In eclipse, if you type the name of a method in a parent class and then do code completion, it will fill in a template to override that method. In Intellij, you don't type the name of the method first. Hit Ctrl-O for Override, and you will get a list of methods that you can override right there.

If you want to be able to use Ctrl-Tab (or some similar key combo) to move between panes in the editor, get the TabSwitch plugin. This functionality has been built into Maia.

Maven

Even though maven support is one of the main reasons I switched from Eclipse, I can't say that I'm any happier with Intellij's current maven support, especially with regards to keeping projects and modules in synch when a pom changes. I wouldn't say it is signifcantly worse than in Eclipse, but it's not really any better either. The IDEA folks have significantly enhanced maven integration in Maia (Intellij 9). I haven't built up the courage to try out those yet, but given the number of problems I have had with keeping modules in synch in Intellij 8, I may take the plunge.

You can create an Intellij project for an existing maven project by simply choosing Open Project and selecting the pom file. However, this uses some strange default settings. For one thing, it did not use the default JDK that I have set in the Template Project Settings. I have both a JDK 5 and a JDK 6 set, with JDK 5 being the default. When I created an Intellij project using this method, it set the JDK for the project to JDK 6. I filed a bug for this with the Intellij folks.

Instead of opening the pom directly, use New Project -> Import Project from External Module. This gives many more options, including whether to create a file-based or directory-based project, and it sets the proper JDK for the project. However, it does not properly set the VCS "Ignored Files" setting from the Project Template. I filed a bug for that too.

If you change a pom, you will be prompted to re-import it. You might think this means re-import for that module only, or for that module and all modules that have it as a (maven) dependency. Nope. It actually will kick off a re-import for all modules in your project, including whatever maven target you have selected to run when an import happens (process-resources by default). So do this with care unless you like frequent coffee breaks. Even after the re-import completes, it may not do what you expected, especially for large projects. It may not pick up any of the changes at all. For example, I had it re-imported a POM to which I had added a version range. This caused the .iml file (module settings file) to lose all of it's dependencies. So I took out the version range and re-imported. No change - no dependencies were added back. I have taken to changing my poms and Intellij module dependencies separately for now. There is a thread on the intellij forum with complaints about this and other issues with using maven in Intellij for large projects. Hopefully, the support in Maia is better.

If you change a single java file within a maven module and you just want to compile it rather than running a full maven compile, you can hit Ctrl-Shift-F9 to just invoke a regular Intellij compile on only that file. It still takes a bit longer than the normal Eclipse behavior of auto-compiling, but it's better than waiting for maven to figure out that it only has to compile 1 file. Note that it doesn't always work. Sometimes it may compile that class, but other classes will have been cleaned out and can't be found. I haven't found that pattern for when this happens yet.

There is a Maven Projects tool window where you can run various maven phases or goals on your module or project. If you have a project with multiple poms though (i.e. a composite maven project), what poms are shown in the window seems to vary. Sometimes I open the project and the 2-3 main poms are listed in the Maven Projects window. Other times it seems to be only the pom corresponding to the module I last ran a debugging session with or some other random choice. I have also found that if you add a new module from an existing pom, Intellij may remove all the other poms listed in the Maven Projects window and just show the one for the new module you added. But then other times it doesn't alter the window at all.

There is an article on jetbrains dzone that explains how to automatically deploy source and javadoc jars for your dependent projects into your maven repository so that they will be picked up by Intellij. This is very useful for getting context help and for being able to step through such libraries while debugging. Make sure to read through the comments because they explain an easier way than what is first discussed in the article.

When viewing a pom.xml file in the editor, you can click on an artifactId for a dependency and hit F4 to jump to the pom for that artifact (equivalent of F3 in eclipse for java classes). If the target artifact is in the current project (i.e. it's another module), you actually go into the pom.xml for it. If the artifact is a 3rd party dependency or something like that, you get a read-only view of the .pom file.

Usually when you open a pom file, it gives the editor tab the name of the project. This is very handy, especially when you have many pom.xml files open at once. But sometimes it leaves the tab title as just "pom.xml". Like with many other maven-Intellij interactions, I can't figure out the pattern.

Unlike with the m2eclipse plugin for Eclipse, there is no way to browse a maven repository. There is a plugin called MavenRepoSearch which does it part way, but you can't configure the repositories it scans (it only does the main one) which significantly reduces it's usefulness.

The MavenProjectHelper plugin (an optional install) lets you create projects for different types of maven artifacts. I haven't experimented with that one yet since I have mostly been modifying the large set of poms we just created during our project conversion.

Another plugin called Maven Dependency Sync lets you quickly pull jars using a pom without controlling the rest of your build with maven. It hasn't been updated in a while, so it did throw a strange exception after pulling dependencies once, but it still worked.

Subversion

The shipping version of Intellij (8.1.2) integrates subversion 1.4. You must use an 8.1.3 EAP for subversion 1.6 support.

In the editor tabs, file names turn blue when a file under version control has been modified. Red file names mean the file is not in version control yet.

You can see the list of changes to your local working files in the Changes->Local pane. Unlike Eclipse, double clicking an entry in this pane will open the file in the editor rather than opening a view to show the differences between your local copy and the repository. To show differences, hit Ctrl-D . Be Warned! That hotkey only works when the focus is on the Changes pane. If you accidentally double click an entry and see the editor window open and then you hit Ctrl-D to see the differences like you really intended, you will end up duplicating lines in the editor because that is what
Ctrl-D does there. Not that I have ever done that...

Subversion Filter Settings

  • You don't need any wildcards to filter out a directory and everything under it, even if the directory is not at the root level of the project. Just select the "Ignore all files matching" option and put the name of the directory there.
  • If you add a "Match" term with a directory name (e.g. add "target" to filter out the target directory created by maven builds), the Unversioned Files list in the Changes->Local tab may not update until you restart Intellij, even if you click the Refresh button.
  • Settings Dialog

    Intellij limits how many tabs you can have open by default. You can change this. Just browse the Settings->Editor and Settings->Editor->Editor Tabs settings.

    Bug Warning
    - If you have more than one project frame open, if you change your global settings from one project frame and then close it, and then close the other project frame to quit Intellij, all of your custom settings will be wiped. So be warned - only change IDE Settings when you have one project frame open.

    Groovy

    I spent a long time trying to figure out how to run a groovy script from within Intellij using the "embeddable" form of groovy rather than the standard set of groovy libs. I posted to the Intellij Community forum with both my conclusion of how to do it and some questions for how to do it better.

    Run/Debug

    • Ctrl-Shift-F10 - run the current file using a temporary run config (replacing whatever was there when you last did Shift-F10). If you want to run something repeatedly, save the config by mousing over the copy icon so that it expands the hidden toolbar, then click the save button.
    • When running a file within a module, the default working directory will either be the root directory of the project containing the module (for java files like JUnit tests) or the directory that contains the file itself (for groovy scripts). This is different from Eclipse where the working directory was always the project/module root. You can manually modify the working directory for the run configuration to set it to the module root. It would be nice to have a preference that lets you set the default working directory to be the content root of a module.
    • Here's a nice little feature - when I loaded and executed a script with an embedded groovy call from within another class, the debugger was able to detect a reference to that script in an exception stack trace that was thrown and highlight it so I could click and jump to the script file.
    • You can attach to an external application server like JBoss just like you can in Eclipse. If you set a breakpoint in a source file, the debugger will stop when that line of code is hit within JBoss. However, step-wise debugging doesn't work as you may first expect. Even though Intellij knew to display the source file where the breakpoint was, you can't step into any other classes or methods and see the corresponding source file automatically. You must explicitly set which sources are to be associated with the debugging session. This was a bit annoying. I am used to Eclipse automatically finding the associated source files.

    Misc Nitpicks

    Here are some random things
    with Intellij that are annoying. None of them will make me stop using the product, but they certainly don't contribute to the "Develop with pleasure!" vibe.
    • When I first load the application, the configuration steps should prompt me to define at least one JDK automatically.
    • It takes a looooong time to load projects. It would be nice to be able to view files at least even when a project is loading. I just read that this is a big new feature in Maia.
    • There are times when Intellij just hangs for a few seconds. Like when you change a project setting and click okay. Sometimes it just sits there with the dialog up for a while, but no "wait" cursor. For that matter, it can take a few seconds just to bring up the Settings or Project Structure dialogs when you have a large project. To be fair, Eclipse had started doing this to me as well at even more random times. But that was one "feature" which I was hoping to leave behind.
    • If you want to reformat a multi-line comment (like javadoc), you have to select the whole comment. If you just select a part of it, no reformatting will take place.
    • In Eclipse, I can highlight any word in any file type and then hit the key combo for "Open Resource" and it will auto-populate the selection dialog with the word I have highlighted. This is very handy for cases like dependency injection where you have the names of classes in an XML file and you want to quickly jump to a particular class.
    • File synchronization is a bit odd. I wrote a simple groovy script that writes to a file in a directory in the project. Then I ran the script from Intellij. I can see the file created, but when I open it in Intellij, the editor shows it as being empty. I have switch out of Intellij and back in to see the updated contents. Same thing happens every time I update the file.

    Misc Niceties

    On the other hand, here are some small things that I do like about it:
    • Module groups. That's a big thing the Eclipse is missing - a tree-like structure for grouping projects.
    • Auto-include of jars in a directory rather than having to specify each one
    • It shuts down very quickly. It could sometimes take Eclipse 2-3 minutes to shutdown. Intellij seems to do it instantly. This is probably related to the fact that it is not managing an entire workspace with 60+ projects, but it's still nice.
    • It is easy to see what's in a hashmap in the debugger. It's impossible to get a good view of a large hashmap in Eclipse.
    • It ran out of memory once, but was nice enough about it to show a dialog that let me change the Xmx setting so it wouldn't happen again.

    1 comment:

    1. I posted a link to this article on the Intellij Community Forum and folks have added comments from their own experience there:
      http://www.jetbrains.net/devnet/message/5241882

      ReplyDelete

    Note: Only a member of this blog may post a comment.