Sunday, 25 July 2010

Java Decompiler for Eclipse

Recently I had to install a decompiler plugin for Eclipse at work and had to spend some time to actually find it as JadClipse sourceforge only points to version 3.3.0 of the plugin which is rather old. In February 2009 a new version - 3.4.0 - has been released, which also changed the name of the plugin. The update site that works also with Eclipse 3.6.0 is http://jadclipse.sf.net/update .

Friday, 4 June 2010

Perforce and Subversion - a short story of a new-found love

Before my previous project I used CVS and SVN and obviously preferred SVN. In my eyes it wasn't maybe the best thing ever, but I was reasonably confident user, knew how to merge and, more importantly, I knew how to force it to cooperate when I screwed my local .svn folders. I liked it.


First few weeks after joining, working with Perforce was a major pain. Ideas of client specs, changelists, "opening for edit", creating branches etc. - all that was new, and not exactly friendly for ex-svn user. I simply didn't know how to use it. I complained a lot, I was completely confused (and rather complicated build process around it specific to the project didn't help at all).

However, recently I switched jobs, and after first shock of learning that we're still using CVS, I realized that the migration I'd love to see is not to SVN. It's to perforce.


What has changed? I have become much more comfortable with P4 and I realized that it really supports productivity and is more powerful than SVN. Bear in mind that last time I used SVN was not this recently and some of the things I'll mention here may be in SVN - but I don't think they were there when I was using it.


  • The first great strength of P4, especially when working in a really big team and not much of code ownership (i.e. everybody touches everything) is merging. The fact that P4 can track exactly which changes were already integrated (merged) and which not makes it sooo easy to work on branch/trunk and only merge as and when necessary. And unless there are conflicts the merge task of quite big branch can be literally 2 mins. And - again - because P4 tracks what you already merged and what not, you could merge every day and barely notice you're working on a branch. you can bring changes between branch and trunk back and forth and unless you're (rather stupidly) trying to manually merge files - it's absolutely unbeatable. Of course working on branches will always give some overhead - but I feel that managing this with P4 is way easier than with SVN.

  • I also loved 3-way diffs (and even though I'm sure that could be done on every version control system, somehow I first saw it when using P4).

  • I loved changelists. I now can barely imagine living without them in SVN. Perhaps it's because I sometimes have some "side-work" that is of very low priority, but being able to keep it on a seperate changelist until I'm (finally) able to commit is really nice. I don't have to check with each commit what files I want to submit now and which ones later - or not at all. BTW latest P4 has idea of "shelving changes" so there isn't even a worry that if the machine dies, you lose your work.

  • I absolutely love the fact that it doesn't store any additional information in my code folders and that it's so easy to revert if I accidentally remove a directory.

  • Despite my initial reservations about "open for edit" sometimes it actually was really useful - for example before doing a major refactoring and deleting/renaming some classes I could check if by any chance someone else is working on them and talk to them, maybe postpone my refactoring a bit so that we don't have to merge. It's not a lock, multiple people can have a file open for edit - it's just a marker. The only drawback is that the first time you start editing a file Eclipse would hang for a fraction of second while opening the file for edit - but you can really live with that.

  • Absolutely fantastic support for viewing history, with my favourite "time line view" which is basically "blame on steroids". You can see whole history (or selected range) of the file with deleted lines stroked out, additions and modifications clearly marked, with author names alongside, and easy access to details of the commit (when, comment etc.).


What I didn't like?



  • That you need to remember to explicitly add files for add - in theory you have to do that in svn as well but somehow SVN clients are always much better in detecting new files. The solution here is to make Eclipse always open for Add when you create a file

  • Eclipse plugin for P4 is nowhere near SVN plugin - but to be honest, it didn't take me very long to get used to having P4Win constantly open on second screen and I didn't miss direct Eclipse integration this much. It would have been much worse if I only had something like Tortoise.

  • Creating of labels and branches could be easier. Once you grasp the concept and understand how it works - the procedure is not this bad, still I think it could be a bit more user-friendly (perhaps all it needs is a nicer wizard in P4Win!).



Overall, I'd say that yes, perforce has a learning curve (in my case from "omg, wtf is that?!" to "it's actually kind of nice" it was about 2 months), but now given choice I'd go for Perforce without a second of hesitation. Unfortunately the fact that is not free (or perhaps should say: is very expensive) doesn't help - but I just found out that you can get Perforce for free for 2 devs - so you can always try it.


I hope that in near future I'll get a chance to try out Git which gets a lot of praise - however, I'm slightly worried by the lack of something in the class of P4Win/TortoiseSVN. Perhaps it's just a matter of time.

Sunday, 2 May 2010

Useful Eclipse plugins (1) - Grep console

I hope this is just the first in series of posts regarding useful Eclipse plugins - there are so many of them. Quite a lot are widely known - here I want to concentrate on the ones that I wasn't aware of for quite a long time.

Grep Console is one of them - a very useful plugin as, like in my current project, the amount of log output is enormous. It's easy to miss what you're looking for... well, not any more.

Here are my settings for this plugin (unfortunately the line with settings cannot be split!):

#Fri Jan 22 16:46:53 GMT 2010
eclipse.preferences.version=1
settings=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><expressions><expression grepExpression\="^(.*Exception\:|.*Caused by\:|\\s*at).*$" name\="EXCEPTION"><style background\="ff80c0" foreground\="000000"/><style/></expression><expression grepExpression\=".*ERROR.*" name\="ERROR"><style background\="ff0000"/></expression><expression grepExpression\=".*WARN.*" name\="WARNING"><style background\="ff8040"/></expression><expression enabled\="false" grepExpression\="^.*INFO .*$" name\="INFO"><style foreground\="808080"/></expression><expression grepExpression\="^.*DEBUG.*$" name\="DEBUG"><style foreground\="c0c0c0"/></expression><expression enabled\="false" grepExpression\="^[^\\d].*$" name\="NONLOG"><style foreground\="c0c0c0"/></expression><expression grepExpression\="^\\t.*$" name\="TAB"><style foreground\="000000"/></expression><expression grepExpression\="^Hibernate.*$" name\="HIBERNATE"><style foreground\="c0c0c0"/></expression></expressions>

It needs to be placed in %ECLIPSE_WORKSPACE%\.metadata\.plugins\org.eclipse.core.runtime\com.musgit.eclipse.grepconsole.prefs file

Saturday, 20 February 2010

Google collections ordering and filtering

Recently on my project I faced a task that could be simplified to a following problem:
I have a list of objects of class Foo, which has a field bar which is a String. I get a list of Strings X and the task is:
a) from the set of objects Foo I need to filter out anything for which the bar field is not equal to one of the Strings on the list X
b) the order of objects Foo according to their bar value must match the order of Strings on the list X

