Tuesday, September 13, 2011

Extensible Factory Method implementation

One of my favourite design pattern is the Factory Method. The design pattern encapsulates object creation, i.e. the factory method decides which implementation you'll get. I often use a slightly different version of the pattern, which returns a specific implementation of an interface based on a name parameter. The supported names are defined as static constants in the factory class. This way, I decouple the actual implementation from its user. The only link to the actual implementation is the name constant.

The implementation I use has several problems. Everytime I add a new manufacturable class, I have to change the factory class by adding a new name constant to identify the new manufacturable. And I have to add nearly the same code to actually instantiate and return the new type by the factory, which violates the DRY-principle. This also makes the factory tightly coupled to the new type, which I want to avoid if possible.

Another problem I had in the past was that I use to same code in every Singleton class (Factory Methods are often Singletons). I solved this by using a Dependency Injection Framework like Google Guice or Spring. It's possible to mark singleton classes using these frameworks by annotations or configuration. The frameworks will then make sure that the marked classes are singletons during execution.

So, I felt a need to improve my implementation of the factory methods. I wanted the following properties for my factory methods:

  1. It should be easy to create new factories, without much (duplicate) code.
  2. It should be easy to add new manufacturables, without changing code in the factory class.

The result is the implementation I'll describe next. Before we go to the actual implementation, let's create an interface for the manufacturable classes, and two example implementation of the manufacturable classes.

The manufacturable interface:

package com.javaeenotes;

public interface MyManufacturable {
  public String getName();
}

Two implementations of the manufacturable interface:

package com.javaeenotes;

public class MyManufacturableAImpl implements MyManufacturable {

  @Override
  public String getName() {
    return getClass().getSimpleName();
  }
}
package com.javaeenotes;

public class MyManufacturableBImpl implements MyManufacturable {

  @Override
  public String getName() {
    return getClass().getSimpleName();
  }
}

The abstract factory method class:

package com.javaeenotes;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public abstract class AbstractFactory<T> {

  private static final String CONFIG_FILE_EXTENSION = ".conf";

  private final String factoryName;
  private final Map<String, Class<? extends T>> manufacturableClasses;

  public AbstractFactory(String name) {

    this.factoryName = name;
    this.manufacturableClasses = new HashMap<String, Class<? extends T>>();

    try {
      loadClasses();
    } catch (IOException ioException) {
      throw new IllegalArgumentException(
              "Error reading factory configuration file.",
              ioException);
    } catch (ClassNotFoundException classNotFoundException) {
      throw new IllegalStateException(
              "Could not find class for name in factory configuration file.",
              classNotFoundException);
    }
  }

  @SuppressWarnings("unchecked")
  private void loadClasses() throws IOException, ClassNotFoundException {

    BufferedReader configReader = null;

    try {
      configReader = new BufferedReader(new InputStreamReader(getClass()
              .getResourceAsStream(factoryName + CONFIG_FILE_EXTENSION)));

      String className;

      while ((className = configReader.readLine()) != null) {
        manufacturableClasses.put(
                className,
                (Class<? extends T>) Class.forName(className));
      }
    } finally {
      if (configReader != null) {
        configReader.close();
      }
    }
  }

  public Set<String> getNamesManufacturables() {
    return manufacturableClasses.keySet();
  }

  public T getInstance(String nameManufacturable)
        throws InstantiationException, IllegalAccessException {

    return manufacturableClasses.get(nameManufacturable).newInstance();
  }
}

The factory method class contains no hard references to our manufacturable implementation classes. Hey, there's even no reference to our manufacturable interface, because we use generics!

The factory is designed as a generic abstract class, which should be extended by every factory method class in the application. The manufacturables are defined in a configuration file in the class path, which has the same name as the factory. The configuration file has a .conf file extension, and should contain the fully qualified names of the manufacturable classes. Upon factory instantiation, the configuration file is read, and all supporting manufacturable classes are loaded.

Here is the example factory:

package com.javaeenotes;

public class MyFactory extends AbstractFactory<MyManufacturable> {

  private static final String name = "MyFactory";

  public MyFactory() {
    super(name);
  }
}

The factory configuration file we use to support our manufacturable classes (MyFactory.conf):

com.javaeenotes.MyManufacturableAImpl
com.javaeenotes.MyManufacturableBImpl
We can use the following main class, which prints the names of the manufacturables, as demonstration:
package com.javaeenotes;

