Monday, December 26, 2011

Annotated callback methods in custom class

We're implementing a simple message service framework to demonstrate how we can implement a framework that uses annotations, like JAX-WS. Using annotations minimizes boilerplate code, and promotes high cohesion of classes. It also promotes decoupling, because it prevents forcing the use of framework classes on clients as much as possible.

The messaging framework has one interface with a register method, which is used to register custom objects that handle incoming messages. The framework does not know what the type is of this object. It uses the reflection API to check for annotated methods, which tell the messaging framework to call these methods when a message has to be handled.

The message service framework supports two types of messages, which we define in as an enum type in MessageType.java:

package com.javaeenotes;


public enum MessageType {
    NORMAL,
    URGENT
}

The interface of the message service framework has a method to register custom client objects that will handle incoming messages. The second method of the interface is only included, so we can send messages through this framework. The interface of the message service framework is defined in MessageService.java:

package com.javaeenotes;


public interface MessageService {
    void registerMessageHandler(Object object);

    void sendMessage(String message, MessageType messageType)
        throws Exception;
}

Now, we define our annotation. This annotation can be used by the client application to mark methods that will handle incoming messages generated by the message service framework. It also has a message type enum parameter, so the framework will only call this method if the type of the message matches the specified type parameter. The annotation is defined in MessageMethod.java:

package com.javaeenotes;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


// Only usable on methods.
@Target(ElementType.METHOD)
// Annotation must be available during runtime.
@Retention(RetentionPolicy.RUNTIME)
public @interface MessageMethod {
    MessageType messageType() default MessageType.NORMAL;
}

A client object will use the annotation to mark callback methods for specified message types. The example client handler has one method for both message types. An example client message handler class for this demo is defined as ExampleMessageHandler.java:

package com.javaeenotes;


public class ExampleMessageHandler {
    @MessageMethod(messageType = MessageType.NORMAL)
    public void handleNormalMessage(String message) {
        System.out.print("NORMAL MESSAGE: " + message + "\n");
    }


    @MessageMethod(messageType = MessageType.URGENT)
    public void handleUrgentMessage(String message) {
        System.out.println("URGENT MESSAGE: " + message + "\n");
    }
}

The most important class of this tutorial is: MessageServiceImpl.java, which you can find below. This is the implementation of our message service framework interface. This class is responsible for determining callback methods provided by the client, and call them when messages arrive.

package com.javaeenotes;


import java.lang.reflect.Method;


public class MessageServiceImpl implements MessageService {
    private Object messageHandler;


    @Override
    public void registerMessageHandler(Object messageHandlerObject) {
        messageHandler = messageHandlerObject;
    }


    @Override
    public void sendMessage(String message, MessageType messageType)
            throws Exception {
        
        for (Method method : messageHandler.getClass().getMethods()) {
            if (method.isAnnotationPresent(MessageMethod.class)) {
                MessageMethod messageMethod
                    = method.getAnnotation(MessageMethod.class);

                if (messageMethod.messageType() == MessageType.NORMAL
                        && messageType == MessageType.NORMAL) {

                    method.invoke(messageHandler, message);
                } else if (messageMethod.messageType()
                        == MessageType.URGENT
                        && messageType == MessageType.URGENT) {

                    method.invoke(messageHandler, message);
                }
            }
        }
    }
}

Now, we only need a Main class to get this demonstration working. The class will create the example client object, and register it in the framework. Then, it will create two example messages, and pass them to the framework, which then will call the annotated callback methods of the example client object. The Main class is defined in: Main.java.

package com.javaeenotes;


