Showing posts with label If-Less. Show all posts
Showing posts with label If-Less. Show all posts

Friday, May 15, 2009

Dependency Injection with EJB 2.x

Very often, I see in an EJB 2.x environment message driven or session beans with the following code :

public void onMessage(Message message)
{
Connection connection = null;
try
{
Context ctx = new Context();
DataSource datasource = (DataSource)ctx.lookup("jdbc/ds");
Connection connetion = ....
// Do somethign with connection
} catch(NamingException exception)
{
// Do something
} catch(SQLException exception)
{
// Do something
} finally
{
try { connection.close(); } catch(Exception ignore) {}
}
}

...or (better) using a service locator :

public void onMessage(Message message)
{
Connection connection = null;
try
{
ServiceLocator serviceLocator = new ServiceLocator();
DataSource datasource = serviceLocator.getDataSource("jdbc/ds");
Connection connetion = ....
// Do somethign with connection
} catch(NamingException exception)
{
// Do something
} catch(SQLException exception)
{
// Do something
} finally
{
try { connection.close(); } catch(Exception ignore) {}
}
}

What is the problem? That piece of code (doesn't matter if it belongs to a session or a message driven bean) should IMO contains only business logic;
I mean, the logic that should make sense, from a business point of view, of that EJB.
Now, again, what is the problem? JDBC Code? Why don't we use a Data Gateway (or in general a data access pattern)?
Yes, that's right, but that's not the point.
Let's make a strong precondition supposing that jdbc code is part of business logic.
What else?

Look at this line of code :

} catch(NamingException exception)
{
// Do something
}

This exception is thrown when some problem occurs with naming service. The funny thing is that we are looking up the resource (a datasource in this case) each time this method is called. What is the problem?

There are at least three issues :

1) Each call to Context.lookup(...) is theoretically a remote call. Here that call is done each time a message arrives. You may think that code could be optimized, looking up the resource the first time, but you must in any case catch the Naming Exception (even if the lookup isn't really executed)
2) What you need is the resource that is bound with the naming service under the name "jdbc/ds", not the naming service itself. Once you got it, you have all what you need in order to retrieve valid database connections. So you should use that lookup code once and only once.
3) NamingException is not a business excepiton...the corresponding "throwing" code it's not part of the business logic too, but the onMessage(), where only the business logic should be, must contain the try-catch statement in order to handle a scenario where a naming service occurs...EACH TIME THE CODE IS EXECUTED!.

The usage of a service locator doesn't solve the problem completely : even if we cache the resource (on service locator), we will avoid the 1) & 2) but not the 3th issue.
In fact the signature of the getDatasource(...) method is throwing a NamingException and therefore the calling code must catch it everytime.

The ideal solution should:

1) make a lookup call only once;
2) catch the naming exception only once (when the lookup call is executed)
3) in case of naming exception (naming service failure) the call should be repeated until the resource is available.

public void GxMessageDriven implements MessageDrivenBean, MessageListener
{
private DataSource datasource;

public void onMessage()
{
// Here we can use directly the datasource instance that
// has been self-injected in ejbCreate() method at startup.
Connection connection = null;
try
{
connection = datasource.getConnection()
} catch(SQLException exception)
{
...
} finally
{
try { connection.close } catch(Exception ignore){}
}
}

public void ejbCreate()
{
try
{
// Using a service locator should be better
Context ctx = new InitialContext();
datasource = (DataSource) ctx.lookup("jdbc/ds");
} catch(NamingException exception)
{
// This ejb cannot be initialized because a needed resource cannot be retrieved
}
}
}

As you can see the lookup code (and the corresponding catch of the NamingException) is executed only once in the ejbCreate().
The first obvious consequence is that within onMessage() method the datasource member instance is used directly because it is already intialized.
There's only remaining open issue : what happens if the lookup fails in the ejbCreate? Basically that means the onMessage method will throw a NullPointerException and obviously we don't want that :)
If you are thinking about an if statement within the onMessage method :

if (datasource != null)
{
....
}

That means probably you didn't read my previous post : I hate if statements :) I think is better to equipe the ejb component with a state pattern in the following way :

1) create a member instance which will represent the current state of the component:

private MessageListener currentState;

2) create one inner class which represents the WORKING state:

private final MessageListener WORKING = new MessageListener()
{
public void onMessage()
{
// Here we can use directly the datasource instance that
// has been self-injected in ejbCreate() method at startup.

Connection connection = null;
try
{
connection = datasource.getConnection()
} catch(SQLException exception)
{
...
} finally
{
try { connection.close } catch(Exception ignore){}
}
}
}

