Tuesday, December 11, 2007

See you at Javapolis!

I'm going to leave Rome and catch my flight for Antwerp.
Actual destination : Javapolis!

I will hold a BOF, so don't miss it.

See you there!

Saturday, December 08, 2007

Owner Based Locking explained

If you attended my presentation at the Rome JavaDay about my real world experience in clustering Atlassian Jira, or if you took a look at my slides, you may already know that one of the challenges was the rewriting of the Jira caching system.
The hardest part of this challenge was to define the cache locking strategy.
That was because of two requirements, due to the Jira code and the way it has been clustered:

  • The need to associate more caches under the same lock.

  • The need to execute arbitrary code blocks atomically: that is, again, under the same lock.


So here it comes my idea of the owner based locking.
It's very simple and I'll explain it in a moment: others may find it useful, or elaborate on that for solving their own locking problems, or just provide useful suggestions.

Let's start with the concept of cache group. The cache group is the entry point for your caching system, where you create caches, put things and get back them and alike.

First step : when you create a cache into the group, assign it to an owner.

The owner is a string, and nothing more. It just serves two purposes: it's the name which associates different caches, establishing some kind of caches sub-group, and their lock.

Here it comes the second step : use the owner as a lock for different caches sub-groups.

This is a lock striping technique.
Lock striping techniques prescribe you to distribute your data in several "stripes" and split your big, fat, lock in several locks, assigning each one to a different stripe : this is done for enhancing thread concurrency, given that different threads will be able to concurrently access different parts (stripes) of your data because guarded by different locks.
In our caching system, the stripes are the different caches sub-groups, and the locks are the owners.
A code snippet will help clarifying.
Here is how a value is retrieved from a cache into the cache group:

public Object get(String cacheName, Object key) {
CacheHolder holder = (CacheHolder) this.group.get(cacheName);
String owner = (String) holder.getOwner();
synchronized (owner) {
Map cache = holder.getCache();
return cache.get(key);
}
}

As you can see, the synchronized variable is the owner string: by doing so, caches with the same owner will be protected by the same lock, while caches with different owners will be accessed concurrently, but without compromising the whole thread safety.

Finally : use callbacks for atomically executing code blocks.

This is best explained by first showing the callback interface:

public interface AtomicContext {

public Object execute();
}

And how it's used into the cache group:

public Object executeAtomically(AtomicContext context, String owner) {
synchronized (owner) {
return context.execute();
}
}

As you can see, the execute() method is executed atomically under the given owner lock.
However, here I have to raise a warning flag: if the implementation of the execute() method uses caches belonging to other owners, it may cause deadlocks; so take care and use only caches whose owner is the same as the one provided to the executeAtomically() method!

That's the owner based locking.
You can take the full source code of the cache group used for clustering Atlassian Jira from the Scarlet Jira extension distribution.

Any feedback will be highly appreciated.

Cheers!

Wednesday, December 05, 2007

News about Scarlet

One month has passed since my last post, due to the fact that I've been very busy working at the hottest (well, maybe I'm a bit biased here...) Jira extension around : Scarlet.
Here are some news about it:

  • Me and my colleague and friend Ugo talked about our experience in clustering Jira with Terracotta at the Rome JavaDay: people really appreciated it, and if you weren't there (or if you liked us so much that you want to read them again) you can take a look at the slides (in English language) here.

  • We've just released the Scarlet Beta 2 version! Take a look at the full announcement here.


As always, every kind of contribution will be welcome.
See you!

Tuesday, November 06, 2007

Scarlet is out!

As I said some weeks ago, in the past two months I've been deeply involved in clustering one of the most important Open Source enterprise applications around.

Now, it is time to unveil the amazing work done here in Sourcesense, because the first public beta release of Scarlet is officially out!

Scarlet is a free, open source, clustering extension to Atlassian Jira, providing scalability and high availability to the most famous and widespread issue tracking software.
It is based on Terracotta DSO, so it's a completely transparent / easy-to-setup clustering solution: no new things to learn, no complex configurations to apply, no expensive hardware to buy ... just the same old Jira!

It has been a very challenging work with a lot of interesting technical issues: you'll surely read some articles about them in the (very) near future.

In the meantime, download and learn more about Scarlet here.
Play with it.
We need any kind of feedback : suggestions, feature requests, bug reports and alike.
Do not hesitate.
We need you.

Saturday, November 03, 2007

Introducing the Scala Language

