Waiting for Groovy 1.8

Groovy 1.8 is going to be released in December 2010. First beta release is already open to download and second beta release will be ready in September.

Groovy developers team preparing for us a few important surprises.

They added more AST transformations, for different cases like @Canonical, @EqualAndHashCash, @ToString and many others. You may use such annotations to generate toString(), equals(), hashCode() methods on compilation. @InheritConstructors helps to generate inherit all parent constructors, and here is link to task.

Another interesting feature is Closure composition, so now it's possible to use special syntax to compose multiple closures, like:

def log = { a -> println(a); a }
def save = { a -> dao.save(a); a}
def notify = { a -> notificationService.notify(a); a }

// so now instead of calling notify(save(log(user)))
// you may call it like
def action = log >> save >> notify
action(user)

// or even like
notify << save << log << user // is that awesome or awful?!

Also they prepared few performance improvements: avoiding calling methods when it's not necessary and processing operations on integers as primary type values but not objects (like, incrementing or adding). As result Groovy can be used for mathematical calculations without performance issues. In this presentation you can read much more about this. And here are related jira tasks so anyone can watch the progress.

This issue is fixed so they can't say that "Ruby is right, Groovy is wrong" anymore :)

Annotations now can accept closure as argument:

@Validator { password.size() > 6 }
String password

This task contains more information and links.

Closure currying is a powerful thing. And now it's possible to curry right and 2nd (of three) parameter. Moreover no need to wait Groovy 1.8 to try this, because it's available right now and right here, starting from version 1.7.2 of course ;)

Well, that's all about this for now. Waiting for Groovy 1.8 and for more interesting things to be released this December.

SpringWS and Jaxb

Well, truly say this small post is not about how to use SpringWS and Jaxb together. It's more about potential power of this combination. I know, that combination is in release for few years alredy and used by thousands of developers. But this article is more for guys in doubt if they really need SpringWS rather than for experienced Spring WS developers.

First of all, I want to say that Spring WS is very powerful framework. I've noticed it when version 1.0 beta was released. As everything in Spring it has good API, simple implementation model and as result it was very flexible. And this mean that you can easily introduce need changes and extensions without changing Spring WS source code.

From the beginning, the Spring WS team was saying that SpringWS should support not only low-level request processing, when you have some object that represents input XML document or build output XML document, but can use different mapping and translation libraries to make it for you. And here is a place for Jaxb.

To enable marshaling you need just to do few simple changes:

  1. Add marshaller bean of org.springframework.oxm.jaxb.Jaxb2Marshaller type:
    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
    <list>
    <value>GetImageRequest</value>
    <value>GetImageResponse</value>
    <value>AddImageRequest</value>
    <value>AddImageResponse</value>
    </list>
    </property>
    </bean>

  2. Add Marshaling Method Endpoint Adapter to yours spring.xml:
    <bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
    <property name="marshaller" ref="marshaller"/>
    <property name="unmarshaller" ref="marshaller"/>
    </bean>

  3. Well, that's all :)

And then, after some testing, I found that it would be nice to trim input text fields and do other post-marshalling operations. And I was sure there was a normal way to do that with rather Spring WS or Jaxb. After a few minutes of searching, I have found the way and had completely working code that was doing what I was needed.

The catch is that Jaxb Unmarshaller supports listeners and Spring's Jaxb2Marshaller has a property unmarshallerListener, that points your listener to Unmarshaller's listeners.
With only 3 lines of configuration we have own listener called on each unmarshalling:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
....
<property name="unmarshallerListener">
<bean class="TargetHandlerUnmarshallerListener"/>
</property>
</bean>

Here is TargetHandlerUnmarshallerListener code:
import javax.xml.bind.Unmarshaller;

public class TargetHandlerUnmarshallerListener extends Unmarshaller.Listener {

@Override public void afterUnmarshal(Object target, Object parent) {
super.afterUnmarshal(target, parent);

if (target instanceof PostPopulatedHandler) {
((PostPopulatedHandler) target).postPopulated();
}
}
}

In this class I override only afterUnmarshal() method, that is called after XML is transformed to the Java object. You can also override beforeUnmarshal() method if you need.

PostPopulatedHandler is my own interface that expose only postPopulated() method. Each class knows what to do after unmarshalling, and declares it in the postPopulated() method. Of course, there can be used some annotation, but interface option is the most simple, easier and obvious way.

