C# Extension methods

Scott Hanselman has a post about a user who doesn’t get what is cool about Ruby.

In the post you can find the below example that compares Java and Ruby in terms of code readability.

The Java code:

new Date(new Date().getTime() - 20 * 60 * 1000)

The Ruby code:

20.minutes.ago

The article was interesting but what really caught my attention was some comments from C# programmers who showed how, in a few lines of code, you can mimic the Ruby syntax in C# using extension methods.

The new version of C#, shipped with the Orcas release of Visual Studio, has a new feature called extension methods. Extension methods were added to the .Net languages to support LINQ and they provide a way to attach methods to classes without changing their code.

The below code is copied and modified from the comments of Ian Cooper in the aforementioned blog post.

public static class TimeExtensions {
 
  public static TimeSpan Minutes(this int numberOfMinutes) {
    return new TimeSpan(0, numberOfMinutes, 0);
  }
 
  public static DateTime Ago(this TimeSpan numberOfMinutes) {
    return DateTime.Now.Subtract(numberOfMinutes);
  }
}

In the above code we defined a class, called TimeExtensions, which contains two extension methods. Notice the this keyword on the left of the fist parameter (both methods take one parameter in the example code) of the methods. The this keyword tells the C# compiler that a method is an extension method. The parameter annotated with the this keyword is the object on which the extension method is called. If I am correct, the methods are not really added to the classes (you can’t find them via reflection), the compiler at-compile-time translates them into static method calls.

In our example the first method, called Minutes, will be added to the int class (probably via auto-boxing) and the second method, called Ago, will be added to the TimeSpan class.

Now, to use the extension methods that we defined above we have to import them using the using TimeExtensions statement. This is a really good thing since the usage of extension methods is always explicit. You have to import them to use them and if you don’t want to use them you don’t import them.

using System;
using TimeExtensions;
 
public class HelloWorld {
  public static void Main() {
    Console.WriteLine( 20.Minutes().Ago() );
  }
}

20.Minutes().Ago() is pretty close to 20.minutes.ago :-)

For a nice tutorial about C# 3.0 extension methods see: New “Orcas” Language Feature: Extension Methods.

Making Maven 2 work with JUnit 4

The current stable version (2.2) of the maven-surefire-plugin does not support JUnit 4. So Maven, out of the box, does not work with JUnit 4. Luckily if we want to use JUnit 4 in our Maven based projects we have two choices. The first is to use JUnit4TestAdapter as illustrated in this post. The second is to use the snapshot version (2.3-SNAPSHOT) of the maven-surefire-plugin that has support for JUnit 4. In a small pet-project I am currently implementing I chose the second option and so far my experience was without any problems.

To use the 2.3-SNAPSHOT you first have to add the Maven snapshot plugin repository into your list of plugin repositories. In your pom.xml add the below XML:

<pluginRepositories>
  <pluginRepository>
    <id>apache.org</id>
    <name>Maven Plugin Snapshots</name>
    <url>http://people.apache.org/repo/m2-snapshot-repository</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </pluginRepository>
</pluginRepositories>

You can also put this configuration into your ~/.m2/settings.xml file to enable this repository for all your projects.

Then go to the maven-surefire-plugin configuration section and change the version from 2.2 to 2.3-SNAPSHOT. For example below I have the maven-surefire-plugin configuration that I use in my pet-project:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.3-SNAPSHOT</version>
  <configuration>
    <includes>
      <include>**/*Test.java</include>
    </includes>
    <forkMode>once</forkMode>        
  </configuration>          
</plugin>

That’s it, you are done. When you run Maven again the new (2.3-SNAPSHOT) version will be downloaded and you can start using JUnit 4 in you project.

Greek Java Champions

Panos and Paris, the JHUG’s JUG leaders, are now Java Champions.

Congrats guys, keep it up!

commons.testing

For me, this is the best April fool’s joke for this year.

Implementing Seam style @Logger injection with Spring

Seam provides a number of features to help programmers with the tedious but necessary logging. One of them is the @Logger annotation that is used to inject a Seam Log instance into a Seam component. For example instead of writing:

private Log log = LogFactory.getLog(MyClass.class);

you can write:

@Logger private Log log;

and Seam will inject an appropriate logger. Below we will try to to implement this feature using the Spring Framework for objects managed by the Spring DI container (actually a BeanFactory).

The Spring DI container provides a number of extension interfaces that beans can implement to get callbacks from the container in various stages of the container operation. One callback interface is the BeanPostProcessor. BeanPostProcessors are called before and after the initialization of each bean and allow the custom modification of bean instances (for example wrapping an instance with a dynamic proxy).

The only thing we have to do to implement the @Logger injection (besides defining a @Logger annotation) is to write a BeanPostProcessor that, before each bean gets initialized (right after it gets constructed), will iterate over the fields of the bean to detect any @Logger annotations and construct and inject a new logger instance.

Let’s define the annotation:

package com.tzavellas.spring.logger;
 
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
 
@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Logger { }

and now the BeanPostProcessor:

package com.tzavellas.spring.logger;
 
import java.lang.reflect.Field;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
 
import static org.springframework.util.ReflectionUtils.FieldCallback;
 
public class LoggerPostProcessor implements BeanPostProcessor {
 
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
  }
 
  public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
      public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
        if (field.getAnnotation(Logger.class) != null) {
          Log log = LogFactory.getLog(bean.getClass());
          field.set(bean, log);
        }
      }
    });
    return bean;
  }
}

Below I have a small JUnit test to verify that it works:

package com.tzavellas.spring.logger;
 
import static org.junit.Assert.*;
 
import org.apache.commons.logging.Log;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
 
public class LoggerPostProcessorTest {
 
  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
 
  @Before
  public void setupFactory() {
    RootBeanDefinition bean = new RootBeanDefinition(Bean.class, true);
    factory.addBeanPostProcessor(new LoggerPostProcessor());
    factory.registerBeanDefinition("bean", bean);
  }
 
  @Test
  public void injectLogger() {
    Bean b = (Bean) factory.getBean("bean");
    assertNotNull(b.log);
    b.doSomething();
  }
}
 
class Bean {
 
  @Logger Log log;
 
  public void doSomething() { log.debug("message"); }
}

This is a very simple implementation since the goal of this article is to demonstrate the extensibility of the Spring DI container and not to implement a complete solution. One limitation is that this implementation only injects loggers (actually commons-logging Logs) to public fields (Seam can inject Seam Logger to private fields).

To use the above in a Spring XML file you simply define a bean with class com.tzavellas.spring.logging.LoggerPostProcessor (the id/name is not needed). The BeanFactory/ApplicationContext will automatically detect all beans that implement the BeanPostProcessor interface at startup time and will initialize them and then call them every time a bean gets initialized.