It is both a pure Object Oriented and fully featured Functional language.
It is both a scripting language and a compiled one.
It is a stable, solid, well designed language.
It has been very well received by a lot of people and has thousands of downloads per month.
It runs on the Java Virtual Machine and fully interoperates with the Java environment.
It has been called the "next next Java".
It is the Scala Language.

I've recently started to learn and play with it and I have to say I'm really enjoying its features.
For those with very little Functional Programming background (as I am) it may have a steep learning curve and its language features may seem too vast, but don't let them discourage you!

First start with this excellent tutorial.

Then I suggest you to start learning the following features:
  • All about classes, singleton objects, abstract types and traits.
  • Mixins.
  • Type inference.
  • Infix and postfix operators.
  • XML processing.
These are in my opinion the most important and interesting object oriented capabilities of the Scala language.

Then go with its functional side:
  • All about functions.
  • For comprehension.
  • Case classes (still to learn).
  • Pattern matching (still to learn).
  • Views (still to learn).
  • ... (still to learn).
As you can see, I have still a lot of things to learn, but I think that just its object oriented and most basic functional features make Scala a great language and a great learning/programming experience!

What about some practical use cases?

Right now I see it very well suited for:
  • Creating Domain Specific Languages (DSL) to integrate in Java applications.
  • Producing XML documents starting from data expressed in objects or some kind of DSL.
Stay tuned.
More info and ideas about my experiences with the Scala language will come soon.

Friday, October 26, 2007

The Fail Fast Rule

Every time you're writing a piece of code and you have to deal with unknown corner cases ...
Every time you're implementing some kind of logic and you don't know what to do when things go bad ...
Every time you think: this can never happen, I don't have to check for it ...
Every time you don't know what to do or what would happen ...
Please ...

Fail fast.

This is the Fail Fast Rule, as I call it, a term borrowed from the Java Collections iterators behavior:

Every time your code might fail, and you don't know what to do, just make it fail abruptly.

That is: do not ignore it, do not (just) log it, but let your code throw an exception.

An example was how we computed a shopping cart total in one of my previous posts:

public class ShoppingCart {

private static final int MAX_TOTAL = 10000;

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
if (total > MAX_TOTAL) {
throw new SomeException();
}

}
return total;
}
}

As soon as the total gets too high, an exception is thrown. Probably this will change later, because we may want to handle it more gracefully, but in the meantime: make it fail.

Why?

Because if an exception will pop up in front of you, you'll have found a bug, a corner case, something that you have not still properly implemented or that you have not thought of.

So remember: make it good, or fail fast.

Tuesday, October 23, 2007

JavaMail and GMail : it's all about configuration

Yesterday I spent a couple of hours trying to send emails with JavaMail APIs via my GMail account.

It wasn't easy: the standard JavaMail configuration didn't work, while Google gave me a lot of wrong and/or outdated information.
Moreover, JavaMail FAQs provide a sample about sending emails via GMail, but it has some problems too.

So I think these bits of information will be helpful to someone trying to accomplish the same task ...

The problem is that GMail uses TLS and the STARTTLS command.
The solution applies to JavaMail 1.4 and JDK 1.4 or higher and is just a matter of configuration.

First, and obviously, enable POP support for your GMail account.

Then, put the following configuration in your properties file:

mail.transport.protocol=smtp

mail.smtp.host=smtp.gmail.com

mail.smtp.starttls.enable=true

mail.smtp.auth=true

mail.user=<your_username>

mail.password=<your_password>

The key point is the part in bold: enabling the STARTTLS command.
That's the tricky part.
Once created the properties file above, just configure your JavaMail Session object and send your mail message as you'd always do:


Properties props = ...; // <-- Your properties above

Authenticator authenticator = new YourAuthenticator(...);

Session session = Session.getInstance(props, authenticator);

Transport t = session.getTransport();

t.send(yourMail);


That's all.
Feel free to comment on for any question.
Enjoy it!

Friday, October 19, 2007

Avoid your getters and setters, Part 2

More than one year ago we've talked about how to avoid getters and setters by using the most fundamental object oriented programming principle: programming to an interface.

Well, it was just the beginning ...

I know we're a bit late, but let's go now with the second part of my
How to avoid getters and setters series ... I hope you'll enjoy it!

Avoid your getters and setters : The Expert, the Aggregate and the Value Object.

Many people use getters and setters so extensively because don't really get the importance of correctly assigning object responsibilities and behaviors.

So, in this second part we'll mix together GRASP and
Domain Driven Design patterns, in particular:
We'll see how wrongly managing responsibilities and behaviors, while abusing getters and setters, can lead to a corrupted business domain, and how the patterns above will help you to correctly address these kind of problems.