Google Collections came to the rescue allowing me to write a nice and concise (and bug-free!) code in a matter of minutes. Here is how it looked like:


import java.util.Collection;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Ordering;

public class Bazz {

private final static class Foo {
private String bar;

public String getBar() {
return bar;
}
}

/**
* @param bars
* Reference bar List to define filter and sorting
* @param foos
* List of object that needs to be filtered and sorted
* @return Filtered and sorted Foos
*/
public List filterAndSort(final List bars, final List foos) {

Collection filtered = Collections2.filter(foos, new Predicate() {
public boolean apply(Foo foo) {
return bars.contains(foo.getBar());
}
});
Ordering fooOrdering = Ordering.explicit(bars).onResultOf(new Function() {
public String apply(Foo foo) {
return foo.getBar();
}
});
return fooOrdering.sortedCopy(filtered);
}
}



The only thing I'm currently wondering about is how would it look in a functional language like Scala for which the book is already in the reading queue...

Saturday, 23 January 2010

Attached properties in Silverlight

I'm pleasantly surprised by the existence of attached properties in Silverlight. They provide a neat point of extension for properties in child-parent relation between components. It may have been better if they called it "metadata properties" or similar (it would certainly bring my mind into correct direction) though. The example in the book I'm reading is not actually very impressive (namely Grid.Row, for which probably a couple of other options exist) but I can see how the mechanism behind this may be useful when desiging my own app.


The idea is simple - when placing an element in XAML you can place an attribute, say Grid.Row="value". Internally, it's going to get translated into a static call to Grid.SetRow(caller, value), and in this particular case in turn will call caller.SetValue(Grid.RowProperty, value). Parent object then can call getValue on the child to get the value. Nice decoupling and no need to implement any special methods on the classes that are going to be contained in the parent. The child doesn't even have to be aware of what properties are set and how are they going to be used.