Friday, 17 June 2011

Why should we use dependency injection?

In this article we will explore some of the benefits of dependency injection and how this can be used in all types of programming, including small and simple programs. Some of the example shown below make use of Guice, a dependency injection framework by Google. The same concept applies for any other dependency injection framework.

This article does not provide detailed description of Guice but it only focus on the benefits of dependency injection and design methods that improve modularity, extendibility and testing.

What is dependency injection?

Let say we want to make some tea. How would we do it and what do we need? We need to boil some water, a clean mug, tea bags, sugar and milk (at least that's what I put into mine). In order to make tea we need to provide all these ingredients and we need to manage all these ourselves. We have to fill the kettle with water and heat it up, get the milk from the refrigerator and get the rest.

Now assume that we can make tea, by simply asking someone else to do it for us. Someone that knows how to do the tea just the way we want it. Would that be better than making the tea ourselves? If yes, then welcome to dependency injection.

Dependency injection is a framework that takes care of creating objects for us without we having to worry about providing the right ingredients so to say.

A Simple Example

Let say we have a class, Person, and this class needs to send a message. The Person class requires the aid of some other class, Email, in order to send a message. Following is a simple way of doing this.

public class Email {
  public void sendEmail(String subject, String message){
  }
}

public class Person {
  private Email email = new Email();

  public void greetFriend(){
    email.sendEmail(parameters...);
  }
}

Some code is omitted from the above classes for brevity

We all agree that this is a very simple and straight forward example that involves two simple Java classes. Nevertheless, the above has some limitations as listed below.

  • The Persons class is dependent (has a strong/tight dependency) on the Email class. There is a hard connection between these two classes. Let say we have a new better version of email class, FastEmail, in order for us to use it, we need to go in each and every class that depends on the Email class, such as the Person class, replace it with the new version.
  • Let say we parametrise the Email's constructor. Again we have to go in each and every class that is initialising the Email class, such as the Person class, and change it.
  • A design decision is taken to make the Email class singleton. Similar to above we need to modify all instances where it is used.
  • In order to improve the notifications/messages system, we decide to add different message delivery systems such as SMS or tweets. The Person class and other like it, need to all be modified in order for it to use the new classes.
  • Another developer needs to use the Person class, but would like to use a different notification/message system. This cannot be achieved with the current version of the Person class as it is hardwired to the Email class. What generally happens is that the other developer duplicates the Person class and modifies it as he/she needs. The projects ends up with two versions of the Person class.
  • In the above points we mentioned many scenarios where code has to be changed. All changes made, need to and should be tested. How can we test the Person class without including the message delivery class such as the Email? Testing, in many cases, is left as an afterthought. The way we have the Person class constructed makes it hard to test it without involving the Email class. Furthermore, how would we automate such test? How can we use JUnit or the like to automate out tests?
  • Moving forward in the project, the Person class starts to depend on another class that allow this object to write a letter using the Pen class for example. The Person class can use other ways to write a letter, such as Pencil class or Typewriter class, but this approach does not allow that.

These limitations can be improved by changing the way we think and restructure our code in a modular way. This is independent from dependency injection as we will see in the following section.

Change the way we think

The Email class provides a service, that is, sending of messages over the Internet using the mail protocol. Instead of having the Person class initialising an instance of the Email class, we first create an interface, MessageService, and make the Person class using this interface instead. This removed the dependency that the Person class has on the Email and replaces it with an abstract message delivery interface.

The following three steps: define, implement and use, show how we can develop modular and extendable code. This approach also improves testing as we will see at the end of this article.

  1. Define Interfaces

    Many developers do not use interfaces as they see them as additional non-required code. This may be true (I said maybe as the System class makes use of interfaces) for the famous hello world program, definitely not true for the rest. Like with everything else, we have to see things in context and there will be cases when we can do without interfaces. Nevertheless, developing code using interfaces produce far more modular and extendable code as illustrated in the following examples. The example discussed in the previous section was quite simple, but nevertheless it included several pitfalls which can be easily avoided. Changing code at a later stage involves more work than having it right in the first place.

    We start by defining the MessageService interface that includes one method, sendMessage(String subject, String message). For simplicity we assume that no exceptions are thrown.

    public interface MessageService {
      void sendMessage(String subject, String message);
    }
    
  2. Implement Interfaces

    In the list of limitations we mentioned four possible methods of sending a message: email, fast email, SMS and tweet. Let's create four classes that handle each message delivery method and have all these classes implement the interface created above.

    public class EmailService implements MessageService {
      @Override
      public void sendMessage(String subject, String message){
        System.out.printf("Email: %s, %s%n ", subject, message);
      }
    }
    
    public class FastEmailService implements MessageService {
      @Override
      public void sendMessage(String subject, String message){
        System.out.printf("Fast Email: %s, %s%n ", subject, message);
      }
    }
    
    public class SMSService implements MessageService {
      @Override
      public void sendMessage(String subject, String message){
        System.out.printf("SMS: %s, %s%n ", subject, message);
      }
    }
    
    public class TweetService implements MessageService {
      @Override
      public void sendMessage(String subject, String message){
        System.out.printf("Tweet: %s, %s%n", subject, message);
      }
    }
    
  3. Use Interfaces

    Finally, instead of using classes, we use interfaces. In the Person class, we replace the Email field with the MessageService service interface as shown in red below.

    public class Person {
      private MessageService messageService;
    
      public Person(MessageService messageService){
        this.messageService = messageService;
      }
    
      public void greetFriend(){
        messageService.sendMessage(parameters...);
      }
    }
    

    Note that the Person class is not initialising the message service but it is expecting it as a parameter of its constructor. This is a key element in the design. It improves modularity, extendibility and testing. The Person class is not dependent on any implementation, but on a service defined by an interface. This means that we can use the Person class without having to worry about the underlying implementation. Furthermore, different Person instance can be instantiated using different message services.

One can argue that the new version of Person class became more complex to instantiate as it requires parameters. This is a fair statement and here is when dependency injection comes into play.

Using Dependency Injection

As mentioned in the introduction, dependency injection can help us initialising objects and provide these objects all the necessary resources (ingredients). For example, the Person class requires an instance of MessageService. The dependency injection framework will provide that for us. So to create an instance of Person, all we need to do is call something like: dependecyFramework.getInstance(Person.class). Magically, (not really), the dependency injection framework will create an instance of the Person class and provide an instance of the a MessageService to the Person object.

The next natural question will be, how does the dependency injection framework knows how to initialise the MessageService? We need to tell the dependency injection framework how to create an instance of MessageService. With Google Guice we do that by creating a module (extends AbstractModule ) as illustrated below:

public class ProjectModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(MessageService.class).to(EmailService.class);
  }
}