The business domain.

Let's start our discussion by showing a simple business domain.
We're implementing yet another ugly e-commerce system, so we have a shopping cart holding a number of orders, each refer
ring to a given product.
Without going further on, let's restrict our domain model to three simple entities: ShoppingCart, Order and Product.









A
ShoppingCart can hold one or more Orders, and an Order refers just to a single Product.
Moreover, we have some simple business rules regarding these entities:
  1. The ShoppingCart total is the sum of all Order sub-totals.
  2. Each Order sub-total is the Product price times the ordered Product quantity.
  3. The ShoppingCart total cannot exceed the value of EUR 10000.
Pay particular attention to the latest point: it is an invariant, a rule that must be always kept valid.

That's all.
Very simple, isn't it?

Let's implement it : the wrong way.

The entities and rules above can be straightforwardly implemented as follows:

public class Product {

private String name;

// ...

private double price;

// ...

public double getPrice() {
return this.price;
}

public void setPrice(double price) {
this.price = price;
}
}

public class Order {

private Product product;
private int quantity;

public Product getProduct() {
return this.product;
}

public void setProduct(Product p) {
this.product = p;
}

public int getQuantity() {
return this.quantity;
}

public void setQuantity(int q) {
this.quantity = q;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public List getOrders() {
return this.orders;
}
}
As you can see, all classes have the right properties and dependencies:
  1. A Product has a price.
  2. An Order refers a Product and has a product quantity.
  3. The ShoppingCart has more orders.
  4. The ShoppingCart total can be calculated by iterating all Orders and summing up each Product price times the ordered product quantity.
However, this design (and implementation) is seriously flawed:
  • There's no clear assignment of responsibilities and behaviors.
    • Hence, it is full of getters and setters.
      • Hence, there's no encapsulation.
        • Hence, all business logic is external.
          • Hence, it is easy to corrupt domain state and violate business rules.
How?

Given our design and implementation, the following code is absolutely legal:

Product p1 = new Product();
Product p2 = new Product();

p1.setPrice(1000);
p2.setPrice(2000);

Order o1 = new Order();
Order o2 = new Order();

o1.setProduct(p1);
o1.setQuantity(5);

o2.setProduct(p2);
o2.setQuantity(5);

ShoppingCart cart = new ShoppingCart();

cart.addOrder(o1);
cart.addOrder(o2);
But hey, wait!
The ShoppingCart total is now EUR 15000!
That's because the business logic is computed outside of the object that holds the information; so let's solve this problem by introducing the
Information Expert pattern.

Refactoring toward the Expert.

The Information Expert pattern is part of the
General Responsibility Assignment Software Patterns (GRASP), and states the following:
Assign a responsibility to the information expert: the class that has the information necessary to fulfill the responsibility.
We have two responsibilities to relocate:
  • The shopping cart total computation: here, the information expert is the ShoppingCart class.
  • The order sub-total computation: here, the information expert is the Order class.
By relocating the two responsibilities we'll improve our encapsulation and make our implementation more robust, because the ShoppingCart will be able to check that the total doesn't exceed EUR 10000.

public class Order {

private Product product;
private int quantity;

public void setProductWithQuantity(Product p, int q) {
this.product = p;
this.quantity = q;
}

public double computeSubTotal() {
return this.product.getPrice() * this.quantity;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
if (total > MAX_TOTAL) {
throw new SomeException();
}
}
return total;
}
}
As you can see, the ShoppingCart computeTotal() method is now able to check against the maximum total, and throw an exception if there's something wrong, avoiding domain state corruption.

However, there's still something wrong; take a look at the following code:

Product p1 = new Product();
Product p2 = new Product();

p1.setPrice(1000);
p2.setPrice(2000);

Order o1 = new Order();
Order o2 = new Order();

o1.setProductWithQuantity(p1, 2);
o2.setProductWithQuantity(p2, 4);

ShoppingCart cart = new ShoppingCart();

cart.addOrder(o1);
cart.addOrder(o2);

cart.computeTotal();

// !!!!!!!!! DANGER !!!!!!!!!!
o1.setProductWithQuantity(p1, 3);
// !!!!!!!!! DANGER !!!!!!!!!!
The problem is that we can always change the Order product and quantity, changing so the shopping cart total without preventing it to enter in an invalid state!

Where's the
real problem?
How to solve it?

Refactoring toward the Aggregate and the Value Object.