3) Create another inner class which represents the OFF state :

private final MessageListener OFF = new MessageListener()
{
public void onMessage(Message message)
{
try
{
Context ctx = new InitialContext();
datasource = (DataSource) ctx.lookup("jdbc/ds");

// State change : OFF --> WORKING
currentState = WORKING;

// Process the message
currentState.onMessage(message);
} catch(NamingException exception)
{
// Don't change current state...resource is not yet available
}
}
}

4) Update the memeber instance variable in order to set the OFF state as default state.

private MessageListener currentState = OFF;

At this point, you should probably see that the ejbCreate is no longer useful because the check is made by the OFF state the first time the component raises up.

So, the final code should look like this :

public void GxMessageDriven implements MessageDrivenBean, MessageListener
{
private final MessageListener OFF = new MessageListener()
{
public void onMessage(Message message)
{
try
{
Context ctx = new InitialContext();
datasource = (DataSource) ctx.lookup("jdbc/ds");

// State change : OFF --> WORKING
currentState = WORKING;

// Process the message using the working state
currentState.onMessage(message);
} catch(NamingException exception)
{
// Don't change current state...resource is not yet available
}
}
}

private final MessageListener WORKING = new MessageListener()
{
public void onMessage()
{
// Here we can use directly the datasource instance that
// has been self-injected in ejbCreate() method at startup.

Connection connection = null;
try
{
connection = datasource.getConnection()
} catch(SQLException exception)
{
//...
} finally
{
try { connection.close } catch(Exception ignore){}
}
}
}
private DataSource datasource;
private MessageListener currentState= OFF;
}

Wednesday, December 03, 2008

IF-LESS code : State / Strategy Pattern

We have a simple class that is looping on a given List. Requirement are :

1) Service must preserve the first value of the list;
2) Each other element must be printed in uppercase
3) At the end of the loop the "Exit" string must be printed out;

The first version is the following :

public class Service {
String theFirst;
public void loop(List strings){
int index = 0;
for (String string : strings) {
if (index == 0) {
theFirst = string;
} else {
System.out.println(string.toUpperCase());
}
index++;
}
System.out.println("Exit");
}
}


Ok, brief and (moreless) clear; Let's try to modify a little bit that class; First, I'd introduce a compose method in order isolate what needs to be done 
for middle iterations (uppercase printing) so I'll introduce :

private void uppercase(String value) {
System.out.println(value.toUppercase());
}

Next, I don't like the explicit loop & condition logic. The tasks that need to be executed in the current example are very simple but let's try to imagine a more complicated task 
(for initial and middle iteration) : the code should result complicated to understand...

 I'd prefer to isolate those tasks in a separate method / class.
So, in order to do that, let's introduce an Iteration interface that represents the task that needs to be executed on a given iteration.

// Determines what needs to be done on a given iteration
interface Iteration {
void execute(String value);
}

we have two concrete implementors; something like that:

Iteration firstIteration = new Iteration() {
public void execute(String value) {
// Store the value of the first element
}
}

Iteration middleIteration = new Iteration() {
public void execute(String value) {
uppercase(value);
}
}

Now, each task should be responsible to execute its logic and in addition should provide some mechanism to compute & execute the next iteration. 
In order to do that we change a little the Iteration interface and the hosting class introducing a new Iterator member that is initialized on the loop() method.


interface Iteration {
void execute();
}

Iteration firstIteration = new Iteration() {
public void execute() {
// Store the value of the iterator.next() that is the first element of the list;
}
}

Iteration middleIteration = new Iteration() {
public void execute() {
uppercase(iterator.next());
}
}

private Iterator iterator;

...

public void loop(List strings) {
iterator = strings.iterator();
}


At this point we need to maintain a reference to the current iteration. So let's introduce another instance member :

private Iteration currentIteration = firstIteration

The initial value of this currentIteration is obviously the previously declared inner class "firstIteration". After that the loop method should be changed in order to start the loop : 

public void loop(List strings) {
iterator = strings.iterator();
currentIteration.execute();
}

Next, we need a way to continue the execution of the loop. We can do that introducing another method :

public void nextIteration() {
currentIteration = (iterator.hasNext()) ? middleIteration: noIteration;
currentIteration.execute();
}
ok, ok, I know...this is still a conditional logic but is not exaclty the same as the previous one...I'm not deal with indexes or temporary variables...just with the given collection...
As you can saw, we need another instance of Iteration inner interface for determine what needs to be done when the end of the loop is reached.

private final Iteration noIteration = new Iteration() {
public void execute() {
System.out.println("Exit");
}
}

