Saturday, January 24, 2009

TestNG

I had read about TestNG, including the book, and even played a little bit with it. But, until today, I had never set it up as the testing framework in a project instead of JUnit.

Why have I taken this step? Well, I have felt the need many times to keep state between test methods to simplify them (and if you add dependent methods, also in TestNG, in order to chain them), even though I understand JUnit's reasons for not providing this functionality.

So, TestNG has earned itself another "testing" round :).
 

Living on the edge...

As predicted by Murphy's Law, if you need some feature (or a critical bug solved) from a third-party library or framework, it'll be planned for the next version.

I faced this truth again a few weeks ago. I was looking at Guice for some specific dependency injection needs... and type converters where planned for 2.0...


Friday, January 23, 2009

A Domain Driven Design snippet

This post in my reading list reminded me of Domain Driven Design (see the book). I've always liked the idea of strong Domain Models that lead to better encapsulation and more information hiding.

What's the problem, then?. For many (even CRUD) applications much business logic involves non-trivial repository access. So, you need your bussiness objects have a reference to the repository. This should not be a problem for your favorite dependency injection engine.

At this point your favorite ORM tool chimes in, taking control of the lifecyle of your domain objects... Well, there are some AOP-based solutions, but I don't see them as long-term general solution yet.

Sunday, January 18, 2009

Null-default and Null-safe operators

Today I've been having a look at Stephen Colebourne's proposal for null-handling in Java 7 (see this post for a summary).

I really like this proposal:
  • It is only syntax sugar, like many of the changes introduced in Java 5.
  • It really helps to reduce boilerplate code.
The main drawback I see is that heavily chained uses of the null-safe invocation operator may lead to some debugging knightmares (which invocation returned null?) unless some support is added to IDEs.

Sunday, November 23, 2008

Asynchronous transitions for Active Objects

I've added support for asynchronous transitions in ActiveObjectSupport (see parts 1, 2 and 3 in the series).

The asynchronous versions share the same logic of the synchronous ones. The preconditions are checked in the calling thread, the state change to a transient state is also done in the calling thread (as it was previously shown it's just an update to an atomic reference) and the transition is performed in a background thread, including waiting for pending requests to finish.

Why did I add this feature now? Well, I'll need it for the next iteration of lucis.

Saturday, November 8, 2008

Thread-safe simple lifecycle (part 3)

In parts parts one and two of these mini-series, we started showing how going multi-thread could affect the simplest lifecycle of what we called and active object. In the end, what we have is a set of open questions, including (some of them were presented in previous posts):
  • What happens if you try to start the object and some other thread have previously done so?
  • What happens if several threads try to stop the object at the same time?
  • What happens if you try to stop the object when there are in-flight requests? Do we wait for them to finish? Do we stop and let them crash?
And the answer to all these questions is the same: it depends. It depends on the semantics of each particular object, so we can't provide a solutions suitable for everyone, every time. But this doesn't mean we can't do anything. I've checked in a new solution. Some of the highlights include:
  • The lifecycle interface is gone. As we have shown different problems need different semantics and thus, a different interface. Instead, we have a support class.
  • Though externally the same fixed-set of states is kept (implemented as an enumerated type), internally an infinite set of states is used, so that we can keep track of in-flight requests.
  • No synchronization is used, and state changes are performed using atomic references. Client-provided transition code is guaranteed to be run by just one thread without holding any locks.
  • No standard semantics are enforced. Instead, the support class provides methods so that you can build your own. Eg, if you call a method to start or stop the object while the transition is being performed in another thread an exception is thrown. However you can catch this exception and use the provided methods to wait for the object to reach a permanent exception to implement different semantics.


Maven deploy to sourceforge

Recently some changes have been made in sourceforge. Basically, previously somewhat unlimited shell access has been removed and now file upload must be done through web.sourceforge.net using username,projectname as the login. This service supports SCP, SFTP and rsync though SSH.

However, I haven't been able to get maven to deploy to sourceforge using these new settings, and I haven't found a solution yet. As a workaround you can issue:

ssh username,projectname@shell.sf.net create

and you will granted (temporal) shell access so you can still use your old-style scp deploys to shell.sf.net. So, you have to (manually) request this shell access before performing your deploy.

This change also affects maven site deploying. When deploying your maven site through SSH, maven uploads a compressed file containing your site and then remotely uncompresses it. However, web.sourceforge.net does not allow remote command execution, so maven is unable to uncompress your site. Fortunately, the same workaround described here applies.