The real problem is that we are interested in keeping the ShoppingCart state always correct, that is, in keeping its invariants: however in the current design and implementation we are not able to control everything happens inside the ShoppingCart, because we can directly modify its Orders without going through it!

The solution is to apply the Aggregate and Value Object patterns, part of the
Domain Driven Design.

An Aggregate is a set of related objects whose invariants must always be kept consistent, and an Aggregate Root is an object that acts like the main access point into the aggregate; all access must go through the root, and objects external to the aggregate cannot keep references to objects contained into the aggregate: they can keep a reference only to the aggregate root.

A Value Object is an object that has no identity and is immutable: it is equal to another value object of the same type if its properties are equal too, and must be discarded if its properties need to change.

How to turn this theory into practice, applying it to our domain?

First, our ShoppingCart and Order are part of an aggregate.
It's easy: the "EUR 10000" invariant involves both objects, so it must be kept consistent across the two.
Moreover, Orders make sense only if related to a ShoppingCart, so no one should access an Order without first going through a ShoppingCart: this means that the ShoppingCart is the root of the aggregate.

Second, the Order is a Value Object: it doesn't make sense to create an order and change its related product and quantity during its life cycle; an order always refers to the same product with the same quantity, and if something needs to be changed, it must be discarded and a new one must be created.

Now let's refactor our previous code:


public class Order {

private Product product;
private int quantity;
private double subTotal;

public Order(Product p, int q) {
this.product = p;
this.quantity = q;
this.subTotal = this.product.getPrice() * this.quantity;
}

public double computeSubTotal() {
return this.subTotal;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public boolean removeOrder(Order o) {
return this.orders.remove(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
}
return total;
}
}

The Order class is now immutable and part of an aggregate together with the ShoppingCart.
The ShoppingCart is now the aggregate root, and every change to its Orders must go through it.

Now, you have no way of corrupting your domain.

Remember: the Expert, the Aggregate and the Value Object.
Who do you want to be?

Saturday, October 13, 2007

Alive

Hi all.

I'm not going to talk about the great Pearl Jam song.
I'm going to talk about me, because (very) long time has passed since my last post, and yes ... I'm still alive.

I don't want to bother you too much, just let me jumble a few bullet points about the most important things happened to me during these months:

  • I finished working at that big project for RAI, the Italian State Television, involving the design and development of its main portal. It was a very interesting experience and I think I'll write more about things I learned (because we always learn), in the future.
  • I became a committer of the Taconite Ajax Framework, improving my Javascript skills and working with CSS Selectors.
  • I've been at Spring One 2007 and it was nice, even if it didn't fulfill my high, maybe too high, expectations.
  • I bought a white MacBook and I'm really happy with it.
  • I've started working at (and I'm still doing) clustering a famous Open Source Enterprise product: I cannot say more right now, but I think more news will pop out soon.
  • Spring Modules approached the 0.8 release and will (hopefully?) soon approach the 0.9 one.
  • I've changed houses, and I'm really happy in the new one.
  • Radiohead released their new album, after about four years of silence ... and I suddenly bought it.
  • ... I've started blogging again ... seriously!
That's all.
Now let the thoughts flow again.
Now let the fragments burst in the air.

Sunday, January 21, 2007

Join Us: Be Commons-Logging Free!

Johannes invited his readers to revise their code in order to remove all dependencies on Jakarta Commons-Logging (JCL).

Why?
It is simple: JCL gives you a lot of class loading problems, often driving you mad.
If you've never had class loading problems while deploying your Simple Servlet / Complex JEE application which makes use of JCL, if you've never struggled for making JCL use that damn Log4j configuration file, you're surely one of the luckiest person in the world, so hurry up and go buying that lottery ticket!

That's way I always use, at least when possible, raw Log4j loggers.

However, thanks to Johannes I've discovered SLF4J: I gave it a try and in less then two minutes I've migrated my current project from JCL to it!
And what's most important : it rocks!

So, again: join us and be Commons-Logging free!

Tuesday, January 16, 2007

Five things you don't know about me

Some weeks ago I've been tagged by Daniele , but I'm very busy to do anything other than working at a big project for RAI .
So, now, let me start the new year with five things you don't know about me:

  • I used to practice martial arts: more specifically, Shorinji Kempo.
  • I used to play guitar in a Rock band called Voodoo Economics.
  • I used to write short novels, and I also won a prize.
  • I have very little spatial ability and I often lose my way (literally).
  • My nickname, Tourist, is related to the homonym Radiohead song: The Tourist.

This silly thing has to have an end ... so here it is!