Here we are telling the dependency injection how to create an instance of the MessageService class. We also need to add an annotation to the Person class in order to allow the dependency injection framework to inject the necessary parameters.

public class Person {
  private MessageService messageService;

  @Inject
  public Person(MessageService messageService){
    this.messageService = messageService;
  }

  public void greetFriend(){
    messageService.sendMessage(parameters...);
  }
}

With everything set, we create an instance of the Person class using the dependency injection framework

  Injector injector = Guice.createInjector(new ProjectModule());
  Person person = injector.getInstance(Person.class);
  person.greetFriend();

We replaced a couple of lines of code with many others. What's the buzz about this? In the next section we will see some of the benefits of dependency injection and how this can be used to simplify our coding life

Benefits of Dependency Injection

In this section we will see some key benefits of dependency injection

  • Changing the message service

    Let's change the delivery method from email to SMS. How would we do that?

    We only need to change the ProjectModule class to map the MessageService class to the SmsService class as shown in red below.

    public class ProjectModule extends AbstractModule {
    
      @Override
      protected void configure() {
        bind(MessageService.class).to(SmsService.class);
      }
    }
    

    This one change will affect all classes initialised with the dependency injection framework without having to change any of these classes. This leads us to another advantage, testing.

  • Changing the message service

    We can create a MockService class which can be using in JUnit test as shown next.

    public class MockService implements MessageService {
    
      public String subject;
      public String message;
    
      @Override
      public void sendMessage(String subject, String message) {
        this.subject = subject;
        this.message = message;
      }
    
    }
    

    The above mock message service simply stores the parameters into two public fields. These fields can be used to retrieve the values of the parameters and used for testing ass illustrated next.

    public class TestPerson {
    
      private Injector injector;
    
      @Before
      public void init() {
        injector = Guice.createInjector(new AbstractModule() {
          @Override
          protected void configure() {
            bind(MockMessageService.class).in(Singleton.class);
            bind(MessageService.class).to(MockService.class);
          }
        });
      }
    
      @Test
      public void testGreetFriend() {
        Person person = injector.getInstance(Person.class);
        person.greetFriend();
    
        MockService mockService = injector
            .getInstance(MockService.class);
        assertEquals("Greet", mockService.subject);
        assertEquals("Hello my friend", mockService.message);
      }
    }
    

    This may require some explanation. So here we go. We created an injection (Guice dependency injection) just for this testing and provided a custom module (as an abstract inner anonymous class). The custom module wires the MessageService with the MockService instead. Also, we set the MockService as singleton, that is, whenever we request an instance of this class from the injection we always get the same object (singleton). After greetFriend() is invoked, we test using JUnit to make sure that the correct parameters are being passed to the message service instance.

    This design setup allows us to test the Person class independent from the other classes that it depends on in an automated manner.

  • Changing the signature of the Person constructor

    As we mentioned in the limitations, the Person class may evolve and include more functionality. Changing the signature of the Person constructor will not affect us as long as the injector knows how to provide the required parameters.

    public class Person {
      @Inject
      public Person(MessageService messageService, 
                    WritingService writingService){
      }
    }
    

    The Person class will still be initialised in the same way as it is now. Thus changing the Person constructor signature will not affect the other classes that make us of it.

        Person person = injector.getInstance(Person.class);
    

    The same applies for anything that is initialised and handled through the injector.

  • Passing the Injector as parameter

    In a project we can have one instance shared throughout the project. This can be achieved by passing the Injector as a parameter to other objects that needs it. We setup the injector at the beginning (in a main method for example), and then have it set as a constructor parameter in all the classes that require an instance of the injector. Like that one injector will server all classes in the project.

