Fork me on GitHub

Running an Avalon Service

Writing an Avalon service without running it is a rather academic approach. The YAAFI container was born out of the need to add infrastructure service to an existing web application. Therefore there are many ways to skin the YAAFI cat

  • Using the org.apache.fulcrum.yaafi.framework.factory.ServiceContainerFactory
  • Using the org.apache.fulcrum.yaafi.cli.Main
  • Using another Avalon container

Using ServiceContainerFactory

The easist way of getting it going is to define a container configuration file as shown below. The file contains the location of the Avalon artifacts to get the container and the services up and running.


<fulcrum-yaafi>
  <componentRoles>
    <location>./tutorial/conf/componentRoles.xml</location>
  </componentRoles>
  <componentConfiguration>
    <location>./tutorial/conf/componentConfig.xml</location>
  </componentConfiguration>
  <parameters>
    <location>./tutorial/conf/parameters.properties</location>
  </parameters>
</fulcrum-yaafi>
          

After writing the container configuration file you fire up the factory to get an instance of the YAAFI container. Since all of the optional configuration the YAAFI container uses the default temp directory and a ConsoleLogger.

ServiceContainer container = null;
ServiceContainerConfiguration config = null;

config = new ServiceContainerConfiguration();
config.loadContainerConfiguration( "./tutorial/conf/containerConfiguration.xml" );
container = ServiceContainerFactory.create( config );
          

It is gooooooood practice to shutdown an Avalon container properly to give the running Avalon service a chance to free any resources

container.dispose();
          

Using Main

This class helps to run a command line application based on the YAAFI container. The following sample shows a more complex setup

  • uses a ConsoleLogger
  • sets "./temp" as the temporary directory to be used
  • loads a container configuration file from "./conf/containerConfiguration.xml
  • blocks the main thread until termination
  • installs a JVM shutdown hook to dispose the YAAFI container during JVM shutdown
public class Application implements Runnable
{
    /** the YAAFI command line interface */
    private Main cli;

    public static void main( String[] args )
    {
        try
        {
            new Application(args).init().run();
        }
        catch( Throwable t )
        {
            String msg = "Execution of the server failed : " + t.getMessage();
            System.err.println(msg);
        }
    }

    public Application(String[] args)
    {
        this.cli = new Main(args);
    }

    protected Application init() throws Exception
    {
        // 1) initialize the YAAFI Main class

        // 1.1) set the temp directory to be used
        this.cli.setTempHome( "./tutorial/temp" );

        // 1.2) set the container configuration to bootstrap the YAAFI container
        this.cli.setContainerConfigValue( "./tutorial/conf/containerConfiguration.xml" );

        // 1.3) block the main thread until the JVM is terminated
        this.cli.setIsBlocking(true);

        // 1.4) install a JVM shutdown hook to dispose the YAAFI container
        this.cli.setHasShutdownHook(true);

        // 2) initialize the logger

        ConsoleLogger consoleLogger = new ConsoleLogger(ConsoleLogger.LEVEL_DEBUG);
        this.cli.setLogger( consoleLogger );

        return this;
    }

    public void run()
    {
        try
        {
            this.cli.initialize();
            this.cli.getLogger().info( "The application is up and running ..." );
            this.cli.onWait();
        }
        catch (Throwable t)
        {
            String msg = "Running the server failed due to : " + t.getMessage();
            this.cli.getLogger().error(msg,t);
            throw new RuntimeException(msg);
        }
    }
 }
          

Using Another Avalon Container

Emebdding YAAFI into another Avalon container might sound like a no-brainer but YAAFI was successfully integrated as Avalon service in the JAMES mail server using the Phoenix container. The ugly truth behind it is the fact that Avalon services might not be portable across different Avalon service containers which definitely is a no-brainer.

<block name="fulcrum-yaafi" class="org.apache.fulcrum.yaafi.framework.container.ServiceContainerImpl" />

<fulcrum-yaafi>
  <containerFlavour>phoenix</containerFlavour>
  <componentRoles>
    <location>../conf/componentRoles.xml</location>
  </componentRoles>
  <componentConfiguration>
    <location>../conf/componentConfiguration.xml</location>
  </componentConfiguration>
</fulcrum-yaafi>