public class Main {

  public void run() {

    MyFactory factory = new MyFactory();

    for (String name : factory.getNamesManufacturables()) {
      try {
        MyManufacturable myManufacturable = factory.getInstance(name);
        System.out.println(myManufacturable.getName());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) {
    new Main().run();
  }
}

Conclusion

The factory method class implementation makes adding new factories very simple. Every factory class just has to extend the abstract factory class, and call its constructor with the name of the factory. The whole factory class consists of just several lines!

Registering new manufacturable classes to the factory is also much easier. Just add the fully qualified name of the new class to the factory configuration file, and we're done!

This concludes this post. If you have any improvements, please don't hesitate to share them in the comments.

Friday, September 9, 2011

Inject instances in Quartz jobs with Google Guice

This post explains how to use Quartz 2 with Google Guice. Before you read any further, I assume you have some basic understanding about Guice and Quartz 2, and what problems they solve.

Normally, Quartz will instantiate job classes itself. You only need to supply the job class, so Quartz knows which class to instantiate when a job is ready to be executed. The job itself is pretty hidden (encapsulated) by Quartz.

In some cases, you want to let Google Guice inject references of (singleton) objects to the job. Such as a Data Access Object, so the job can access or store data.

The solution is to supply our own job factory to the Quartz class that is responsible for job instantiation. Our factory will use Guice to create instances for Quartz to use.

package com.javaeenotes.guicequartz;

import org.quartz.Job;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;

import com.google.inject.Inject;
import com.google.inject.Injector;

public class MyJobFactory implements JobFactory {

    @Inject
    private Injector injector;


    @Override
    public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler)
            throws SchedulerException {

        return (Job) injector.getInstance(
            bundle.getJobDetail().getJobClass());
    }
}
To complete this example, we need an example DAO class, and a Quartz job class that will hold the injected DAO object.
package com.javaeenotes;

public interface Dao {
    public abstract String getData();
}
package com.javaeenotes;

import com.google.inject.Singleton;

@Singleton
public class DaoImpl implements Dao {

  @Override
  public String getData() {
    return "Data from DAO.";
  }
}
package com.javaeenotes;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.google.inject.Inject;

public class MyJob implements Job {

  @Inject
  private Dao dao;


  @Override
  public void execute(JobExecutionContext context)
        throws JobExecutionException {

    System.out.println(dao.getData());
  }
}
Now, we need a Guice module that defines and maps the factory and DAO classes.
package com.javaeenotes;

import org.quartz.spi.JobFactory;
import com.google.inject.AbstractModule;

public class MyModule extends AbstractModule {

  @Override
  protected void configure() {

    bind(JobFactory.class).to(MyJobFactory.class);
    bind(Dao.class).to(DaoImpl.class);
  }
}
Finally, a Main class to demonstrate the application:
package com.javaeenotes;

import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;

import com.google.inject.Guice;
import com.google.inject.Injector;

public class Main {

