tag:blogger.com,1999:blog-112001642024-03-07T21:41:03.967-05:00Nirav's ContemplationsThoughts on Programming, Software and Open Source.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.comBlogger19125tag:blogger.com,1999:blog-11200164.post-56090668503916563262010-03-07T12:58:00.004-05:002010-03-07T13:04:28.980-05:00Eclipse Refactoring for legacy code<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;">It has been quite sometime since I wrote anything on this blog, twitter probably spoiled me. If you are <a href="http://twitter.com/niravn1">following me on twitter</a>, you probably noticed announcement of a small eclipse plugin for automated refactoring for Legacy Code. </span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;">Before few months, I wrote an LTK refactoring mainly in Scala (yes, eclipse plugin in Scala language) to forward static method calls in a Java method to an instance method in same class. I am not really an expert at Scala (or functional programming for that matter) so the code is more of javaish Scala but I am improving and thats the best thing about Scala. This is also an attempt to prove how easy it is to write eclipse plugins in Scala and how seamlessly it integrates with Java source; Scala is not only a better language, it is much more suitable to deal with Eclipse APIs (you can define views etc. on extremely verbose interfaces like JDT AST).</span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;">Enough about Scala; the real purpose of the refactorings provided in this plugin would be to ease development with Legacy Java code, most of the code generators (think JavaCC) generate ugly Java code which is not only non unit testable but pain to comprehend and is often not usable with concurrent routines. Using this automated refactoring should make such code better. You can read more about the motivation behind the <a href="http://code.google.com/p/java-ext-refactorings/wiki/StaticCallForwardRefactoring">plugin in wiki</a>.</span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></span></span><br />
For the performance heads who are worried about method chains introduced by this refactoring are encouraged to run their own "sane" micro-benchmarks to be sure JVM is really in-lining the method calls created by this refactoring.<br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;"><br />
</span></span></span></span><br />
<span class="Apple-style-span" style="font-family: Arial; font-size: small;"><span class="Apple-style-span" style="font-size: 13px;"><span class="Apple-style-span" style="font-family: 'Times New Roman';"><span class="Apple-style-span" style="font-size: medium;">The plugin is currently in beta and I am open for any new refactoring proposals. If you have any feedback, you are welcome to comment on this blog post or <a href="http://code.google.com/p/java-ext-refactorings/issues/list">create a bug</a>. The <a href="http://java-ext-refactorings.googlecode.com/svn/branches/0.1-beta/name.nirav.refcatoringman.update">update site is here</a>.</span></span></span></span>Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com5tag:blogger.com,1999:blog-11200164.post-91372079962899525482009-03-22T22:58:00.005-04:002009-03-22T23:29:56.937-04:00EVars UpdateBased on the awesome feedback, I have been <a href="http://code.google.com/p/evars/updates/list">doing some offline development</a> on <a href="http://code.google.com/p/evars/">EVars</a> plug-in lately. I have added some basic documentation on <a href="http://code.google.com/p/evars/w/list">wiki</a>. Installation is now easy, let P2 do the work to <a href="http://evars.googlecode.com/svn/evars-update">install/update</a> the plug-in (it's a struggle to host update-site with google code).<br /><br />One of the most exciting feature (Which I can't stop talking about) is value based filtering. Now you can have all the powers of predicate expression, how about searching a map like map//key['@user.*']/.. to select entries matching regular expression user.* ? This update also includes support for relational operators so you can search exactly you want like this //value[count > n] .<br /><br />I have uploaded <a href="http://code.google.com/p/evars/wiki/OPathGrammar">OPath grammar</a> for the language enthusiasts (left factored, left recursion free). One feedback was 'experiencing some unresponsive behavior for huge graphs' I have addressed that to some extent by integrating progress monitoring and asynchronous interpretation job.<br /><br />Thanks for the feedback! Also, for those at <a href="http://www.eclipsecon.org/2009/">EclipseCon</a> have fun with your sessions!Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com0tag:blogger.com,1999:blog-11200164.post-43198818787205353292009-03-10T19:37:00.012-04:002009-03-11T20:55:20.117-04:00Improve your debugging speed with EVars Eclipse pluginUpdate: Added alternate link to screen-cast. Workaround to start plug-in<br /><br />I have been debugging a lot lately which included open source libraries, closed source web-service engine and parts of closed source application server (WebLogic). During this painful debug-fest I felt a strong need for several features missing in Eclipse (NetBeans as well, for that matter) . Debugging closed applications is a pain beyond imagination, even with IDE integrated decompilers, it takes incredible amount of patience and time to debug.<br /><br />To improve productivity (or prevent burnout), I jotted down a plugin to export/import live variables, filter variables view with a xpath like expressions etc. The plugin, called <a href="http://code.google.com/p/evars">'evars'</a>, features a small expression interpreter (similar to xpath) which can do a wonderful job of filtering variables on current stackframe. It also allows you to export variables to a file and reload them at a later point.<br /><br />For the first time, I have attempted to create a screencast to explain its usefulness. <a href="http://nirav.thaker.googlepages.com/evars.htm" target="_blank">You may watch it over here</a> [10mb non-streaming, 1275x860], <a href="http://evars.googlecode.com/files/evars.swf" target="_blank">alternate link</a> (open with your browser).<br /><br />I have also created a beta release to see if it finds any interest which you can <a href="http://evars.googlecode.com/files/name.nirav.evariablesview_1.0.0.jar">download it from here</a> [JAR ~800kb, Jdk6] (<a href="http://evars.googlecode.com/files/name.nirav.evariablesview_1.0.0-1.5.jar">Click here for Java 5 version</a>) and drop it in dropins folder [Eclipse 3.4+]<br /><br />If you find it interesting, please leave feedback here.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com14tag:blogger.com,1999:blog-11200164.post-29219943322529230702009-01-21T19:22:00.012-05:002009-01-21T20:33:05.832-05:00Mutual recursion fun with Eclipse Debug model<style type="text/css"> <!-- @page { margin: 0.79in } P { margin-bottom: 0.08in } --> </style> <p style="margin-bottom: 0in;">I rarely come across real-world data structures which are inherently mutually recursive (a.k.a. Daisy chain recursion in CS literature). Recently, while writing a plug-in related to eclipse.debug, I came across this interesting data structure.<br /><br /></p> <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.eclipse.org/articles/Article-Debugger/images/debug_model.gif"><img style="cursor: pointer; width: 408px; height: 608px;" src="http://www.eclipse.org/articles/Article-Debugger/images/debug_model.gif" alt="" border="0" /></a> <a href="http://www.eclipse.org/articles/Article-Debugger/how-to.html">Source Eclipse.org</a><br /><br /><br /><p style="margin-bottom: 0in;">Observe the IVariable ←→ IValue relationship (although most relationships in this object-model is mutually recursive), given an implementation of this model (say JDI) how do you clone an object-tree representing variables on a stack-frame?</p> <p style="margin-bottom: 0in;">The answer is simple: assuming implementation classes Variable and Value just write a simple function to clone variables one by one:</p><br /><pre style="background: none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">class</span> Variable {<br />…<br /><span style="color: rgb(127, 0, 85); font-weight: bold;">private</span> Value value;<br />…<br /><span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">static</span> Variable create(IVariable var) {<br /> Variable v = <span style="color: rgb(127, 0, 85); font-weight: bold;">new</span> Variable() ;<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">try</span> {<br /> v.setName(var.getName());<br /> v.setType(var.getReferenceTypeName());<br /> v.setValue(Value.create(var.getValue()));<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">return</span> v;<br /> } <span style="color: rgb(127, 0, 85); font-weight: bold;">catch</span> (DebugException e) {<br /> ..<br /> }<br />}<br />}<br /></pre>Similarly for Value class:<br /><br /><pre style="background: none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">class</span> Value {<br />…<br /><span style="color: rgb(127, 0, 85); font-weight: bold;">private</span> Variable[] variables;<br />…<br /><span style="color: rgb(127, 0, 85); font-weight: bold;">public</span> <span style="color: rgb(127, 0, 85); font-weight: bold;">static</span> Value create(IValue var) {<br /> Value v = <span style="color: rgb(127, 0, 85); font-weight: bold;">new</span> Value() ;<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">try</span> {<br /> v.setType(var.getReferenceTypeName());<br /> v.setValue(...);<br /> IVariable[] variables = value.getVariables();<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">if</span> (variables != <span style="color: rgb(127, 0, 85); font-weight: bold;">null</span>) {<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">for</span> (IVariable variable : variables)<br /> v.add(Variable.create(variable));<br /> }<br /> <span style="color: rgb(127, 0, 85); font-weight: bold;">return</span> v;<br /> } <span style="color: rgb(127, 0, 85); font-weight: bold;">catch</span> (DebugException e) {<br /> ..<br /> }<br />}<br />}<br /></pre><p style="margin-bottom: 0in;">Statement 'Variable.create(yourJDIVariable);' clones entire JDI object. This is one of those intuitive recursion examples which you die to find out IRL. Interesting, isn't it?</p><p style="margin-bottom: 0in;">This is how your regular stack-frame looks (Variables view):</p><p style="margin-bottom: 0in;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZGDwEB0DR5KQELjVDYJ2-793vSfO5tHeCQJGqL2-kV9uP22nx40yvVRfcgaLKSB93zcLLflAooRT_pTRFrE9gUyLV51EplABRloHMKG1Iokdk6IjXvAqXLVaYMoZMkB4f-QJ3gQ/s1600-h/first.jpg"><img style="cursor: pointer; width: 320px; height: 240px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZGDwEB0DR5KQELjVDYJ2-793vSfO5tHeCQJGqL2-kV9uP22nx40yvVRfcgaLKSB93zcLLflAooRT_pTRFrE9gUyLV51EplABRloHMKG1Iokdk6IjXvAqXLVaYMoZMkB4f-QJ3gQ/s320/first.jpg" alt="" id="BLOGGER_PHOTO_ID_5293918829819797490" border="0" /></a></p><p style="margin-bottom: 0in;"><br /></p>And this is how it looks when you represent it using an example debug model :<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9k4JhVE_9zLfGGg1Si29QCRvUYPSGsqvAMe3dTc0pDmZtgEdRhDAZFpALUVr9dgQqadh9nWCClIm7KuW_RZptnWLJMi8nn2nwr_jVQCQpnd_cF7wPSHvJosJQbyc-2_tspKhkbg/s1600-h/second.jpg"><img style="cursor: pointer; width: 320px; height: 248px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9k4JhVE_9zLfGGg1Si29QCRvUYPSGsqvAMe3dTc0pDmZtgEdRhDAZFpALUVr9dgQqadh9nWCClIm7KuW_RZptnWLJMi8nn2nwr_jVQCQpnd_cF7wPSHvJosJQbyc-2_tspKhkbg/s320/second.jpg" alt="" id="BLOGGER_PHOTO_ID_5293919113302478194" border="0" /></a>Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com1tag:blogger.com,1999:blog-11200164.post-45076979875758227982008-12-05T23:37:00.004-05:002008-12-13T00:08:07.821-05:00Introducing PyConsole!I have been pretty inactive this year, unlike what I <a href="http://blog.nirav.name/2007/11/what-am-i-upto-this-year.html">planned</a> (yawn, haven't heard from <a href="http://www.eclipse.org/dltk/">DLTK </a>since June either) . I started learning Python earlier this year and felt the need of an embedded python shell inside Eclipse. This was something <a href="http://pydev.sourceforge.net/">PyDev</a> is missing [Edit: <a style="font-style: italic;" href="https://www.blogger.com/comment.g?blogID=11200164&postID=4507697987575822798">Simone</a><span style="font-style: italic;"> pointed out that PyDev already has <a href="http://pydev.sourceforge.net/console.html">this neat feature</a>, I was late to discover it</span>] as compared to other <a href="http://blog.nirav.name/2008/02/state-of-eclipse-based-python.html">python tools</a> in Linux such as <a href="http://www.die-offenbachs.de/eric/index.html">Eric</a>. So I decided to write one.<br /><br /><a href="http://pyconsole.sf.net/">PyConsole</a> is direct result of my irregular and intermittent Eclipse development (lately), it's very simple plug-in with a basic exploit of <a href="http://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in%3F">Eclipse Console View</a> and manages two way synchronized I/O from the python interpreter process controlled by a background Eclipse job. It provides few basic features anyone might expect from a shell such as syntax highlighting, command history etc.<br /><br />Here's the <a href="http://pyconsole.svn.sourceforge.net/viewvc/pyconsole/trunk/">code repository</a> if anyone would like to check it out. If you have suggestions or feedback please write to me or <a href="http://sourceforge.net/tracker/?group_id=216852&atid=1039896">create a bug</a>.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com4tag:blogger.com,1999:blog-11200164.post-85304737753466898072008-08-16T14:35:00.008-04:002009-01-13T20:16:58.371-05:00Productive keyboard shortcuts for Eclipse EditorsI've seen very few developers using true power of Eclipse editors, so I thought of listing few very handy shortcuts that can significantly improve your source editing and navigation speed with Eclipse.<br /><br />1. Ctrl + J / Ctrl + Shift + J : Inline search, meaning you can type on the fly to search text in current editor. You can use Up/Down arrow keys to navigate between matching text fragment in forward/reverse direction. This is one of the most powerful features you will find in advanced editors like Vim or Emacs.<br /><br />2. Ctrl + K/ Ctrl + Shift + K : Search text in forward or reverse direction.<br /><br />3. Ctrl + L : Go to line.<br /><br />4. Ctrl + Alt + Up/Down : Duplicate current line above/below. Very useful in repeatative assignment statements (Java code, eh?).<br /><br />5. Alt + Up/Down : Move current line up or down. Also, very handy to select current line.<br /><br />6. Ctrl + . OR , : This is contextual and may be specific to Java editors: if you have error or warnings in current file in editor it will navigate to them.<br /><br />All of these except for no. 6 are generic text editor features which are inherited by all eclipse text editors. You will realize that you will work much faster than average user if you start using these key bindings.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com5tag:blogger.com,1999:blog-11200164.post-82021521817588013732008-02-12T18:39:00.000-05:002008-02-12T19:44:30.116-05:00State of Eclipse based Python Development ToolsFor starters, Python Interpreter console isn't a bad place for trying hands on the language. But if you plan on building larger programs with it you will need a good development environment, There are <a href="http://wiki.python.org/moin/IntegratedDevelopmentEnvironments">plenty of </a>integrated development environments for Python today. Most of them are freely available open source projects, some have specialized support for GUI building while some are general purpose.<br /><br />Since I'm Eclipse platform zealot, the first one I used was <a href="http://pydev.sourceforge.net/">PyDev</a>, PyDev is excellent python tooling built on Eclipse platform. It builds on excellent Eclipse UI and non commercial version offers basic refactoring, integrated debugging, Jython integration, Unit testing and several regular features which most Eclipse based IDEs inherit.<br /><br />When it comes to dynamic languages tooling, <a href="http://www.eclipse.org/dltk/">DLTK</a> is one potential place to look for in Eclipse Ecosystem. From time to time I'm lurking around DLTK newsgroups as well as keeping an eye on things moving in codebase for Python IDE. As of today, Python support in DLTK isn't too bad but it's still not as good as other IDEs out there, although it's coming up slowly. Eclipse DLTK is one fantastic tooling idea, it is so cool to build IDE for dynamic languages that you might want to try your hands building one, have a look <a href="http://wiki.eclipse.org/DLTK_IDE_Guide">at the guide here</a>.<br /><br />Out of Eclipse ecosystem, <a href="http://www.die-offenbachs.de/eric/index.html">Eric</a> is an IDE which I got chance to try hands on so far. Although It doesn't look as refreshing as PyDev or Eclipse in general, but it's pretty decent IDE nevertheless. It has lot of features, so many of them that you will confuse yourself on where to start, Eric UI has to be the last thing to impress anyone. It primarily features syntax highlighting editor, refactoring tool, debugger, package diagram viewer, regex builder, integrated version control and Python shell among others. While I'm not sure if Netbeans has any rock solid plan to support Python as Eclipse DLTK but I came across <a href="http://jpydbg.sourceforge.net/">JPyDbg</a> which is cross-IDE (and one of it's kind) for Python development. JPyDbg is kind of inspiring idea and I'm wondering if cross-ide-platform plugins would be a good idea? but that deserves separate post.<br /><br />I haven't mentioned JyDT etc. because they seem to be dying or not actively compatible with later Eclipse versions. I would keep posting on python tooling as I go along working more on it.<br /><br />PS: DLTK, I'm watching you.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com2tag:blogger.com,1999:blog-11200164.post-78507790891142575952007-10-22T09:44:00.000-04:002007-10-22T10:33:29.881-04:00On IClass (anti-)patternI'd been re-reading <a href="http://blog.sidu.in/2007/09/programming-to-interfaces-strikes-again.html">this post</a> by Sidu and the comments on it. I had to do exactly similar to IClass anti-pattern for one of the development effort. And I think having IWhatever completely makes sense for the current state of affairs in my development environment.<br /><br />While it's unfortunate, most of the time, to have an Interface for just about every class in the code-base, It does have certain uses in some situations (apart from the (IoC) frameworks which mandate you to have them) like:<br /><ul style="font-weight: bold;"><li>Support parallel development.</li></ul>I will define parallel development as a situation where there are many components involved in developing a software and your component (or module or whatever..) and it's arbitrary version has to support other components (and their integration tests depending on your environment). For example, for something as important as (so called) service layer in an Enterprise application you need the Interface with single implementation at one time, it might just be a 'placeholder implementation' for a dependent component while the new version being developed parallely. It just makes sure that there is something to hold the place which can be tested easily. This is one more learning from distributed development, you're not alone developing it man!<br /><ul><li><span style="font-weight: bold;">When using Generative development methods<br /></span></li></ul>If you use code generators heavily, say, most of your code-base is generated out of models (UML, BPMN, BlahL ...) then depending on the generation pattern you'll find interface for just about every implementation (or other way around for EMF generator - one implementation for each interface). This is necessary as you might want to customize forward engineering by overriding parts of generated artifacts.<br /><br />Most of the Eclipse code does have this pattern, for every class there's IClass. For Eclipse, In my opinion, it is justifiable (to some extent) to have them considering it is a development platform rather than just an application. However, I would be more than interested to know conceivable reasons to have those IInterfaces which I might be missing.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com3tag:blogger.com,1999:blog-11200164.post-30376710693402873662007-10-05T21:21:00.000-04:002007-10-05T23:37:10.131-04:00Layman's review on Modeling etc. features in Netbeans 6.0I know, I'm not going to sound very good for this post on the planet and expecting very less dialog in form of comments on it, but anyway...<br /><br />The Java development <span class="blsp-spelling-error" id="SPELLING_ERROR_0">blogosphere</span> is experiencing a new wave of marketing campaign, yes everyone is talking about <a href="http://netbeans.org/"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">Netbeans</span></a>, but hold on, it's not just viral-marketing, I found reviews where some says it's ruby support <a href="http://headius.blogspot.com/2007/08/netbeans-ruby-support-is-bomb.html">is the bomb</a>, some are <a href="http://sureshkrishna.wordpress.com/2007/10/05/eclipse-33-and-netbeans-60-compared/">finding <span class="blsp-spelling-error" id="SPELLING_ERROR_2">profiler</span> better</a>, <span class="blsp-spelling-error" id="SPELLING_ERROR_3">someone is</span> just finding it coming-up with <a href="http://blogs.zdnet.com/Burnette/?p=387">better attitude</a>:). Well, I've to tell it, I'd tried <span class="blsp-spelling-error" id="SPELLING_ERROR_4">Netbeans</span> in various forms in last few weeks, I can tell you it can do pretty much what all <span class="blsp-spelling-error" id="SPELLING_ERROR_5">IDEs</span> do these days. <span class="blsp-spelling-error" id="SPELLING_ERROR_6">Netbeans</span> might be looking less refreshing with all that swing (elegant inside!) rendering, but giving Eclipse Key binding, for example, really shows it's eager to compete your favorite <span class="blsp-spelling-error" id="SPELLING_ERROR_7">IDE</span>. In this post I'm not trying to say <span class="blsp-spelling-error" id="SPELLING_ERROR_8">Netbeans</span> is better or something like that, my love for Eclipse is unparalleled for various reasons, but yes I am, sure, eager to tell you my modeling experience with <span class="blsp-spelling-error" id="SPELLING_ERROR_9">Netbeans</span>.<br /><br />Before I do that I'd just write down my opinions about <span class="blsp-spelling-error" id="SPELLING_ERROR_10">Netbeans</span> 6. I would say, profiling is really pretty good, I don't need to understand nefariously complex architecture to use it, I don't need to go to help to use it. See you would say, <span class="blsp-spelling-error" id="SPELLING_ERROR_11">TPTP</span> is complex only for lame users. Are you talking about <span class="blsp-spelling-error" id="SPELLING_ERROR_12">UI</span>? how many perspectives you have as part of <span class="blsp-spelling-error" id="SPELLING_ERROR_13">TPTP</span>? which one to use for profiling? and what you've to do to profile remote Java application? can you answer it without looking in documentation? Don't get me wrong, I'm trying to be as unbiased as I can.<br />As for Ruby support, It is just about as good as <a href="http://www.eclipse.org/dltk/"><span class="blsp-spelling-error" id="SPELLING_ERROR_14">DLTK</span> </a>Ruby <span class="blsp-spelling-error" id="SPELLING_ERROR_15">IDE</span>, I'm no Ruby big shot as yet, but things works pretty <span class="blsp-spelling-corrected" id="SPELLING_ERROR_16">OK</span> with <span class="blsp-spelling-error" id="SPELLING_ERROR_17">DLTK</span> as well, cheers! <span class="blsp-spelling-error" id="SPELLING_ERROR_18">Netbeans</span> has fantastic <span class="blsp-spelling-error" id="SPELLING_ERROR_19">UI</span> editor though, <a href="http://www.eclipse.org/vep/WebContent/main.php"><span class="blsp-spelling-error" id="SPELLING_ERROR_20">VE</span></a> plain sucks, oh and is it around now? last time I heard <a href="http://www.eclipsezone.com/eclipse/forums/t91368.html?start=0">it's dead</a>.<br /><br />Now on modeling, To My fellow Eclipse <span class="blsp-spelling-error" id="SPELLING_ERROR_21">committer</span> guys, let's face it, Eclipse doesn't give anything in modeling front which an average user can use <a href="http://www.eclipse.org/downloads/">out of the box</a>. It might have innovative and <a href="http://www.eclipse.org/modeling/emf/">wonderful framework</a> <span style="text-decoration: underline;">/ </span><a href="http://www.eclipse.org/modeling/mdt/?project=uml2"><span class="blsp-spelling-error" id="SPELLING_ERROR_22">UML</span> infrastructure </a>for building tools around it though, which is very well appreciated by 2% eclipse plug-in developers (including me), fine. So for our <span class="blsp-spelling-error" id="SPELLING_ERROR_23">hacky</span> interests <a href="http://ed-merks.blogspot.com/2007/10/is-emf-going-to-replace-mof.html">EMF might replace <span class="blsp-spelling-error" id="SPELLING_ERROR_24">MOF</span> </a>but Eclipse users are not getting any advantage of it. I know, some might say it's no big deal to not have modeling as a part of <span class="blsp-spelling-error" id="SPELLING_ERROR_25">IDE</span>, but hey that's the whole point, everything from single place is the point. Few would like to use <span class="blsp-spelling-error" id="SPELLING_ERROR_26">Visio</span> to model class diagram and then write code for it. We've quite a few other <a href="http://topcased.org/">reluctantly-<span class="blsp-spelling-error" id="SPELLING_ERROR_27">opensource</span></a> projects, in the community, controlled by arbitrary licenses which are not very useful.<br /><br />For those who don't agree, download and try <span class="blsp-spelling-error" id="SPELLING_ERROR_28">Netbeans</span> for modeling, You will, for sure, appreciate the efforts put into it, it can do hell lot of stuff (It can't copy and paste model elements in single diagram though :) ), Java reverse engineering, simple modeling, in context design pattern appliance, it's just there and works! you don't need to find something on Internet and read it's license thrice before using it. And the best part of it, It doesn't <a href="https://www.regsoft.net/regsoft/vieworderpage.php3?productid=72855">cost an arm and leg </a>to get these features. <span class="blsp-spelling-corrected" id="SPELLING_ERROR_29">OK</span>, it might behave little<span class="blsp-spelling-error" id="SPELLING_ERROR_30"></span> in-development but it's just there for you, try it!<br /><br />Eclipse is the great <span class="blsp-spelling-error" id="SPELLING_ERROR_31">Plaform</span> and I can't even start to compare it or any of it's innovative aspects with something as trivial as <span class="blsp-spelling-error" id="SPELLING_ERROR_32">Netbeans</span> in that context, but guys, shouldn't Eclipse consider it's "end-users" who expect nice features? Advocacy on plain words don't help, it needs strong backing of solid product which offers something more. Learn Learn..Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com4tag:blogger.com,1999:blog-11200164.post-90767278577570236672007-08-26T22:22:00.000-04:002007-08-26T23:02:55.424-04:00Back to Enterprise AppsIt's been quite sometime that I worked with Eclipse and developed RCP apps and Plug-ins leveraging several *<span style="font-weight: bold;">highly</span>* interesting Eclipse projects. The more I work with Eclipse more it attracts.<br /><br />But the time had it and I've to move back with traditional Enterprise Application stuff. I <a href="http://www.eclipse.org/newsportal/article.php?id=251&group=eclipse.employment#251">tried hard </a>to be in Eco-system, but I guess I was out of luck. If you ever happen to be JEE developer you know how different feeling it is to code for Eclipse. Eclipse is fun :), Now, that I agree with <a href="http://mea-bloga.blogspot.com/2007/08/web-development-is-so-90s.html">chris on his views about we</a><a href="http://mea-bloga.blogspot.com/2007/08/web-development-is-so-90s.html">b development</a>, It's time for a conformity rant: Web application development sucks big time. Ok, I'm done.<br /><br />Now that I'm back into the Enterprise app. dev. environment where, apparently, I'll wait months and months for Web Logic (or WebSphere w/e. all of them are bad) to start and deploy large-large application with more and more of ugly XML configs than Java code. I would have open war with the BA on requirements that don't make sense. I can't guess what else will happen with me, I've been the part of this nightmare before and It's coming back.<br /><br />Oh Eclipse, I'm missing you already :(.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com3tag:blogger.com,1999:blog-11200164.post-44386641061653991722007-08-24T12:42:00.000-04:002007-08-24T13:21:05.760-04:00Undo Closetab feature for Eclipse editor tabsOne of the things I love about FireFox is it's nice feature of 'undoing' the close tab. If you work with too many tabs you know how cool this feature is.<br /><br />I was wondering how useful this feature would be in Eclipse. I usually work with tens of FileEditors which keep on growing as I work, to limit my efforts fumbling around a large pile of Editors, I always turn on a useful preference from 'Preferences->General->Editors : Close Editors Automatically'. This is not enough, I still have many editors open and unfortunately it's not too hard for me to close useful editors by mistake, Ctrl+Shift+R helps though. Not sure about you but this feature will be a nice one to have for me.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com3tag:blogger.com,1999:blog-11200164.post-59805512442851172302007-07-30T12:05:00.000-04:002007-07-30T12:56:23.610-04:00Fat Jar Plugin for Europa releaseThere are quite a few bugs on <a href="http://sourceforge.net/tracker/?func=browse&group_id=115990&atid=673355">Fat Jar Tracker</a> lately, <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1748732&group_id=115990&atid=673355">some</a> of <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1744243&group_id=115990&atid=673355">them</a> <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1591854&group_id=115990&atid=673355">related</a> to incompatibility with <a href="http://www.eclipse.org/europa/">Eclipse 3.3 release</a> (aka. Europa). It's been a long time since I touched the code-base of Fat Jar plug-in, There were several Eclipse 3.3 API incompatibilities including <span style="font-style: italic; font-weight: bold;">setSorter(ResourceSorter rs)</span> method, now deprecated, and replaced with <span style="font-style: italic; font-weight: bold;">setSorter(ResourceComparator rc) </span>in <span style="font-weight: bold;">org.eclipse.ui.dialogs.ElementTreeSelectionDialog </span>class etc. I'm glad to have no other major, and painful, changes :) (at least, I haven't encounter one so far).<br /><br />If you are code freak, changes are committed to cvs repository at <span style="font-weight: bold;">fjep.cvs.sf.net</span>. For the users, Since I'm just a developer member of the project, I don't have enough rights to upload the build and release the plug in officially, all I can do is to provide you a link for the latest build which works with Europa release. As of this time, I'm not sure when the latest plug in will be available from sf.net, in the mean time you can <a href="http://nirav.thaker.googlepages.com/net.sf.fjep.fatjar-Eclipse3.3.zip">download it from here</a>.<br /><br />Enjoy Deployment with Europa :)!Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com4tag:blogger.com,1999:blog-11200164.post-19315581546746533792007-04-29T14:51:00.000-04:002007-04-29T16:49:51.207-04:00Closed development instance in Eclipse ecosystemI've been reading <a href="http://eclipse-projects.blogspot.com/2007/04/open-source-must-allow-others-to.html">Bjorn's posts </a>on open source and open development. I can't disagree with his view on open source being more than just making code available. Getting project participation, in greater capacities than just mailing lists, from community is a <span style="font-weight: bold;">good </span>thing, and that should definitely be taken into consideration with proper feedback. The very purpose of being "open" is defeated when a project starts ignoring community contribution without sensible reasons.<br /><br />I've reason to write this, although I'm not strictly against closely developed open source projects.<br /><br />I've been working with <a href="http://topcased.org">a modeling toolkit </a>for quite sometime and had customized it to suit my requirements. The contribution was in the core part of the tool (GEF based clipboard, motility and other ergonomic support for better modeling experience). I sent a mail to project admin asking if they would be interested in taking this contribution, after unknown number of days I got the reply asking for contribution review. I sent it as plug-in source code, not as patch, listing changes in the packages and configs. Most of the features offered in the contribution are actually in the project road-map as enhancement list.<br /><br />But, after more than two months now, I'm still without reply(positive or negative), without comments, without acknowledgment. Now, I've almost lost interest in contributing it.<br /><br />I hope those required features will be implemented (in anyway project team wishes) in next major release of the project, but <span style="font-weight: bold;">I can only hope</span> because the project is not really being developed openly. How sad...<br /><br />Don't get me wrong. I've nothing against the tool, the tool is excellent and remarkably well designed and implemented; Nor with the team developing it, it's their job. But they should definitely mention somewhere that they are not open to external contributions in development.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com13tag:blogger.com,1999:blog-11200164.post-18965203967616668932007-04-13T02:50:00.000-04:002007-04-13T03:44:19.110-04:00Essential Features for Eclipse PDT<a href="http://www.eclipse.org/pdt/index.php">Eclipse PDT</a> project initiative is a good news for <span class="blsp-spelling-error" id="SPELLING_ERROR_0">PHP</span> developers. However, there are few basic features, which are expected of any web development tooling, still missing. It is good to know that the project is focused on serious features on unit testing, debug infrastructure, editors etc. You can vote for the essential feature enhancement on project page.<br /><br />I would like to share some PDT uses from a developer perspective. I use PDT for editing and source code management. These features are good enough, and will be more productive eventually.<br /><br />However I felt lack of support for deployment features, all you get is external tools for local <span class="blsp-spelling-error" id="SPELLING_ERROR_1">apache</span> and basic page browsing. But Every time I modify a web page, I've to do <span style="font-weight: bold;"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">rcp</span> </span>or use <span class="blsp-spelling-error" id="SPELLING_ERROR_3">WinSCP</span> to deploy that file back to the server and refresh page. Also, most of the times, It's essential to be connected with server on SSH connection to do regular fancy server stuff. <a href="http://winscp.net/eng/index.php"><span class="blsp-spelling-error" id="SPELLING_ERROR_4">WinSCP</span></a>, although a great tool, isn't really "ergonomic excellence" and hence this tool switching becomes a painful activity.<br /><br />It seems PDT is assuming that developers work only on development/staging machine and hence the lack of support for deployed web applications. Also based on my experience, I found <span class="blsp-spelling-error" id="SPELLING_ERROR_5">PHP</span> deployment to be very very different, fairly simple to be ridiculously near non-existence, compared to other "heavy-weight" web environment. Java, for example, has lots of "things" and steps to deploy a web app, but that's a different story...<br /><br />I strongly recommend consideration for following features:<br /><ol><li>Built in SSH command interface (remote terminal as console view ).</li><li>Support for auto upload, or built in <span class="blsp-spelling-error" id="SPELLING_ERROR_6">rcp</span> (<span class="blsp-spelling-error" id="SPELLING_ERROR_7">rsync</span> builder - <span style="font-weight: bold;"><span class="blsp-spelling-error" id="SPELLING_ERROR_8">rsync</span> </span>as a part of auto-build would be a great feature!). Alternatively, this can be like MS Visual Studio style interface through HTTP interface, using HTTP methods (PUT etc.). Live Deployment feature is *<span style="font-weight: bold;">essential</span>*.</li></ol>These basic features, not specific to only <span class="blsp-spelling-error" id="SPELLING_ERROR_9">PHP</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_10">IDE</span>, can substantially increase productivity.<br />I'll post more uses of PDT as I go along using it.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com14tag:blogger.com,1999:blog-11200164.post-24896044514777162422007-03-12T00:38:00.000-04:002007-03-12T06:18:00.702-04:00Taking care of abused Exceptions using JDT ASTHow many times you went nuts while dare debugging a large application? and while debugging, faced desperate failure in getting any clue on what went wrong, no exception, no log?<br /><br />Well, If you work on right smartly large bad code base, this experience is quite common. One of the main reasons, as I think, for this situation is swallowed and mishandled exceptions.<br /><br />I ran in similar problems once, where it was becoming very hard to find the problems. I came to know mishandled exceptions in many places. And I decided to write a plug-in to manipulate AST and replace it with logging statements.<span style="font-weight: bold;"><br /><br /></span>Here is the code for interesting parts of the plug-in. Created a <b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">catch</span></b> clause visitor, which will visit all the catch clauses in AST. The AST will be parsed for each Compilation Unit in a loop. <span style="font-weight: bold;"><br /></span> <p class="MsoNormal" style=""><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);"></span></b></p><blockquote> <p class="MsoNormal"><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">private</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">final</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">class</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> CatchClauseVisitor </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">extends</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> ASTVisitor {</span><span style="font-size: 10pt; font-family: "Courier New";"></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(100, 100, 100);">@Override</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">public</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">boolean</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> visit(CatchClause node) {</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(0, 0, 192);">allCatchClauses</span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">.add(node);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">return</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">super</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">.visit(node);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>}</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;">}</span></p> </blockquote>This visitor can be used to collect clauses from AST:<br /> <p class="MsoNormal" style=""> </p><p class="MsoNormal" style=""><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span><blockquote><span style="font-size: 10pt; font-family: "Courier New"; color: black;">ASTParser parser = ASTParser.<i>newParser</i>(AST.</span><i><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(0, 0, 192);">JLS3</span></i><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;">parser.setKind(ASTParser.</span><i><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(0, 0, 192);">K_COMPILATION_UNIT</span></i><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;">parser.setSource(lwUnit); </span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// set source</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;">parser.setResolveBindings(</span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">true</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">); </span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// we need bindings later on</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;">CompilationUnit unit </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">=</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">(CompilationUnit) parser.createAST(</span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">/* IProgressMonitor */</span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);<br />unit.accept(</span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">new</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> CatchClauseVisitor());</span></blockquote><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span></p><p class="MsoNormal" style=""><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span></p><blockquote></blockquote> <p class="MsoNormal" style=""><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span></span></p><p class="MsoNormal"><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span></p> Now that we have all catch clauses, we can iterate on them to execute transformations and rewrite the AST.<br /> <p class="MsoNormal" style=""> </p> <p class="MsoNormal" style=""> </p> <p class="MsoNormal" style=""><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);"></span></b></p><blockquote><p class="MsoNormal" style=""><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">try</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> {</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">for</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> (CatchClause node : </span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(0, 0, 192);">allCatchClauses</span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">) {<br /><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">if</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> (list.size() == 0) </span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// SWALLOWED EXCEPTION</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>putLoggingStatement(node, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">, rewrite, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span> <span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">else </span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// code to replace SOP statements with logger call </span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">for</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> (Object object : list) </span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);"> // ....</span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);"> // computation of the new source code<br /></span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> TextEdit edits = rewrite.rewriteAST(doc,<br />lwUnit.getJavaProject().getOptions(</span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">true</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">));</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);"> </span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">edits.apply(doc);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>String newSource = doc.get();</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// update of the compilation unit</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>lwUnit.getBuffer().setContents(newSource);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>lwUnit.save(</span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">false</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span>} </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">catch</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> (...){...}</span></p></blockquote>And here is the putLoggingStatement method.. <br /><p class="MsoNormal"><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);"></span></b><blockquote><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">private</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">void</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> </span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">putLoggingStatement(</span><span style="font-size: 10pt; font-family: "Courier New"; color: black;">CatchClause node, Object object,</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>ASTRewrite rewrite, ASTNode expStatement) {</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p><br /></o:p></span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>MethodInvocation invocation = node.getAST().newMethodInvocation();</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>setLoggingMethodName(node, invocation);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>SimpleName args = node.getAST().newSimpleName(</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>node.getException().getName().getIdentifier());</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>invocation.arguments().add(args);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">if</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;"> (expStatement == </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">) {</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>ExpressionStatement statement = node.getAST()</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>.newExpressionStatement(invocation);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>ListRewrite listRewrite = rewrite.getListRewrite(node.getBody(),</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>Block.</span><i><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(0, 0, 192);">STATEMENTS_PROPERTY</span></i><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>listRewrite.insertFirst(statement, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>rewrite.replace(node, node, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">); </span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// replace the nodes</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span></span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">return</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">;</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>}</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>ExpressionStatement statement = node.getAST().newExpressionStatement(</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span><span style=""> </span>invocation);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>setContextInstaceVariable(invocation);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>rewrite.replace(expStatement, statement, </span><b><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(127, 0, 85);">null</span></b><span style="font-size: 10pt; font-family: "Courier New"; color: black;">);</span><span style="font-size: 10pt; font-family: "Courier New";"><o:p></o:p></span><br /><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""> </span>}<br /></span><span style="font-size: 10pt; font-family: "Courier New"; color: black;"><span style=""></span></span><span style="font-size: 10pt; font-family: "Courier New"; color: rgb(63, 127, 95);">// ....</span><br /></blockquote><span style="font-size: 10pt; font-family: "Courier New"; color: black;"></span></p> A number of details are removed for the sake of brevity and I don't claim the code to be professionally written. There are some improvements I can thing of, like, the SOP can be replaced with logging statement, a provision for rethrowing exception statement based on some config (no, no configs!)....<br /><br />Finally let me tell you that writing the code involving AST can become complex and error prone, but it does a real good job. This small job of carefully writing a custom code manipulation saved me from doing it manually for hundreds of java source files as well as code maintainability got much better, what a relief!Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com4tag:blogger.com,1999:blog-11200164.post-11380044964564910722007-02-27T02:58:00.000-05:002007-02-27T05:23:31.040-05:00Executable Models<span style="font-weight: bold;">Imagine...</span><br /><br />A work place where your regular tasks involve analyzing and modeling the parts of system based on stories (or requirements, whatever) and writing few snippets of instructions. You've a world class IDE with some wonderful perspectives, editors, views and a state of art execution infrastructure. The IDE allows quick execution of your models to test them, allows visual model debugging while encouraging ergonomics to prevent heavy "keying and mousing", IDE supporting finest model refactoring to allow painless design change, while providing real time collaboration for distributed brainstorming and discussions...<br /><br />You pair model it, you test drive it, you version it at finer granular unit of control, you've a catalogue of blueprints (design + domain) which can be used statically as well as in context of existing system, you have continuous integration of models which compiles, validates (tests) and builds the system. At end of the day, you've a system which can simulate in development environment as well as deployable as production software....<br /><br />Imagine a execution infrastructure able interpret UML (relax, take unambiguous parts of UML or Mellor subsets) directly, or may be it emits a script which can be plugged in existing JVM, or may be UML VM itself with attach on demand and hot model replacements :) ....<br /><br />I dream to be in such an environment as well as developing such environment.<br /><br /><span style="font-weight: bold;">Realize....</span><br /><br />These imaginations, although will sound like philosophies, are not without basis, existing tools and technologies can be leveraged and bridged to provide this envisioned platform; it's hard, takes lot of resources but not impossible. Ok, it will not give quick returns, will have adoption problems which can be handled.<br /><br />At first, <a href="http://en.wikipedia.org/wiki/Executable_UML">Executable UML</a> will seem like a buzzword, to me it sounded daunting and it seemed like everyone wants to change the world. That change is for good, how long you want to work with something as ugly as XML or JSP and other complexities which in no way adds to customer requirements? They deserve to be generated or they don't even deserve to be in our codebase (I should say modelbase :) ).<br /><br />Executability of models is not something entirely new (apart from Virtual Machines, OOP etc.), guys like Steven Mellor and Marc Balcer are working on it for quite sometime now.<br /><br />If you feel, that, support for such tooling is not enough; Let me tell you, Eclipse has made such feeling "Past"; With Eclipse, We can leverage most of the Eclipse related technologies for achieving it, ECF for collaboration, UML/EMF/GEF/GMF for modeling, Debug Framework and GEF for simulation and model debugging (in this case, we may need to change the abstraction semantics of stack frames etc.) . Of course building VM or runtime is non-trivial, but it's worth trying alternative approaches like integrating with existing runtime.<br /><br />This is the time for improving the software crafting (or engineering?), no one needs costly software, and current fashions make them expensive; Well its different topic to debate about productivity levels of existing methods but it can surely be improved.Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com1tag:blogger.com,1999:blog-11200164.post-86008162044996692692007-02-21T10:15:00.000-05:002007-02-22T01:46:40.081-05:00When will 'Software Modeling' catch big time attention?From last one year, I'm working on a modeling tool featuring support for UML2 and BPMN1.0 specifications. Well, this tool is not envisioned just like "yet another modeling tool" allowing you to draw basic elements (and strange visual manipulations) and generate structural code and documentation (which is not impressively useful!).<br /><br />It's commonly known that modeling is good for visualizing and documenting a system. Well, I've heavily used UML for documenting and I found it useful for communicating software blueprints to those who don't understand the technology well.<br /><br />Contemporary tools can do better apart from visualizing, Typically a modeling tool doesn't sponsor full blown generation of an application for target platform, say J2EE; Not that it's insane attempt but it's simply too much of work. They generate structural code (skeletal) from model (say, classes from Class Diagrams) ; this is commonly known as forward engineering. Tools also support round trip engineering for regenerating the code from model while maintaining the manual customizations.<br /><br /><span style="font-style: italic;">How redundant, Why to model and code at the same time and why maintain both? </span><br /><br />The tool I'm working on is supposed to generate "typical application" end-to-end (heh, really?!). Also, Tool has a special language(sort of BASIC dialect) , that can be used to write business logic for the application which might, otherwise, result in tedious micro modeling (boy, you will require incredible mouse capabilities for that level of modeling). This language is customized implementation of <a href="http://www.omg.org/">OMG</a>(tm) Action Semantics Language (ASL) and Object Constraint Language (OCL); The logic in this language is translated in to platform specific code during transformation and code generation.<br /><br />Technically, this is enough for generating entire application. Recently, tool vendors are trying to avoid the ASL approach altogether and use supplemental UML models (like activity and state machines) to specify behavioral aspect of system; but this approach has usability problems, although it is an interesting technical challenge (umm... given enough beer and I'll even admit that I wrote a state machine compiler for money to generate behavioral code..).<br /><br /><span style="font-style: italic;">How bad again, Why I want to learn UML, a dumb ASL language and still struggle with generated code to customize it?</span><br /><br />I agree that the tool can generate "student projects" like applications, but still keeps me skeptical about *serious* applications which involve complexities of security, performance and integration. It's not impossible to do that either, however, supporting multiple security/persistence/application frameworks/third party interfaces for multiple platforms, in its entirety, would be a non-trivially huge attempt ever made.<br /><br />Lately, I'm observing generative methods in regular development; these days, most applications are combination of generated + hand written code(in some reasonable combination), people manage both code as well as model. Generative Technologies are gaining acceptance gradually, especially because support from Eclipse projects like <a href="http://www.eclipse.org/emf">EMF</a>, <a href="http://www.eclipse.org/gef/">GEF</a>, <a href="http://www.eclipse.org/gmf/">GMF </a>and other <a href="http://www.eclipse.org/modeling/">Modeling subprojects</a> apart from rising community interest, hundreds of modeling tools are available and major players are investing in this technologies.<br /><br />We have witnessed the transitions in technologies; Transitions from Hardware specific Assembly code to C code, C code to C++/Java/RoR code.., these transisions are fine and gradual, but with modeling being a paradigm shift in the way we see software development (its not just about learning new language, right?), modeling imposes the steep learning curve, and understanding the mammoth specifications. It's always difficult to adopt a different way of doing things.<br /><br />With the current state of tooling and specifications, it is difficult to offer <span style="font-weight: bold;">"Generate everything, Write Nothing"</span> jargon feature, and its pain in a**e to maintain both model and code in sync (tools are improving though). I'm sure of one thing, generative development is going to be the next generation of software development, not sure how many more years...Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com6tag:blogger.com,1999:blog-11200164.post-68869501374295056702007-02-01T02:03:00.000-05:002007-02-01T03:40:39.521-05:00The Pune Eclipse Developer Group<a href="http://dynamicproxy.livejournal.com/">Sriram </a>and <a href="http://ketan.padegaonkar.name/">Ketan </a>initiated <a href="http://groups.google.com/group/eclipse-pune-dev">The Pune Eclipse Developers' group</a> to promote collaboration between eclipse developers in Pune. I came to know about good strength working on eclipse plug-ins and related technologies in Pune, its good idea to get them together, share ideas-techniques and socialize with like minded people around town.<br /><br />Recently at <a href="http://gnunify.symbiosiscomputers.com/">GNUnify '07</a> Ketan and Sriram spoke about Eclipse Rich Client Application Development. Eclipse Enthusiast can find the presentation <a href="http://eclipse-pune-dev.googlegroups.com/web/gnunify-rcp-2007-01-26.zip">here</a> and workshop code <a href="http://eclipse-pune-dev.googlegroups.com/web/gnunify-svn-2007-01-26.zip">here</a>. The presentation is interesting, explains Eclipse architecture; frameworks around it; benefits etc.<br /><br />I wish Pune Eclipse Developers' group existed before few months, I would have found few more good guys for my team :).Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com0tag:blogger.com,1999:blog-11200164.post-26771185911965084412006-10-17T11:59:00.000-04:002007-01-31T11:12:29.339-05:00Reuse Pain in Eclipse UI CodeCode Reuse is one of the most interesting, if not alluring, part when you are contributing to Eclipse. In eclipse, many a times I'm tempted to use code of other plugins. Eclipse guys like to keep UI-code 'internal' , still, I try and again to reuse, which ends up in "monkey see/monkey copy+paste" with added disarrays. <p>This temptation is not just because of my indolence to duplicate development cycles but something which is commonly done (it's all about reuse right?), ofcourse at very clear granular leves (called extensions) which, I, somehow find limiting.</p> <p>It is too frustrating to figure out sheer context information for some code deep in eclipse dungeons, the more you read code, deeper it takes (and ofcourse how can the temptation of what is inside be controlled?). This results in a tempest of hazardous shortcuts which keeps you away from starting afresh or thinking in different way and you end up in violent mess of yellow signs and incomprehensive code !</p> <p>Recently one of my collegue ran in similar situation, I looked in to it to see how serious it can get, I too quicky drawn in it. The task involved implementation of preference pages for code/comments etc. in our code generation templates, as well as templates for ADDL( home grown action semantics language). We started looking into JDT UI, which has a preference page with similar functionality named "CodeTemplatePreferencePage" which delegates UI to CodeTemplateBlock which in turn owns inner classes to do "real" stuff. There are hardly any hooks where it can be extended "as is". We started with extending it and ended in copy pasting somewhere around 6-7 java files (and contrived satisfaction that it was looking good to end-user).</p> <p>It just didn't helped! we finally created UI using <a href="http://www.eclipse.org/vep/">Eclipse Visual Editor</a> and programmed widgets/viewers and preferences in less than one forth the time we spent in reading and fumbling in JDT-UI code.</p> <p>Lessons learned after hours of pairing, never try to reuse what is "internal" and don't ignore it no matter how tantalizing it is!</p>Nirav Thakerhttp://www.blogger.com/profile/07204297663478577248noreply@blogger.com0