Conclusion

This ended up to be quite a long article. Dependency injection is quite simple to use and it has quite a "shallow" learning curve. This article does not explain how to use the actual dependency injection framework (such as Guice). Articles about that are easily found. This article described key benefits of using a dependency injection framework even in small projects.

Saturday, 11 June 2011

OutOfMemoryError when reading large volumes of records from MySQL

When loading a large number of records from MySQL, an out of memory error (exception) may be thrown by the MyQSL connector. The connector reads all the data in memory (buffering) before it returns the result set. This may not be the case for other JDBC providers.

The follow code fragment will fail on the third line (shown in red) when invoking the executeQuery() method if the memory required to load the whole result is larger than the allocated heap size.

Statement statement = connection.createStatement();
ResultSet resultSet = 
    statement.executeQuery("SELECT * FROM `large_table`");
while(resultSet.next()){
}

One possible solution is to increase the heap size but this may not be required, especially if you are accessing small parts from the result set at one time. Increasing the heap size will only allow the program to consumes more resources that it actually requires.

The MYSQL statement interface (com.mysql.jdbc.Statement) provides a method called enableStreamingResults() which enables streaming over buffering, (as shown in red in the following code fragment).

Statement statement = connection.createStatement();
// This prevents the MYSQL connector from loading all the 
// results into memory
((com.mysql.jdbc.Statement) statement).enableStreamingResults();
ResultSet resultSet = 
    statement.executeQuery("SELECT * FROM `large_table`");
while(resultSet.next()){
}

This allows the code to read from a large table without consuming a large amount of memory.

Friday, 9 July 2010

In line images

Many web sites include small images and icons in tool bars and menus. These images are downloaded one by one by the browser while the page is downloaded. In many cases, the establishing of connection is more expensive in terms of time and traffic than the actual image. By converting these images to base64 encoding text, the browser can download the page content and the images at one go. Here’s is the code of how to convert an image into a base64 string.

public static String convertToInLineImage(
    byte[] image, String type) {
// Convert a byte array to base64 string
char[] chars = new sun.misc.BASE64Encoder().
                    encode(image).toCharArray();
StringBuilder builder = new StringBuilder();
for (char c : chars) {
 switch (c) {
   case '\n':
   case '\r':
   continue;
 default:
   builder.append(c);
 }
}

return "data:" + type + ";base64," + builder.toString();
}

The above method simple converts an image from bytes into string. The string returned by this method should be placed within the image HTML style.

style="width:50px;
      height:50px;
      background:url('the-base64-string-here')
          no-repeat scroll 0px 0px transparent;"

Monday, 28 December 2009

Upgrade to GWT 2