That's all! Do you think I'm paranoic? :)....mmmmmm...yes! Note that the code above is just an exercise and the benefits are not evident because the starting class is very simple (I mean, the logic of the initial version of that class) but I can ensure you that they are more evident when those things are applied to a more complicated scenario...

This is the final version of the IlLessService :


public class IfLessService {
String theFirst;
private ListIterator iterator;
private interface Iteration {
void execute();
}
// What needs to be done in the first iteration?
private final Iteration firstIteration= new Iteration() {
public void execute() {
theFirst = iterator.next();
executeNextIteration();
}
};
// And in the middle iteration(s)?
private final Iteration middleIteration = new Iteration() {
public void execute() {
uppercase(iterator.next());
executeNextIteration();
}
};
// And when the iteration will terminate?
private final Iteration noIteration = new Iteration() {
public void execute() {
System.out.println("Exit");
}
};
private Iteration currentIteration = firstIteration;
public void loop(List strings){
iterator = strings.listIterator();
currentIteration.execute();
}
private void uppercase(String aString) {
System.out.println(aString.toUpperCase());
}
private void executeNextIteration(){
currentIteration = (iterator.hasNext()) ? middleIteration: noIteration;
currentIteration.execute();
}
}

Regards,
Andrea

Friday, November 14, 2008

IF-LESS code : State Pattern

Hi all, let's start with a post on this interesting topic (at least for me) with a simple example.
We have an interface named IService that represents a generic service. The interface offers three methods : start(), stop() and isRunning(). 

public interface IService {
void start(); // Starts the service.
void stop(); // Stops the service. 
boolean isRunning(); // Returns true if the service is running.
}

While looking at the following implementation, I wasn't satisfied about the conditional statements on start() and stop() method :

public class ServiceImpl implements IService {
   private volatile boolean started;
   private Thread thread;
   public synchronized void start() { 
      if (started) {
         return;
      }
      
      started = true;
      
      thread = ... // Create your daemon implementation.
      thread.setDaemon(true);
      thread.start();
   }
   
   public synchronized void stop()
   {      
      if (!started) {
         return;
      }
      started = false;
      thread.interrupt();
      
      try {
         thread.join();
      }
      catch (InterruptedException ignore) {         
      }
   }
   
   public synchronized boolean isRunning() {
      return started;
   }
}

To be honest, what I don't like is :

- Maintaining the state of the service in a boolean member and therefore relying on that in order to know if the service is alive or not (the isRunning method)
- Conditional logic used for checking everytime the (start & stop) methods are called if the service is alive or not. I think the service should know that without using a boolean member to remember! An example : if you are driving a car, how do you know that it's running? You know that because it's running and you're driving! ;-) and not because after turned it on you put a post-it on the dashboard with "RUNNING" written over! 
I mean : it's the status itself that suggests you what's going on!
As result of that, I prefer this version of the service implementation:


public class IfLessService implements IService {
   private Thread _watcher;
   
   /**
    * RUNNING STATE.
    */
   private final IService running = new IService() {
      public boolean isRunning()
      {
         return true; // We are inside the running state and so...
      }
      public void start() {
         // Nothing to do here...it is already started.
      }
      public void stop()  {
         _watcher.interrupt();      
         try  {
            _watcher.join();
         }
         catch (InterruptedException ignore)
         {         
         }
        state = notRunning;
      }
   };
   
   /**
    * NOT RUNNING STATE.
    */
   private final IService notRunning = new IService()  {      
      public boolean isRunning()  {
         return false; // We are inside the not running state and so...
      }
      public synchronized void start()  {
      _watcher = ...// Create your daemon implementation...
         _watcher.setDaemon(true);
         _watcher.start();
         // ...and make a state change too...from NOT-RUNNING to RUNNING.
         state = running;
      }
      public void stop() {
         // Nothing to do here...it is already stopped.         
      }      
   };   
   
   // Default initial state is stopped (not running).
   private IService state = notRunning;
   public synchronized void start() {      
      state.start();  // Current state delegation
   }
   public synchronized void stop() {      
      state.stop();    // Current state delegation   
   }
   public boolean isRunning() {
      return state.isRunning();  // Current state delegation
   }
}
Now the service implementation is delegating the execution of the IService methods to the current internal state. Those states are themselves implementors of IService interface. We have two states : running and notRunning. 
Note that the responsibility of  each state is not only to manage the "state" of the object at a specific moment but also to provide an eventual state transition: for example when the service is not running (state = notRunning), if you call the start() method there will be a state transition (state = running).
Any comment would be very very appreciated...