Thursday, December 20, 2012

Webapp development stack evolution (a.k.a Intellij + git + maven tomcat plugin = AWESOME!)

You know that +JetBrains' Intellij has a free and open source community edition, right? I have been using it on and off and it really rocks. First I'd like to start with my previous set of tools and workflow, so that you understand that it was not dead simple for me to switch IDE.

To start off, let me tell you that I am currently working on a webapp that is supposed to be deployed on tomcat.

Original stack

Back in the dark ages (about 2 years ago) I was using:
- SVN for version control
- eclipse
- maven from commandline and used mvn eclispe:eclispe to generate the eclipse project files
- mvn package to make war files

This had some major issues:
- any change in pom's required mvn eclipse:eclipse and reimport in eclipse
- any change in code required packaging and redeploying to tomcat. 
- I had frequently looked through the local history in search of not broken version of the codes

This was clearly a sub-awesome way to work.

Improvement #1 - m2e

Well, it turned out that there was a better way to integrate maven and eclipse, it's called m2e (formerly m2eclipse) and is bundled in eclipse nowadays. This made the eclipse:eclipse and reimport reduntant and was a major boost in productivity.

Improvement #3 - git!

This one is probably the most important thing. Git integrates with SVN nicely, and for me works like an unlimited undo tool. It also allows me to try out different ideas in the local branches and then easily merge the changes back to the upstream branch and push the changes to SVN. THis really rocks! Never again was I going through the local history in eclipse only to find out that I forgot some changes in one of the files. There was some drawback to that: switching between branches in git is painless, but switching them in eclipse is painful. Why? Because eclipse (despite the really awesome egit plugin) is not well suited for frequent switching of branches. Maybe it's because of the way m2e is built, but switching of a branch triggered a full rebuild of the entire workspace. Many times in the last year or 1,5 I have been waiting for 5-10 minutes for eclipse to "build workspace" only to find out that it re-triggered again. This sucked, but I somehow sticked with this way for over a year.

Improvement #4 - WTP and m2e integration

Now, I still build the webapp using mvn:package and deployed it manually to tomcat. This made the loop too long, so I was looking for a way to do that faster. The best solution I have found was WTP and m2e WTP integration, which basically installs a tomcat in your eclipse workspace, and starts tomcat with classpath set to the target directory of your maven projects. This means that your code changes can be visible immediately on your tomcat (if you have started it in debug mode, where the classes are reloaded on change) or you can just restart tomcat and see the results. Depending on the size of your project this can be a very fast process, definitely faster and less error prone from building war file and deploying it manually. 

Improvement #5 (and also regression #1) - Intellij

At times, even when editing things in eclipse, it would get sluggish. Also, sometimes the code completion capabilities would be... hmm. Sub-awesome is again the righ word - they were fine, don't get me wrong, but come'on to name a variable list? This is not what I want to name it. Knowing that the classes can get reloaded in debug mode made me think that maybe another IDE could also do the code hot-swap on tomcat. Why not try it? I have started using intellij about 3 months ago and it really rocks:
- the code completion is much better, it's instant, it's spot-on, it's everything that eclipse is and more. I don't know whether it is because intellij has all the classes and interfaces indexed or what but sometimes I feel like intellij is reading my mind.
the code refactoring is again everything that eclipse is (which is to say it is great) plus a little more. 
- switching branches and changing project structure was painless. Intellij immediately recognizes another branch, rebuild takes about 10s. Same goes for changing project structure (adding/removing modules etc). This is WAY faster than m2e.

There were some issues with intellij as well:
- there is no tomcat (or any container) integration in the community edition. This is really a pain, but I understand that JetBrains has to make money, too. It was actually the reason to give the paid trial version a try, but somehow it was not able to import my projects (!). So I was unable to find out how well (or how poor) the tomcat integration really is. With intellij 12 out of the door I will give it another try, as it might be a reason to actually pay for the full version instead of hacking the community edition

Improvement #6 (almost fixed regression #1) - maven tomcat plugin

Well, somehow through the prcoess of googling around and looking at stackoverflow, I have found a really decent way to improve the turnaorund time. The fastest way to deploy your webapp on tomcat is this:

mvn war:inplace tomcat:inplace

that builds a webapp in your src/main/webapp, then deploys that to tomcat. It does not build a war file! There are some caveats with this:
- you need to build your dependencies first. If you have some sort of grouping project, you are probabaly better off running this from your parent pom's directory
- you should not commit that to your repo. Probably the best way is to add src/main/webapp/WEB-INF/classes and src/main/webapp/WEB-INF/lib to .gitignore or svn:ignore properties.

Afterwards you can connect to the runnign tomcat with a debugger and do the hotswapping. When hotstwapping fails, you run the above mvn incantation (you can do that from within intellij as well), and you have your changes deployed within 1-2 seconds. 

No comments:

Post a Comment