To upgrade the Eclipse Plugin to GWT 2, is an easy process. Unfortunately GWT is installed with the default name, GWT, GWT (1), GWT (2) and so on, for any different release. Ideally, the name used is a meaning full one, such as GWT 1.7.1 and GWT 2.0.0.

In this short article we discuss who to rename an existing GWT Eclipse Plugin and install GWT 2

Rename the existing GWT Eclipse Plugin

This step is optional.

By default, the GWT Eclipse plugin is installed with the name GWT as shown in the following figure. This can be misleading especially if you have multiple versions installed. Unfortunately, the name cannot be changed once installed. The only way to rename it is to remove it and then add it again with the proper name.

To rename the GWT Eclipse Plugin, please follow the steps below:

  1. From the menu, open Window > Preferences
  2. Expand the Google node and select the Web Toolkit

    As you can notice, the name set to GWT.
  3. Select it and click the Remove button
  4. Once removed, click the Add button
  5. A dialog will open. Click the Browse button to locate the current GWT Eclipse plugin

  6. Browse to the GWT Eclipse plugin folder. This is usually found at: C:\Program Files\Eclipse\eclipse-jee-galileo-SR1-win32\plugins\com.google.gwt.eclipse.sdkbundle.win32_1.7.1.v200909221731\gwt-windows-1.7.1.

    Note that the version numbers may be different depending on the version you have installed.

  7. Set the display name to correspond to the version, GWT X.X.X, and press OK

  8. Press OK to complete the process

This complete the renaming process.

Install the GWT 2 Eclipse plugin

This is installed as any other new Eclipse plugin.

  1. From the menu, open Help > Install New Software.... Make sure to select the Install New Software... and NOT Check for Updates
  2. Select the Google Eclipse URL: http://dl.google.com/eclipse/plugin/3.5 (for Eclipse 3.5), check both the Plugin and SDK options and press Next as shown in the image below.

  3. Next, Next, ..., Next through the installation. Once ready, restart Eclipse.

The GWT 2 Eclipse plugin is installed, with the name GWT. It is recommended to rename it to GWT 2.0.0 following the steps above discussed.

Draft Compile

One of the new features available in GWT2 is the draft compile, which is ideal for development as it skips the optimisation processes carried out by the compiler reducing the compile time. This is a great feature for development, but the production code SHOULD NOT be compiled in this mode.

To make use of this feature, simple add the -draftCompile to the advance compiler options as illustrated below.

Thursday, 17 December 2009

Simple Java WAV Player

In this article we'll discuss a simple way how to play wav files in Java. We'll start with the complete example and explain each bit in the process. This example only involves one class, the one listed below.

package com.albertattard.pmm;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

public class TheMusicPlayer {

  public static void play(final InputStream inputStream) {
    new Thread() {
      @Override
      public void run() {
        AudioInputStream audioInputStream = null;
        try {
          audioInputStream = AudioSystem
              .getAudioInputStream(inputStream);
        } catch (UnsupportedAudioFileException e) {
          e.printStackTrace();
          return;
        } catch (IOException e) {
          e.printStackTrace();
          return;
        }

        SourceDataLine sourceDataLine = null;
        try {
          AudioFormat audioFormat 
              = audioInputStream.getFormat();
          DataLine.Info info = new DataLine.Info(
              SourceDataLine.class, audioFormat);
          sourceDataLine = 
              (SourceDataLine) AudioSystem.getLine(info);
          sourceDataLine.open(audioFormat);
        } catch (LineUnavailableException e) {
          e.printStackTrace();
          return;
        }

        sourceDataLine.start();
        byte[] data = new byte[524288];// 128Kb
        try {
          int bytesRead = 0;
          while (bytesRead != -1) {
            bytesRead = 
                audioInputStream.read(data, 0, data.length);
            if (bytesRead >= 0)
              sourceDataLine.write(data, 0, bytesRead);
          }
        } catch (IOException e) {
          e.printStackTrace();
          return;
        } finally {
          sourceDataLine.drain();
          sourceDataLine.close();
        }
      }
    }.start();
  }

  public static void play(final String wavFile)
      throws FileNotFoundException {
    play(new FileInputStream(wavFile));
  }
}

Those of you who are in a hurry, just copy and paste the above code and get on with your life. The others who can spare sometime, just read the following part.

Explained

The class has two static overloaded methods which play the wav file provides as a parameter. The second method simple invokes the first method passing an instance of input stream (and instance of FileInputStream, which inherits from InputStream)