public class Main {
    public static void main(String[] args) {
        // Create message service and register message handler.
        MessageService messageService = new MessageServiceImpl();
        messageService.registerMessageHandler(
                new ExampleMessageHandler());

        try {
            // Sending test messages through the message service.
            messageService.sendMessage("This is a normal message.",
                    MessageType.NORMAL);

            messageService.sendMessage("This is an urgent message!",
                    MessageType.URGENT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

If we run the Main class, we should get the following output:

NORMAL MESSAGE: This is a normal message.
URGENT MESSAGE: This is an urgent message!

Tuesday, December 20, 2011

Custom SLF4J Logger adapter

The Simple Logging Facade for Java or (SLF4J) is a simple facade for various logging frameworks. It decouples the logging framework from the application. The deployer can choose which logging framework to use. For every popular logging framework, an adapter Jar file is available. Deploy this file together with the core SLF4J Jar file, and the logging automagically works.

In my current work situation, a financial application I developed has to be integrated into an existing server application. This server application uses its own logging framework. Luckily, I've been using SLF4J, so logging integration is just a matter of writing a custom SLF4J adapter and replace the current adapter (SLF4J-Log4J) with it.

Writing an adapter is very easy. You only need to create three files:

  1. Create an implementation of the logger interface: org.slf4j.Logger
  2. Create a factory for the new logger using this interface: org.slf4j.ILoggerFactory
  3. Create your own binder class, so SLF4J knows which factory to use to get loggers: org.slf4j.spi.LoggerFactoryBinder
It is important to create these files in the package: org.slf4j.impl, because SLF4J is using this to find the correct adapter.

Firstly, we create the class that implements the SLF4J Logger interface. The implementation of this interface is used by SLF4J to delegate the logging. It's an interface with a large number of methods, so let the IDE generate the empty methods for you. Next is to implement the bodies of the methods to do the actual logging. In my case, I call the custom logging framework.

package org.slf4j.impl;

import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.helpers.MessageFormatter;

public class MyLoggerAdapter implements Logger {
    // Bunch of inherited methods here. Let your IDE generate this.
    // Implement these methods to do your own logging.
}

Now, we create a factory implementation for the Logger class. This class is used to retrieve Logger objects used by the application. Make sure it implements the ILoggerFactory interface.

package org.slf4j.impl;

import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.Map;


public class MyLoggerFactory implements ILoggerFactory {
    private Map<String, MyLoggerAdapter> loggerMap;

    public MyLoggerFactory() {
        loggerMap = new HashMap<String, MyLoggerAdapter>();
    }

    @Override
    public Logger getLogger(String name) {
        synchronized (loggerMap) {
            if (!loggerMap.containsKey(name)) {
                loggerMap.put(name, new MyLoggerAdapter(name));
            }

            return loggerMap.get(name);
        }
    }
}

Finally, we need a way to register or bind the logger factory to SLF4J. To do that, we have to customize the StaticLoggerBinder class. You can almost use the same code provided by other adapters. I shamelessly ripped my code from the Log4J adapter.

package org.slf4j.impl;


import org.slf4j.ILoggerFactory;
import org.slf4j.spi.LoggerFactoryBinder;


public class StaticLoggerBinder implements LoggerFactoryBinder {

    /**
     * The unique instance of this class.
     */
    private static final StaticLoggerBinder SINGLETON
        = new StaticLoggerBinder();

    /**
     * Return the singleton of this class.
     *
     * @return the StaticLoggerBinder singleton
     */
    public static final StaticLoggerBinder getSingleton() {
        return SINGLETON;
    }


    /**
     * Declare the version of the SLF4J API this implementation is
     * compiled against. The value of this field is usually modified
     * with each release.
     */
    // To avoid constant folding by the compiler,
    // this field must *not* be final
    public static String REQUESTED_API_VERSION = "1.6";  // !final

    private static final String loggerFactoryClassStr
        = MyLoggerFactory.class.getName();

    /**
     * The ILoggerFactory instance returned by the
     * {@link #getLoggerFactory} method should always be the same
     * object.
     */
    private final ILoggerFactory loggerFactory;

    private StaticLoggerBinder() {
        loggerFactory = new MyLoggerFactory();
    }

    public ILoggerFactory getLoggerFactory() {
        return loggerFactory;
    }

    public String getLoggerFactoryClassStr() {
        return loggerFactoryClassStr;
    }
}

Compile and deploy this code together with the SLF4J jar, and logging will be handled by the our new adapter.

Links:

Friday, December 16, 2011

Running Wicket on Jetty

If you're only using the web functionality provided by an application server, or you want to optimize HTTP performance, it would be a good idea to consider embedding the Jetty HTTP server inside your application. This way, you don't even have to generate a WAR-file and a web.xml file. The application is just a basic Java application, which you can run on any server with a Java VM.

Maven setup

If you're using a Maven project, add the following dependencies to the pom-file in the "dependencies"-element in order to start working right away:

<dependency>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-hightide</artifactId>
  <version>8.0.4.v20111024</version>
</dependency>

<dependency>
  <groupId>org.apache.wicket</groupId>
  <artifactId>wicket-core</artifactId>
  <version>1.5.3</version>
</dependency>

Minimal Wicket application

For our example, we use a minimal Wicket application that consists of one page.

The ExampleWicketApplication.java file:
package com.javaeenotes;


import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.WebApplication;


public class ExampleWicketApplication extends WebApplication {

    @Override
    public Class<? extends Page> getHomePage() {
        return HomePage.class;
    }
}
The HomePage.java file:
package com.javaeenotes;


import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;


public class HomePage extends WebPage {
    public HomePage() {
        add(new Label("message", "Hello World!"));
    }
}
The HomePage.html file:
<html>
<body>
  <span wicket:id="message"></span>
</body>
</html>

The final class we need is a main class with the static main-method, in which we tie the Wicket servlet to the Jetty server.

The Main.java file:
package com.javaeenotes;


import org.apache.wicket.protocol.http.WicketFilter;
import org.apache.wicket.protocol.http.WicketServlet;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;


public class Main {
    public static void main(String[] args) {
        // Object that holds, and configures the WicketServlet.
        ServletHolder servletHolder =
                new ServletHolder(new WicketServlet());
        servletHolder.setInitParameter(
                "applicationClassName",
                "com.javaeenotes.ExampleWicketApplication");
        servletHolder.setInitParameter(
                WicketFilter.FILTER_MAPPING_PARAM, "/*");
        servletHolder.setInitOrder(1);

        // Web context configuration.
        WebAppContext context = new WebAppContext();
        context.addServlet(servletHolder, "/*");
        context.setResourceBase("."); // Web root directory.

        // The HTTP-server on port 8080.
        Server server = new Server();
        SocketConnector connector = new SocketConnector();
        connector.setPort(8080);
        server.setConnectors(new Connector[]{connector});
        server.setHandler(context);

        try {
            // Start HTTP-server.
            server.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Run the main method in a VM, and connect to port 8080 with a browser to check that the application is working.

Friday, October 28, 2011

MyBatis and Oracle Database

While I was using MyBatis with the Oracle Database, I ran into two problems:

  1. Generating primary keys when inserting database rows
  2. Mapping Java boolean type to a database type
The next sections describe how I solved these problems.

Inserting new rows

Unlike other databases like MySQL, the Oracle database does not provide the functionality to generate primary keys automatically when inserting rows. Normally, I would create a sequence together with a trigger in the Oracle database. The sequence is a thread-safe number generator, and the trigger is custom code that is called on certain type of events. In this case an "insert" event, which will update the row with the primary key.

With MyBatis, we still need the sequence. The trigger functionality is provided by MyBatis. Let's get started by creating an example class in Java. I left the "getters" and "setters" out, but we still need them in the actual code ofcouse.

public class Client {
    private Integer id;
    private String name;

    // Setters and Getters for the attributes here.
}

Next, we have to prepare the database by create a table that corresponds with the "Client" class, and a sequence.

CREATE TABLE client (
    id INTEGER primary key,
    name VARCHAR2(100)
);

CREATE SEQUENCE client_seq
    START WITH 1
    INCREMENT BY 1
    NOCACHE
    NOCYCLE;

MyBatis uses "mapper" interfaces (defined and provided by us) to map the class to actual SQL-statements. Additional configuration can be provided by either XML, or annotations. When the configuration is simple, I prefer using annotations. Complex configurations are often only possible by using XML. The following mapper interface provides mapping for inserting the "Client" class. The interface is only used by MyBatis, we don't have to provide an actual implementation of it.

public interface ClientMapper {
  @Insert("INSERT INTO client (id, name) VALUES (#{id}, #{name})")
  @SelectKey(
            keyProperty = "id",
            before = true,
            resultType = Integer.class,
            statement = { "SELECT client_seq.nextval AS id FROM dual" })
  public Integer insertClient(Client client);
}

The "@SelectKey" annotation tells MyBatis to get the primary key value from the sequence, and use it as primary key when executing the insert statement.

Mapping boolean types

The final example illustrates how we deal with boolean types when using MyBatis. We extend the "Client" class with a boolean attribute "admin".

public class Client {
    private Integer id;
    private String name;
    private boolean admin;

    // Setters and Getters for the attributes here.
}

Add a "VARCHAR(1)" column that acts like a boolean attribute to the corresponding "Client" database table. The column value "Y" corresponds to boolean value true, and "N" to boolean false.

CREATE TABLE client (
    id INTEGER primary key,
    name VARCHAR2(100),
    admin varchar(1)
);

MyBatis doesn't know how the Java boolean is mapped to a database type, as there's no primitive database boolean type. We have to provide MyBatis with a converter, which implements the "TypeHandler" interface. This converter will then be used to convert a Java boolean to a database type, and vice versa.

package com.javaeenotes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

public class BooleanTypeHandler implements TypeHandler {

    private static final String YES = "Y";
    private static final String NO = "N";


    @Override
    public Boolean getResult(ResultSet resultSet, String name)
            throws SQLException {

        return valueOf(resultSet.getString(name));
    }


    @Override
    public Boolean getResult(CallableStatement statement, int position)
            throws SQLException {

        return valueOf(statement.getString(position));
    }


    @Override
    public void setParameter(
            PreparedStatement statement,
            int position,
            Boolean value,
            JdbcType jdbcType) throws SQLException {

        statement.setString(position, value.booleanValue() ? YES : NO);
    }


    private Boolean valueOf(String value) throws SQLException {

        if (YES.equalsIgnoreCase(value)) {
            return new Boolean(true);
        } else if (NO.equalsIgnoreCase(value)) {
            return new Boolean(false);
        } else {
            throw new SQLException("Unexpected value "
                    + value
                    + " found where "
                    + YES
                    + " or "
                    + NO
                    + " was expected.");
        }
    }
}

Now, configure MyBatis to use the type handler for booleans in the mapper interface where needed.


    @Insert("INSERT INTO client (id, name, admin) VALUES (#{id}, #{name}, #{admin,typeHandler=com.javaeenotes.BooleanTypeHandler})")
    @SelectKey(
            keyProperty = "id",
            before = true,
            resultType = Integer.class,
            statement = { "SELECT client_seq.nextval AS id FROM dual" })
    public Integer insertClient(Client client);

    @Select("SELECT * FROM client WHERE id = #{clientId}")
    @Results(
            value = {
                @Result(
                    property = "id",
                    column = "id"),

                @Result(
                    property = "name",
                    column = "name"),

                @Result(
                    property = "admin",
                    column = "admin",
                    typeHandler = BooleanTypeHandler.class)
             })
    public Client getClient(int clientId);

    @Update("UPDATE client SET name = #{name}, admin = #{admin,typeHandler=com.javaeenotes.BooleanTypeHandler} WHERE id = #{id}")
    public void updateClient(Client client);

Thursday, October 13, 2011

Adding Oracle JDBC driver to Maven 2 repository

I like my library JAR-files to be managed by Maven 2. It makes life much easier. Sadly, due to the binary license there is no public Maven 2 repository with the Oracle JDBC driver. So we have to add the JDBC driver manually to our local Maven 2 repository.

First, download the latest Oracle JDBC driver here: http://www.oracle.com/technetwork/indexes/downloads/index.html. Do a search on "JDBC" to find the correct download link.

If you're using Maven inside Eclipse like I am, the "mvn" command will not work from the command prompt. We have to install Maven 2 on our system. You can download Maven 2 here: http://maven.apache.org/download.html. Simply unzip, and make sure the "bin" directory is in your command path.

Now, we can install the JAR file with the following command:

mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6
  -Dversion=11.2.0.3 -Dpackaging=jar -Dfile=ojdbc6.jar -DgeneratePom=true
Be sure to check the parameters, like the version number.

Finally, we can use the Oracle JDBC driver in our Maven 2 project by adding the following dependency to our "pom.xml" file:

<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc6</artifactId>
    <version>11.2.0.3</version>
</dependency>

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.

Tuesday, June 28, 2011

Sunday, June 5, 2011

Short introduction to jMock

The jUnit framework is a great tool for testing your Java application. But writing test cases can be complex. Especially when the object under test is dependent on several other objects, which in turn depend on other objects. This means the whole dependency graph has to be created before the test can be executed. Building this graph can be complex, and error-prone.

Luckily for us, there exists a framework called jMock. jMock enables you to create mock objects that mimic behavior of dependent objects. We can configure the expected interaction and behavior of these objects.

Let's start with an example class we want to test:

package com.javaeenotes;

public class TestSubject {
private DependentClassInterface depObject;

public TestSubject(DependentClassInterface depObject) {
this.depObject = depObject;
}

public String method() {
return depObject.method();
}
}

The class is dependent on a class with the following interface:

package com.javaeenotes;

public interface DependentClassInterface {
public String method();
}

The interface specifies a method that returns a String. The actual implementation of this interface is not required for jMock. jMock uses the interface to create an object with the same interface you can use in your test cases.

An example test case:

package com.javaeenotes;

import static org.junit.Assert.assertTrue;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;

public class TestSubjectTest {
@Test
public void testMethod() {
Mockery context = new Mockery();
// Create mock object.
final DependentClassInterface depObject = context
.mock(DependentClassInterface.class);

// Test object is instantiated with mock object.
TestSubject testSubject = new TestSubject(depObject);

// Configure expectation and behavior.
context.checking(new Expectations() {
{
oneOf(depObject).method();
will(returnValue("hello"));
}
});

// Test outcome.
assertTrue(testSubject.method().equals("hello"));

// Check if expectations are satisfied.
context.assertIsSatisfied();

}
}

In this test case, we create the object under test with a mock object. The expected interaction and behavior is then configured. First, the method() method is called, which then returns a string value "hello". Other interactions, like calling the same method twice, will result in an error.

As you can see, jMock is a very valuable extension to the jUnit framework, which makes writing test cases much easier.

Links:


Note: when running jMock in Eclipse, the following error can occur when running test cases:

java.lang.SecurityException:
class "org.hamcrest.TypeSafeMatcher"'s signer information
does not match signer information of other classes in the
same package

The solution is make sure the jMock libraries are included before the standard jUnit libraries in the build path.

Thursday, May 19, 2011

Free resources associated with web clients

Imagine we have the following problem. Resources are kept open for web clients as long as the clients are using them. When they leave, the resources have to be closed.

Technically, we can say as long as the HttpSession is alive in the web container, the resources are kept open. When the HttpSession is invalidated, we need to call a method that frees the resources.

A solution is to use the HttpSessionBindingListener to solve this problem.

The idea is to create a class that implements this interface. The unbound method contains or refers to the clean-up code. Whenever resources are opened, an instance of this class is created and saved to the corresponding session. When the session invalidates, which can happen by timeout, the web container automatically calls the method of the object in order to free open resources.

The class:

package com.javaeenotes;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class Janitor implements HttpSessionBindingListener {

public void valueBound(HttpSessionBindingEvent arg0) {
;
}

public void valueUnbound(HttpSessionBindingEvent arg0) {
// Start some cleaning here.
}
}


Use the HttpSession.setAttribute() method to save an instance of this class to the session.

Saturday, May 14, 2011

Creating a Modal Window page with Apache Wicket

This post aims to clarify creating a modal window with Apache Wicket. Before continuing, minimum basic knowledge about Apache Wicket is required. A modal window is a child window on top of the main window. The modal window requires the user to interact with it, before the user can return to the main window.

The application we're developing consists of two pages:

  • The main page (LaunchPage.java and LaunchPage.html)
  • The modal window page (ModalContentPage.java and ModalWContentPage.html)

The main page defines and displays the content of a variable and it also has a link to open the modal window page.

The modal window page displays the content of the same variable. But when the modal window is closed, the variable is changed by the modal window page.

Let's start by creating the HTML-file of the main page.

<html>
<head>
<title>Launch Page</title>
</head>
<body>
<div wicket:id="modal"></div>
<span wicket:id="passValueLabel">Value of passValue variable.</span>
<a wicket:id="showModalLink">Open modal window.</a>
</body>
</html>

This page defines the modal page with id "modal". The next line is the location where the content of the variable "passValue" is displayed. Finally, a link is defined that opens the modal window.

Next, the corresponding Java class:

package com.javaeenotes;

import org.apache.wicket.Page;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.model.PropertyModel;

public class LaunchPage extends WebPage {

private String passValue;

@SuppressWarnings("serial")
public LaunchPage() {

passValue = "This value is passed to the modal window.";

// Display the current content of the passValue variable. The
// PropertyModel must be used, as the value can be changed.
final Label passValueLabel;
add(passValueLabel = new Label("passValueLabel",
new PropertyModel<String>(this, "passValue")));
passValueLabel.setOutputMarkupId(true);

// Create the modal window.
final ModalWindow modal;
add(modal = new ModalWindow("modal"));
modal.setCookieName("modal-1");

modal.setPageCreator(new ModalWindow.PageCreator() {
public Page createPage() {
// Use this constructor to pass a reference of this page.
return new ModalContentPage(LaunchPage.this.getPageReference(),
modal);
}
});
modal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
public void onClose(AjaxRequestTarget target) {
// The variable passValue might be changed by the modal window.
// We need this to update the view of this page.
target.add(passValueLabel);
}
});
modal.setCloseButtonCallback(new ModalWindow.CloseButtonCallback() {
public boolean onCloseButtonClicked(AjaxRequestTarget target) {
// Change the passValue variable when modal window is closed.
setPassValue("Modal window is closed by user.");
return true;
}
});

// Add the link that opens the modal window.
add(new AjaxLink<Void>("showModalLink") {
@Override
public void onClick(AjaxRequestTarget target) {
modal.show(target);
}
});
}

public String getPassValue() {
return passValue;
}

public void setPassValue(String passValue) {
this.passValue = passValue;
}
}

The class file displays the content of "passValue" and creates the modal window class with its methods. Look carefully at the code and comments in the modal window methods. We can see that the passValueLabel is expected to change in the window close callback method. We can also see that the variable is actually changed using a setter in the close button callback method. This happens when the user clicks on the close button of the modal window. Finally, an AJAX link is defined and added to the page.

The second part is the modal window page:

<html>
<head>
<title>Modal Content Page</title>
</head>
<body>
<span wicket:id="passValueLabel">Current content of passValue variable.</span>
</body>
</html>

The modal page only displays the content of the "passValue" variable. The variable is owned by the main page.

package com.javaeenotes;

import org.apache.wicket.PageReference;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;

public class ModalContentPage extends WebPage {

public ModalContentPage(final PageReference modalWindowPage,
final ModalWindow window) {

// Retrieve the passValue content for display.
String passValue = ((LaunchPage) modalWindowPage.getPage())
.getPassValue();
add(new Label("passValueLabel", passValue));

// You can use the
// ((LaunchPage)modalWindowPage.getPage()).setPassValue() method to
// change the passValue variable of the launch/caller page.
}
}

This class is pretty simple. The first parameter refers to the main page that created the modal window page. Go back, and look how the modal window page is constructed in the main page. The main page is casted and the variable is retrieved using the getter-method. The content is then displayed in the modal window page.

Now run the code and the main page will look like this:



After clicking the link, the modal window page is opened:



We can see the same variable is displayed in the modal window page. Now, we close the modal window page. Because of this event, the variable is changed as instructed in the callback code:



As expected, the variable is changed in the main window.

Thursday, May 12, 2011

Java Practices

A came across a very nice site with a collection of best practices in Java development:

http://www.javapractices.com

Definitely worth a read!

Wednesday, April 20, 2011

Unnecessary Code Detector (UCD)

I'm currently working on a couple of years old Spring-based Java application. The application is developed and extended by multiple developers, which is clearly visible in the code. I'm responsible for a feature change that is going to have a big impact on the code.

An important step before implementing the new feature, is to refactor the relevant parts of the application in order to make the change easier to implement (and more understandable).

I noticed that parts of the code or modules are probably not used anymore. To make the refactoring process easier and more effective, it's probably a good idea to locate and remove dead code. Refactoring dead code is a waste of energy! I've found an Eclipse plugin in the Eclipse Marketplace called Unnecessary Code Detector, which helps me locating dead code.

A first run of UCD results in a bunch of markers on code locations, where UCD thinks the code is unused. It also places markers on locations where the "visibility" of variables and methods could be improved.

The tool enables me to quickly find classes and methods with no references. I always do a double check with a "text find" on the whole project, to make sure the code is really not used. Because I'm using Spring, some of the classes are only referenced and used in the XML file. This type of reference is not detected by UCD, and it results in false positives. I annotate these locations with @SuppressWarnings("ucd"), which will stop UCD from marking them as unused code in the future.

In my opinion, Unnecessary Code Detector is a very valuable tool for the Java Developer. Give it a try!

Sunday, April 17, 2011

Java Management Extensions (JMX) and Spring

The Java Management Extensions (JMX) API is a standard for managing and monitoring applications and services. We will skip all the theory, and go right into developing a JMX bean that is partly exposed to JMX. Using JMX tools we can manage and monitor the bean.

This blog post shows how to create a bean, which has a normal interface and a custom restrictive interface for JMX.

The Java interface below defines a class with three methods. The first two methods are setters and getters of an attribute.


package com.javaeenotes;

public interface Example {
public String getAttribute();

public void setAttribute(String s);

public void hiddenOperation();
}


Take this interface and develop a class with some extra methods.


package com.javaeenotes;

public class ExampleImpl implements ExampleMBean, Example {
private String attribute = null;
private int attribute1 = 0;
private String attribute2 = null;

// Not exposed to JMX.
public String getAttribute() {
return attribute;
}

// Not exposed to JMX.
public void setAttribute(String s) {
attribute = s;
}

// Exposed to JMX.
public int getExampleAttribute1() {
return attribute1;
}

// Not exposed to JMX.
public void setExampleAttribute1(int i) {
attribute1 = i;
}

// Exposed to JMX.
public String getExampleAttribute2() {
return attribute2;
}

// Exposed to JMX.
public void setExampleAttribute2(String s) {
attribute2 = s;
}

// Not exposed to JMX.
public void hiddenOperation() {
;
}

// Exposed to JMX.
public void operation() {
;
}
}


Some of them are meant to be exposed to JMX, which means they can be monitored and manipulated. Now, define an interface to be used by JMX. The interface must follow the MBean conventions. This means we use getters and setters for attributes we want to expose. We leave out setters if we want to make the attribute read only. We also define operations for JMX.


package com.javaeenotes;

public interface ExampleMBean {
public int getExampleAttribute1();

public String getExampleAttribute2();

public void setExampleAttribute2(String s);

public void operation();
}


Lastly, we configure all of this in a Spring beans XML file. We use the class MBeanExporter to expose our bean to JMX. We also tell it to use the restrictive MBean interface for our bean.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="com.javaeenotes:name=exampleBean" value-ref="exampleBean" />
</map>
</property>
<property name="assembler">
<bean
class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
<property name="managedInterfaces">
<value>com.javaeenotes.ExampleMBean</value>
</property>
</bean>
</property>
<property name="autodetectModeName" value="AUTODETECT_MBEAN" />
</bean>

<bean id="exampleBean" class="com.javaeenotes.ExampleImpl">
<property name="exampleAttribute2" value="a value" />
</bean>
</beans>


To get all of this working as a demonstration, we're going to use the following Main class.


package com.javaeenotes;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {
new ClassPathXmlApplicationContext(new String[] { "beans.xml" });

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


Now, it's time to run this in our IDE. Or you can export it as runnable JAR, but make sure you place the beans.xml file in the same directory as the JAR-file.

After we run it, we're going to use the jconsole tool to lookup our bean. The tool can be found in the bin directory of your JDK installation directory. The screen below is presented to us, after we fire up jconsole.



Select our Main class and click on Connect, which will take us to the overview screen. Now select the MBeans tab, to find our bean.



Browse the directory tree to get the details of our bean. We can use it to view the values of the variables. We can even call the exposed methods of the bean. Try it!

This is a very, very short tutorial to get it working. Please use the following links to get more detailed information about JMX.

Saturday, April 2, 2011

Google Guice

As a developer and designer, you want to reduce static dependencies between classes. Whenever you need an instance, you still have to refer to the real class in order to get an instance of the implementation.

ExampleInterface object = new ExampleImpl();

We are only interested in the interface, so we want to avoid having to know the real implementation class. We can use a Factory Method design pattern to achieve this. Using this design pattern, we centralize and hide the implementation class in the factory class. This enables us to vary the implementation if needed. This is particular useful, when using mock objects for testing the application. Using Factory Methods reduces coupling and increases modularity.

public class ExampleFactory() {
public ExampleInterface getInstance() {
return new ExampleImpl();
}
}

The factory is commonly implemented as a Singleton.

A better way to couple objects together, is to use Dependency Injections. In JEE, this is available in a container for container managed classes. In the example code below, the container will automatically create and set a resource instance of the desired class.

public class Client {
@Resource
private ExampleInterface instance;
}

In other classes where container Dependency Injection is not possible, we can pass the implementation to the client class by using its constructor.

public class Client {
private ExampleInterface instance;

public Client(ExampleInterface instance) {
this.instance = instance;
}
}

The problem here is, that we need the implementation class whenever we instantiate the client class. This ties our implementation class to every location where we instantiate the client class, which we really want to avoid.

In this blog post, we'll use Google Guice to leverage Dependency Injection in the rest of our code. In order to use Guice, we need a class that maps interfaces to their implementation. The class has to extend AbstractModule provided by Guice.

public class ExampleModule extends AbstractModule {
@Override
protected void configure() {
bind(ExampleInterface.class).to(ExampleImpl.class);
bind(AnotherClass.class).to(AnotherInterface.class);
}
}

Now, we can use the @Inject annotation in places, where we need the implementations of mapped interfaces. The class below shows how.

public class ExampleClient {
// Attribute Injection
@Inject
private ExampleInterface instance;

// Constructor Injection
@Inject
public ExampleClient(ExampleInterface inst1) {
...
}

// Method Injection
@Inject
public void ExampleMethod(ExampleInterface inst2) {
...
}
}

Now, when we instantiate the client class, we let Guice to instantiate it.

Injector injector = Guice.createInjector(new ExampleModule());
ExampleClient client = injector.getInstance(ExampleClient.class);

Guice will create and inject the dependencies before returning the client class.

We can also use the injector as a factory.

ExampleInterface instance = injector.getInstance(ExampleInterface.class);

A complete example application can be found below. Make sure the following JAR-files are included in your build path when compiling the example:

  • guice-3.0.jar
  • javax.inject.jar
  • aopalliance.jar

ExampleClient.java

package com.javaeenotes;

import com.google.inject.Inject;

public class ExampleClient {
// Attribute Injection
@Inject
private ExampleInterface instance;

// Constructor Injection
@Inject
public ExampleClient(ExampleInterface inst1) {
inst1.method("Constructor is successfully injected.");
}

// Method Injection
@Inject
public void ExampleMethod(ExampleInterface inst2) {
inst2.method("Method is successfully injected.");
}

// Used to test Attribute Injection
public void testAttribute() {
instance.method("Attribute is successfully injected.");
}
}

ExampleImpl.java

package com.javaeenotes;

public class ExampleImpl implements ExampleInterface {

@Override
public void method(String s) {
System.out.println(s);
}
}

ExampleInterface.java

package com.javaeenotes;

public interface ExampleInterface {
public void method(String s);
}

ExampleModule

package com.javaeenotes;

import com.google.inject.AbstractModule;

public class ExampleModule extends AbstractModule {
@Override
protected void configure() {
bind(ExampleInterface.class).to(ExampleImpl.class);
}
}

GuiceDemo.java

package com.javaeenotes;

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

public class GuiceDemo {

public static void main(String[] args) {
Injector injector = Guice.createInjector(new ExampleModule());

System.out.println("Getting instance using injector as a factory.");
ExampleInterface instance = injector
.getInstance(ExampleInterface.class);
instance.method("Test instance returned by injector.");

System.out.println("Getting injected client.");
ExampleClient client = injector.getInstance(ExampleClient.class);
client.testAttribute();
}
}

Saturday, March 26, 2011

Law of Demeter (LoD)

As a programmer, you want to create software that are loosely coupled. A common rule called Law of Demeter (LoD) can be used in object-oriented software to reduce coupling.

The rule is formulated as: Only talk to your friends. A friend is defined as a variable a piece of code directly knows, ie. an attribute, a local variable or a method parameter.

Now, let's examine the following code:

public void do(ExampleClass c) {
String s = "Hello";

c.getSomething().passString(s);
}

In this example, the code is coupled to three classes: ExampleClass, String, and an unknown class returned by the getSomething() method. Only the first two classes are considered friends.

The code is calling (talking to) methods of two objects: the ExampleClass object and the unknown object.

According to the LoD rule, we don't want to talk to classes that are not our friends. This unknown object is not a friend of us, so we'd rather not call its methods.

We can improve the code using the Law of Demeter like this:

public void do(ExampleClass c) {
String s = "Hello";

c.passStringToSomething(s);
}

A new method is created in ExampleClass in order to take over the responsibility for passing a String to the unknown object. The improved example is coupled to two classes now.

Saturday, March 19, 2011

JAR-files and Property-files in an EAR-file

If you get a ClassNotFoundException when deploying an EAR-file, chances are that shared library/utility JAR-files like hibernate3.jar or log4j.jar are not included in the EAR-file.

Place the missing files directly in APP-INF/lib of the EAR-file. Property-files must be placed in APP-INF/classes. This ensures both types of files are visible after deployment.

More on this subject can be found here.

Sunday, March 13, 2011

Thread scoped JAX-WS webservices

Like Servlets, the container uses one instance of a web service class to handle incoming web service requests, which is the default behavior. Ofcourse, you can make the web service thread-safe by adding the synchronized method to the exposed methods like the following code:

@WebService
public class ExampleWS {
public synchronized void doSomething() {
;
}

public synchronized void doSomethingElse() {
;
}
}

By doing this, you eliminate the possibility of parallel or concurrent handling of incoming requests. In order to support concurrent processing, you can mark the web service class as thread scoped by using the @ThreadScope annotation.

import org.jvnet.jax_ws_commons.thread_scope.ThreadScope;

@WebService
@ThreadScope
public class ExampleWS {
public synchronized void doSomething() {
;
}

public synchronized void doSomethingElse() {
;
}
}

The added annotation will force the container to create a new instance of the web service class for every thread (ie. every request). Instances will not be shared by threads.

Thursday, February 17, 2011

Configuring your Java web application as root (/)

By default, if you deploy an application "myWebApp" in an application server like Glassfish, the root URL is http://my.server.com:8080/myWebApp. To change this, you can use the sun-web.xml descriptor file of the application to configure the application as root application of the server. Which means that the application is accessible using the URL http://my.server.com:8080/.

Inside the sun-web.xml file, make sure the context-root element looks like this:

<context-root>/</context-root>


The document type definition (DTD) of the descriptor file can be found here.

If the web application is part of an EAR-file, make sure you configure this in application.xml. Otherwise, the setting in application.xml will override it!

To make the URL even simpler, you can ofcourse change the listen port to 80. The URL to the application will then look like this: http://my.server.com/

Wednesday, February 16, 2011

Listing Open Source Web Frameworks in Java

I've stumbled acros a nice listing of available open source web frameworks for Java:

http://java-source.net/open-source/web-frameworks.

Are there really too many Java web frameworks?

Monday, February 14, 2011

When @SchemaValidation in JAX-WS web services fails

I'm currently developing web services in an Oracle WebLogic environment. To enable schema validation on the web service, one only has to use the @SchemaValidation annotation in the web service class. Like this:


import com.sun.xml.ws.developer.SchemaValidation;

@WebService(...)
@SchemaValidation
public class WebService implements WebServiceInterface {
...
}


Unfortunately, that doesn't work for me. I get this error when I try to deploy my application:


Caused by: javax.xml.ws.WebServiceException:
Annotation@com.sun.xml.internal.ws.developer.SchemaValidation
(handler=class com.sun.xml.internal.ws.server.DraconianValidationErrorHandler)
is not recognizable,
atleast one constructor of class com.sun.xml.internal.ws.developer.SchemaValidationFeature
should be marked with @FeatureConstructor


I also tried creating my own validator to use in the annotation (@SchemaValidation(handler = ExampleValidationHandler.class)):


import org.xml.sax.SAXParseException;

import com.sun.xml.internal.ws.developer.ValidationErrorHandler;

public class ExampleValidationHandler extends ValidationErrorHandler {

public void warning(SAXParseException exception) {
;
}

public void error(SAXParseException exception) {
;
}

public void fatalError(SAXParseException exception) {
;
}
}


Then I enabled schema validation explicitly in the Oracle WebLogic web services deployment descriptor: weblogic-webservices.xml.


<?xml version="1.0" encoding="UTF-8"?>
<weblogic-webservices
xmlns="http://xmlns.oracle.com/weblogic/weblogic-webservices"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-webservices http://xmlns.oracle.com/weblogic/weblogic-webservices/1.1/weblogic-webservices.xsd">

<webservice-description>
<webservice-description-name>ExampleWSService</webservice-description-name>
<webservice-type>JAXWS</webservice-type>
<port-component>
<port-component-name>ExampleWSService</port-component-name>
<validate-request>true</validate-request>
<reliability-config>
<inactivity-timeout>P0DT600S</inactivity-timeout>
<base-retransmission-interval>P0DT3S</base-retransmission-interval>
<retransmission-exponential-backoff>true</retransmission-exponential-backoff>
<acknowledgement-interval>P0DT3S</acknowledgement-interval>
<sequence-expiration>P1D</sequence-expiration>
<buffer-retry-count>3</buffer-retry-count>
<buffer-retry-delay>P0DT5S</buffer-retry-delay>
</reliability-config>
</port-component>
</webservice-description>
</weblogic-webservices>


Unfortunately, that didn't work either. Google shows me three other developers with the same problem, but there is no working solution for me, and for them. So, another approach is needed to enable schema validation on incoming messages.

The solution presented in this blog post makes use of web service handlers. A web service handler is like an intercepting filter, which enables you to intercept incoming and outgoing messages, before they are passed on to the (external) system. The steps needed for this solution:

1. Create web service handler class
2. Define handler chain in XML-descriptor
3. Use annotation in web service class

1. Create web service handler class

There are two types of web service handlers:
- LogicalHandler
- SOAPHandler

The LogicalHandler provides access to the logical message, without protocol details like: SOAP envelopes. The SOAPHandler provides access to SOAP protocol details. For the purpose of message validation, the LogicalHandler is a better choice.


package com.javaeenotes;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.ws.LogicalMessage;
import javax.xml.ws.handler.LogicalHandler;
import javax.xml.ws.handler.LogicalMessageContext;
import javax.xml.ws.handler.MessageContext;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class ValidationHandler implements LogicalHandler<LogicalMessageContext> {
private String schemaUrl = "http://127.0.0.1:8080/webservice/schema.xsd";

@Override
public boolean handleMessage(LogicalMessageContext context) {
Boolean isOutBound = (Boolean) context
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

if (isOutBound) {
return true;
}

LogicalMessage lm = context.getMessage();
Source payload = lm.getPayload();
StreamResult res = new StreamResult(new StringWriter());
String message = "";

try {
Transformer trans;
trans = TransformerFactory.newInstance().newTransformer();
trans.transform(payload, res);
message = res.getWriter().toString();
// Validate
validate(message, schemaUrl);
} catch (TransformerConfigurationException e) {
// When Source payload Transformer object could not be obtained.
throw new WebServiceException(e);
} catch (TransformerFactoryConfigurationError e) {
// When Source payload Transformer object could not be obtained.
throw new WebServiceException(e);
} catch (TransformerException e) {
// When Source payload could not be transformed to String.
throw new WebServiceException(e);
} catch (MalformedURLException e) {
// When URL to schema is invalid.
throw new WebServiceException(e);
} catch (ParserConfigurationException e) {
// When parser needed for validation could not be obtained.
throw new WebServiceException(e);
} catch (IOException e) {
// When something is wrong with IO.
throw new WebServiceException(e);
} catch (SAXException e) {
// When XSD-schema validation fails.
throw new WebServiceException(e);
}

return true;
}

private void validate(String xml, String schemaUrl)
throws ParserConfigurationException, IOException,
MalformedURLException, SAXException {

DocumentBuilder parser = null;
Document document = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
parser = dbf.newDocumentBuilder();

byte bytes[] = xml.getBytes();
document = parser.parse(new ByteArrayInputStream(bytes));
SchemaFactory factory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

Schema schema = null;
schema = factory.newSchema(new URL(schemaUrl));
javax.xml.validation.Validator validator = schema.newValidator();
validator.validate(new DOMSource(document));
}

@Override
public boolean handleFault(LogicalMessageContext context) {
return true;
}

@Override
public void close(MessageContext context) {
;
}

}


It is important to note that the payload must be defined in an XSD-schema. A definition in a WSDL file cannot be used. Use the boolean property: MessageContext.MESSAGE_OUTBOUND_PROPERTY to differentiate between out-bound or in-bound messages. Throw a WebServiceException when something goes wrong.

2. Define handler chain in XML-descriptor

Now, create a handler chain XML-descriptor file, which refers to the handler created in the previous step. In this example, I named the file handlers.xml and placed it in the same directory as the handler. The location of the file is important in the last step.


<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/javaee_web_services_metadata_handler_2_0.xsd">
<handler-chain>
<handler>
<handler-name>ValidationHandler</handler-name>
<handler-class>com.javaeenotes.ValidationHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>


3. Use annotation in web service class

The final step is to use the @HandlerChain annotation in the web service class. The file parameter must be a relative path to the XML-descriptor file from the annotated class file or an absolute URL.


package com.javaeenotes;

import javax.jws.HandlerChain;
import javax.jws.WebService;

import com.javaeenotes.ws.ExampleWS;
//import com.sun.xml.ws.developer.SchemaValidation;

@WebService(name = "ERSService",
targetNamespace = "http://javaeenotes.com/",
serviceName = "ExampleWSService",
portName = "ExampleWSPort",
endpointInterface = "com.javaeenotes.ws.ExampleWS",
wsdlLocation = "WEB-INF/wsdl/ExampleWSService.wsdl")
//@SchemaValidation
@HandlerChain(file = "handlers.xml")
public class WsImplementation implements ExampleWS {

@Override
public int sum(int arg0, int arg1) {
return 0;
}

@Override
public String greet(String arg0) {
return null;
}

@Override
public int multiply(int arg0, int arg1) {
return 0;
}
}