  public void run() {

    // The Guice injector used to create instances.
    Injector injector = Guice.createInjector(new MyModule());

    // Object that contains the job class.
    JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
            .withIdentity("jobId", "jobGroup").build();

    // Create the trigger that will instantiate and execute the job.
    // Execute the job with a 3 seconds interval.
    Trigger trigger = TriggerBuilder
            .newTrigger()
            .withIdentity("triggerId")
            .withSchedule(
                    SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(3).repeatForever())
            .build();

    try {
      // Retrieve the Quartz scheduler to schedule the job.
      SchedulerFactory schedulerFactory = new StdSchedulerFactory();
      Scheduler scheduler = schedulerFactory.getScheduler();

      // Here we tell the Quartz scheduler to use our factory.
      scheduler.setJobFactory(injector.getInstance(MyJobFactory.class));
      scheduler.scheduleJob(jobDetail, trigger);

      // Start the scheduler.
      scheduler.start();
    } catch (SchedulerException e) {
      e.printStackTrace();
    }

    try {
      Thread.sleep(10000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }


  public static void main(String[] args) {
    new Main().run();
  }
}
This will output the following every 3 seconds:
Data from DAO.

Installation of Quartz 2 and Google Guice

If you use Maven 2 for your project, you can install both frameworks by simply adding the following configuration to your pom.xml file.

  org.quartz-scheduler
  quartz
  2.0.2



  com.google.inject
  guice
  3.0

Thursday, September 8, 2011

Kick-start Quartz 2 Tutorial

Quartz is a job scheduling framework, which provides a powerful way of executing and controlling scheduled jobs. This tutorial is based on the official tutorial on the main website of Quartz. The goal of this tutorial is to get a kick-start in using Quartz. Most details are left out. The example is designed to be easy to follow. The example consists of three classes:
  • Main: instantiates, and initiates Quartz classes
  • JobTask: the actual job definition
  • JobTaskListener: a listener class that monitors the execution of the job
Let's get right into the code. The first code fragment represents the state of a job. Job classes that Quartz uses are stateless. So we are forced to use the Memento design pattern to externalize state. This class should be serializable to prevent problems when we use Quartz to persist job states in the future. The state is meant to be accessed by the main thread and Quartz, so make sure it's thread-safe.
package com.javaeenotes;

import java.io.Serializable;

public class JobContext implements Serializable {

  private static final long serialVersionUID = 1L;

  private String state = "Initial state.";


  public String getState() {
    synchronized (state) {
       return state;
    }
  }


  public void setState(String state) {
    synchronized (state) {
      this.state = state;
    }
  }
}
The next code is the job definition class, which implements the method called by the Quartz scheduler. It's recommended to wrap the whole body of the method in a try-block in order to catch any exceptions that might occur. Wrap the exception in the checked JobExecutionException before throwing it. The main thread can deal with the exception later.
package com.javaeenotes;

import java.util.Date;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

// Disallow running multiple jobs based on this class at the same time.
@DisallowConcurrentExecution
public class JobTask implements Job {

  @Override
  public void execute(JobExecutionContext executionContext)
          throws JobExecutionException {

    // It's a good idea to wrap the entire body in a try-block, in order to
    // catch every exception thrown.
    try {
      // Retrieve the state object.
      JobContext jobContext = (JobContext) executionContext
            .getJobDetail().getJobDataMap().get("jobContext");

      // Update state.
      jobContext.setState(new Date().toString());

      // This is just a simulation of something going wrong.
     int number = 0;
     number = 123 / number;
    } catch (Exception e) {
      throw new JobExecutionException(e);
    }
  }
}
The next class is responsible for monitoring the job. It's also responsible for dealing with exceptions thrown by the job.
package com.javaeenotes;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;

public class JobTaskListener implements JobListener {

  public static final String TRIGGER_NAME = "Trigger";

  @Override
  public String getName() {

    return TRIGGER_NAME;
  }

  @Override
  public void jobToBeExecuted(JobExecutionContext context) {

    System.out.println("Job is going to be executed: "
            + context.getJobDetail().getKey().toString());
  }

  @Override
  public void jobExecutionVetoed(JobExecutionContext context) {

    System.out.println("Job is vetoed by trigger: "
            + context.getJobDetail().getKey().toString());
  }

  @Override
  public void jobWasExecuted(
        JobExecutionContext context,
        JobExecutionException jobException) {

    System.out.println("Exception thrown by: "
            + context.getJobDetail().getKey().toString()
            + " Exception: "
            + jobException.getMessage());
  }
}
Now, we can use these classes to see how it runs. We use the Main-class for this purpose.
package com.javaeenotes;

import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.KeyMatcher;

public class Main {

  @SuppressWarnings("unchecked")
  public void run() {

    // The state of the job.
    JobContext jobContext = new JobContext();

    // The value or transfer object provided by Quartz that contains the
    // state of the job. Save it in JobDetail or Trigger.
    JobDataMap jobDataMap = new JobDataMap();
    jobDataMap.put("jobContext", jobContext);

    // Create an identifier for the job.
    JobKey jobKey = new JobKey("jobId", "jobGroup");

    // Object that contains the job class and transfer object.
    JobDetail jobDetail = JobBuilder.newJob(JobTask.class)
            .withIdentity(jobKey).usingJobData(jobDataMap).build();

    // Create the trigger that will instantiate and execute the job.
    // Execute the job with a 5 seconds interval.
    Trigger trigger = TriggerBuilder
            .newTrigger()
            .withIdentity("triggerId")
            .withSchedule(
                    SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(5).repeatForever())
            .build();

    // Setup a listener for the job.
    JobListener jobListener = new JobTaskListener();

    // Use the Quartz scheduler to schedule the job.
    try {
      SchedulerFactory schedulerFactory = new StdSchedulerFactory();
      Scheduler scheduler = schedulerFactory.getScheduler();
      scheduler.scheduleJob(jobDetail, trigger);

      // Tell scheduler to listen for jobs with a particular key.
      scheduler.getListenerManager().addJobListener(
              jobListener,
              KeyMatcher.keyEquals(jobKey));

      // Start the scheduler after 5 seconds.
      scheduler.startDelayed(5);
    } catch (SchedulerException e) {
      e.printStackTrace();
    }

    // Print the job state with a 3 seconds interval.
    while (true) {
      try {
        System.out.println(jobContext.getState());
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

  public static void main(String[] args) {
    new Main().run();
  }
}

The first thing we do is to create the state object, and wrap it in the transfer or value object provided by Quartz. The reason we do this, is because Quartz doesn't let us instantiate the job class ourselves.

The next step is to define and instantiate a JobKey object, which acts as the identifier for our job. This is also used together with the listener to tell the scheduler which jobs we want to monitor.

Then we create a JobDetail object, which contains details of the job. A trigger object is also needed to tell the scheduler when we want our job to be run. This provides a nice separation of the job and run schedule. Using multiple triggers we can run the same job at different times.

Next, we instantiate the listener class.

Finally, we retrieve an instance of the Quartz scheduler to schedule the job with the trigger. The listener class is also added, together with a matcher based on the job identifier. This way, the scheduler knows which jobs the listener is listening to. The scheduler is then started with a delay of 5 seconds.

The resulting output, when we run the Main class:
Initial state.
Initial state.
Job is going to be executed: jobGroup.jobId
Exception thrown by: jobGroup.jobId
    Exception: java.lang.ArithmeticException: / by zero
Job is going to be executed: jobGroup.jobId
Exception thrown by: jobGroup.jobId
    Exception: java.lang.ArithmeticException: / by zero
Thu Sep 08 18:07:03 CEST 2011
Thu Sep 08 18:07:03 CEST 2011
Job is going to be executed: jobGroup.jobId
Exception thrown by: jobGroup.jobId
    Exception: java.lang.ArithmeticException: / by zero

Quartz installation for Maven 2

To add Quartz to a Maven 2 project, just add the following code to your pom.xml file.

  org.quartz-scheduler
  quartz
  2.0.2

Friday, August 26, 2011

A stoppable Thread in Java

I am currently working on an application that has multiple different threads running. The threads are running loops and cannot be stopped using interrupts, because a clean up method has to run after the thread stops. Because I don't want to implement the same code for all these thread classes, I created an abstract subclass of the Thread class. The new class provides the following new functionality to its subclasses:
  1. Automatically call start up method when started
  2. Automatically call a method in an endless loop
  3. A way to stop the thread
  4. Automatically call clean up method when stopped
The implemenation of this abstract class:
package com.javaeenotes;

public abstract class AbstractStoppableThread extends Thread {

    private volatile boolean stopThread = false;

    @Override
    public final void run() {
        startUp();

        while (!stopThread) {
            runInLoop();
        }
        cleanUp();
    }

    public void stopThread() {
        stopThread = true;
    }

    protected void startUp() {
        ;
    }

    protected abstract void runInLoop();

    protected void cleanUp() {
        ;
    }
}
A subclass of this class has to provide the actual overriding implementations of the last three methods. A class that demonstrates the use of the abstract class is shown next:
package com.javaeenotes;

public class ExampleThread extends AbstractStoppableThread {

    @Override
    protected void startUp() {
        System.out.println("Thread started!");
    }

    @Override
    protected void runInLoop() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            ;
        }

        System.out.println("Running in a loop!");
    }

    @Override
    protected void cleanUp() {
        System.out.println("Cleaning up resources!");
    }

    public static void main(String[] args) {
        ExampleThread exampleThread = new ExampleThread();
        exampleThread.start();

        try {
            Thread.sleep(10000);
            exampleThread.stopThread();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
When the example is class is run, the program will output the following:
Thread started!
Running in a loop!
Running in a loop!
Running in a loop!
Running in a loop!
Running in a loop!
Cleaning up resources!
Other interesting links about stopping threads:

Saturday, July 16, 2011

Some tips for application logging in Java

Some tips for application logging in Java

In this blog post I want to share some of my thoughts about application logging in Java. Hopefully, you'd find them useful!

1. Consistent use of logging levels

Have a good understanding of the available log levels, and make sure you use them consistently throughout the application. Especially, if you're using the old JDK 1.4 Logger framework. What is the difference between FINER and FINEST?

Below is an abstract list of common log levels and a description of when to use them. This list is based on the Log4J log levels, but can be mapped to other logging frameworks.

FATAL
Unrecoverable errors. Leads to termination of the process (or a crash). Example: the application is in a corrupt state, and has no clue how to restore state.

ERROR
Errors that are not recoverable, but application can continue running. Example: an user request could not be executed, because some inputs are missing or invalid.

WARN
Undesirable or unexpected situations, but not necessarily "wrong". Example: the application expects a value in the cache, but could not find it. The application attempts to get the value in another way. Or a network connection is broken. The application tries to recover by reconnecting.

INFO
Important but normal run time events useful for monitoring. Example: a business process is finished.

DEBUG
Detailed information useful for debugging the system. Example: the content of a variable is printed in strategic locations of the application.

TRACE
Detailed control flow information. Example: a method is called message.

Below is a mapping of log levels of different logging frameworks. Levels that have the same level of severities are placed on the same row.









Carbon Severity EnumCommons LogLog4JJDK 1.4 LoggerLogKit
FATALFATALFATALSEVEREFATAL_ERROR
ERRORERRORERRORSEVEREERROR
WARNWARNWARNWARNINGWARN
INFOINFOINFOINFOINFO
DEBUGDEBUGDEBUGFINEDEBUG
DEBUGDEBUGDEBUGFINERDEBUG
TRACETRACEDEBUGFINESTDEBUG


2. Proper error logging

Error logging should not be done at the location where an exception is thrown, but at the location where the exception is handled to prevent double logging.

public void doSomething() throws ACheckedException {
if (someErrorCondition) {
String errorMessage = "Hey, some error occurred.";
logger.error(errorMessage);
throw new ACheckedException(errorMessage);
}
}

public void callerMethod() {
try {
doSomething();
} catch (ACheckedException exception) {
logger.error(exception.getMessage());
doSomethingElse();
}
}

The code above will log the same error twice. The log statement in the first method can be removed. Exceptions should "bubble up" to the method of the class that can handle the error, and then be logged. In most cases this class will play the controller role in a MVC style application.

3. Prevent unnecessary string concatenations

SLF4J is considered by many the best Java application logging framework. It's a logging facade that masks existing logging frameworks, which can be determined at deployment time. A great feature is that SLF4J allows you to avoid unnecessary string concatenation, which is really expensive.

logger.error("The error '" + errorMessage +
"' occurred in the " +
component.getName() + " component.");

Of course, you can use logging guards like this:

if (logger.isEnabledFor(Level.ERROR) {
logger.error("The error '" + errorMessage +
"' occurred in the " +
component.getName() + " component.");
}

But this will clutter your code, and degrades code readability.

The SLF4J way looks like this:

log.error("The error '{}' occurred in the {} component.",
errorMessage, component.getName());

As you can see, the use of SLF4J makes the logging statement more readable, and SLF4J will not compile the log message when the message will not be logged (i.e. not running in a high enough log level).

4. Use complete logging messages

Read logs, and check that the information in the log messages is complete, and can be used to reverse engineer back to the original state of the system.

01/02/2011 ERROR The user has a missing property.

The log message above could be improved by adding: the identifier for the user, and the name of the property, so it's easier to understand (and recreate) the situation that caused the log message. Another improvement is to add a message that gives information about what will happen next.

If you also have tips or views about application logging in Java, please don't hesitate to share them in the comments!

Wednesday, July 6, 2011

Restarting a Java application programmatically

I found an interesting article through DZone (excellent site) about how to start a Java application programmatically. The original article can be found on the blog of Leo Lewis. Restarting a Java application is pretty useful for certain applications, where you don't have direct access to the deployment environment.

Here is the orginal link to the article:
http://leolewis.website.org/wordpress/?p=499

Friday, July 1, 2011

Mocking classes with JMock

Normally, you'll get the following exception when you try to mock a class with jMock:

java.lang.IllegalArgumentException:
com.javaeenotes.YourClass is not an interface.

The solution is to use the ClassImposteriser when instantiating the Mockery class.

context = new Mockery() {
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};

Now you can mock any class, just as interfaces. The complete instructions can be found on this web page.