All the logic is found in the first play() method, and that's what we'll be explaining next.

Let say we have a program and would like to play a sound (saved as a wav file) when an event/scenario occurs. The code to do so is very straight forward as illustrated below (a copy and paste from the example above).

        AudioInputStream audioInputStream = null;
        try {
          audioInputStream = AudioSystem
              .getAudioInputStream(The Input Stream);
        } catch (UnsupportedAudioFileException e) {
          e.printStackTrace();
          return;
        } catch (IOException e) {
          e.printStackTrace();
          return;
        }

        SourceDataLine sourceDataLine = null;
        try {
          AudioFormat audioFormat 
              = audioInputStream.getFormat();
          DataLine.Info info = new DataLine.Info(
              SourceDataLine.class, audioFormat);
          sourceDataLine = 
              (SourceDataLine) AudioSystem.getLine(info);
          sourceDataLine.open(audioFormat);
        } catch (LineUnavailableException e) {
          e.printStackTrace();
          return;
        }

        sourceDataLine.start();
        byte[] data = new byte[524288];// 128Kb
        try {
          int bytesRead = 0;
          while (bytesRead != -1) {
            bytesRead = 
                audioInputStream.read(data, 0, data.length);
            if (bytesRead >= 0)
              sourceDataLine.write(data, 0, bytesRead);
          }
        } catch (IOException e) {
          e.printStackTrace();
          return;
        } finally {
          sourceDataLine.drain();
          sourceDataLine.close();
        }

The above code fragment is made from three parts:

  • Initialisation of the audio input stream
  • Initialisation of the audio output
  • Playing the audio data

We're reading bytes from the input stream (the famous wav) and instead of writing/printing these in the console (as we traditionally do with text files), we're writing to the speaker/sound card of the computer.

We start by initialising the It's good to point out that the AudioInputStream, which inherits from the InputStream. This instance behaves the same like any other stream and can be treated/handled in the same manner as other streams.

AudioInputStream audioInputStream = null;
try {
  audioInputStream = AudioSystem
    .getAudioInputStream(The Input Stream);
} catch (UnsupportedAudioFileException e) {
  e.printStackTrace();
  return;
} catch (IOException e) {
  e.printStackTrace();
  return;
}

Then we initialise the audio output (this is NOT an OutputStream), that is, where the sound will be played. This has to match the audio input initialise in the previous step. Remember that there are many different sound files and not all these can be played with the following code.

SourceDataLine sourceDataLine = null;
try {
  AudioFormat audioFormat 
    = audioInputStream.getFormat();
  DataLine.Info info = new DataLine.Info(
    SourceDataLine.class, audioFormat);
  sourceDataLine = 
    (SourceDataLine) AudioSystem.getLine(info);
  sourceDataLine.open(audioFormat);
} catch (LineUnavailableException e) {
  e.printStackTrace();
  return;
}

The first two were quite straight forward. In the third step we're actually playing the sound by reading the bytes and play them in a similar fashion we do with other streams. We're reading a predefined amount of data (128k) into the array called data and saving the amount of bytes read in the other variable bytesRead.

bytesRead = audioInputStream.read(data, 0, data.length);

When the whole file is played, and there is no more data to be played, the read() method returns -1 (like it does with any other InputStream). This will have the while condition to false ending the playing process.

It is good to note that the third step will consume the focus of program until the wav file is played. That is, if you have a two minute wav file, than the above code will take two minutes to execute. All the other parts of the program (that are executed by this thread) will have to wait for the sound/music to finish. Since this is not what we want, the static method play() wraps this code into a thread which is started at the end of the method.

public static void play(final InputStream inputStream) {
  new Thread() {
    @Override
    public void run() {
      Code removed for brevity
    }
  }.start();
}

Since the code is started within a thread the control is immediately returned to the calling method which can proceed without having to wait for the file to play.

To play a wav file, all we need to do is invoke the pay method with the wav file as a parameter as illustrated below.

package com.albertattard.pmm;

public class TheMain {

  public static void main(String[] args) {
    // File downloaded from: 
    //   http://freewavesamples.com/bowed-bass-c2
    TheMusicPlayer.play(TheMain.class
        .getResourceAsStream("Bowed-Bass-C2.wav"));
  }
}

It's good to point out that the wav file Bowed-Bass-C2.wav (available at: http://freewavesamples.com/bowed-bass-c2) is in the same directory/package as the above class.