So, some summary is next: Spring libraries are awesome, because they always provide very good API and you always can do what you need without changing library source code. Jaxb is awesome as well. I'm noticing this, because it's always hard to write good API, especially in multifunctional libraries.

Migrate from SVN repository to Git

As I was saying in my previous post it is easy to migrate you project from Subversion to Git.

Really, you will need just a few commands to run.

First of all you need to make a clone of Subversion repository using git-svn tool:

$ git svn clone --authors-file=authors.txt https://example/svn/MyRepo/trunk/project project

On this command git will go through the history of the project and fetch it into local git repository. If your subversion repository is using standard layout (i.e. trunk, branches and tags paths are present in the SVN repository root tree) than you may be interesting in --stdlayout option. You may also specify custom path for trunk or branches or tags using -T or -t or -b option respectively.

Option --authors-file contains the path to the file with committers mapping.
This file contains SVN committer mapping to git user per line.
For example:

ruslan = Ruslan <ruslan@example.com>
john = John Smith <john@smith.com>

So now you have local working copy that is managed by Git and also you have all project history in your local repository. It's easy to check what branches and tags you have using next commands:

$ cd project
$ git branches
$ git tag -l

If you have remote Git repository (maybe in GitHub), than you may want to push source code with all history to that repository. And it is not a problem, as you have already everything you need.

1. So add remote repository:

$ git remote add origin git@github.com:myname/myproject.git

2. And push to the remote repository:

$ git push origin master

3. and be happy - now you have migrated to the git repository.

Remove directory with SVN repository clone and make another clone but from git repository and continue using it:

$ cd ..
$ rm -rf project
$ mkdir project
$ cd project
$ git init
$ git remote add origin git@github.com:myname/myproject.git
$ git pull origin master


Thats how it worked for me 2 months ago.

Git and GitHub

Completely moved to Git and it's awesome. Feeling like someone unleashed my hands. Git works much faster than Subversion in everyday use. Using branches is easy and NORMAL and I'm using it day by day. No more need to have many directories with strange names and different project versions. No more fear before merging. No more failures on merging.

My opinion is that everyone must try and use some of distributed version control system, like Git or Mercurial or Bazaar. I've started using Git intensively with projects under Subversion. It was possible thanks to the git-svn project and I was working on Windows in that times. Now I'm on Linux and using git is much easier and natural. git-svn also is very useful to migrate projects from svn repository to the git repository. On checking out project you need to wait some time, because it reads the all history of repository with all changes, that is pretty long in subversion for large projects. As soon you have clone of the project svn repository, you push your changes to central git repository if any. If you need you can do commiters mapping. If you need, you can continue work with both repositories.

And what about GitHub? It's another awesome software. A lot of open source projects are using GitHub. You easily can have and use private repositories and it's pretty cheap - only $7 per month for 5 private repositories.
Each repository goes with wiki, basic issues tracker, useful reports and many others. Especially, I like Network graph, because it helps to visualize commits and merge history.

Some interesting links:
1. ProGit online book
2. Git with Subversion
3. GitCasts
3. The way GitHub helped Erlang and the way Erlang helped Github

Other related posts:
1. Git and Subversion work together

Ruslan and Linux

Давненько я нічого не писав...

За такий здавалося нетривалий період часу, багато чого встигло помінятися, тому, думаю, буде що розсказати.

Мабуть, найбільшою зміною для мене був цілковитий перехід на Linux. Ось уже від початку травня я є гордим користувачем Ubuntu 10.04. Перехід видався значно простішим, ніж можна було очікувати, але це скоріше за все результат моїх попередніх поривань в цю сторону, а також нетривалого, але плідного використання Slackware.

Важко далося використання MS SQL Server на локальній машині під Linux. Не можу сказати як я вирішив цю проблемо, тому що я її не вирішив. Використовувати віртуальну машину було нереально, адже в результаті тормозило все і вся. Тому довелося використовувати віддалений сервер і в результаті працювати тільки в онлайн. Благо, тепер потреба в ньому мінімальна.

Декілька слів про Ubuntu. Зручно, приємно, вражаюче і крім цього є консоль із всіма її потугами. Через кілька тижнів використання, я вже не міг собі уявити себе без Linux, а Windows 7 почав виглядати поцікавому і, навіть можна сказати, екзотично.
А ще недавнo я для себе відкрив, що в mc можна використовувати мишку. І це могло би перевернути мій світ, але не стало ;)

Люблю консоль. Консоль та набір скриптів дозволили оптимізувати роботу в Linux та роботу по проектах.