Building a Lightweight JMS Provider
by Eric J. Bruno


Listing One
import javax.naming.*;
import javax.jms.*;

// Set the JMS Provider specific properties here.
// This can be read from a file at startup so that it's not hard coded
Hashtable props = new Hashtable();
props.put( Context.PROVIDER_URL, "rmi://localhost:1099/JndiServer" );
props.put( Context.INITIAL_CONTEXT_FACTORY, 
           "jms.jndi.rmi.RmiJndiInitialContextFactory");
Context jmsContext = new InitialContext(props);
// Get a ConnectionFactory object
ConnectionFactory connFactory 
jmsContext.lookup("ConnectionFactory");

Listing Two
import javax.jms.*;
import com.LJMS.*;
// Get the JMS-Light singleton instance
JMSLight ljms = JMSLight.getInstance();
// Get a ConnectionFactory object
ConnectionFactory connFactory = (ConnectionFactory)
ljms.lookup("ConnectionFactory");
// or...
QueueConnectionFactory queueConnFact = (QueueConnectionFactory)
ljms.lookup("QueueConnectionFactory");
TopicConnectionFactory topicConnFact = (TopicConnectionFactory)
ljms.lookup("TopicConnectionFactory");

Listing Three
public class JMSLightTopicConnection extends JMSLightConnection 
                                     implements TopicConnection
{
    public ConnectionConsumer createConnectionConsumer(Topic topic, ...)
    {
        // Call the base class' implementation. Topic extends
        // Destination so no cast is required
        return super.createConnectionConsumer(topic, ...);
    }
    public static ConnectionConsumer _createConnectionConsumer(...)
    {
        // this is where the real work is done...
    }
    // ...
}
// The base class:
public class JMSLightConnection implements Connection
{
    public ConnectionConsumer createConnectionConsumer(Destination dest,...)
    {
        // Because we're using 'instanceof', the downcast is safe
        if ( destination instanceof Queue ) {
            return JMSLightQueueConnection._createConnectionConsumer(
                (Queue)dest, ... );
        }
        else if ( destination instanceof Topic ) {
            return JMSLightTopicConnection._createConnectionConsumer(
                (Topic)dest, ... );
        }
    }
    // ...
}


Listing Four
public void onMessage(Message message) throws Exception
{
    if ( messageListener != null ) {
        // Asynchronous listener
        logger.log("JMSLightMessageConsumer: calling client onMessage()");
        messageListener.onMessage(message);
    }
    else {
        // Synchronous listener
        if ( ! clientBlocking )
            throw new Exception("Synchronous listener in wrong state");
        // Blocking listener, store message and set flag
        logger.log(this + " Storing message for queue " + destination );
        this.message = message;
        // Notify the blocking receiver thread and yield to it
        try {
            notifyAll();
            Thread.yield();
        } 
        catch ( Exception e ) {
            e.printStackTrace();
        }    
    }
}


Listing Five
public class OrderSystem
{
    private JMSLight ljms = JMSLight.getInstance();
    // ...
    public void createDestinations() throws Exception 
    {
        salesTopic = (Destination)ljms.createTopic("SaleItemTopic");
        orderQueue = (Destination)ljms.createQueue("OrderQueue");
    }
}

Listing Six
class Customer extends Thread implements MessageListener {
    // ...
    public void run() {
        salesTopic = (Destination)ljms.lookup( SALES_TOPIC_NAME );
        connFact   = (ConnectionFactory)ljms.lookup("ConnectionFactory");
        Connection conn = connFact.createConnection();
        Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        MessageConsumer saleConsumer = session.createConsumer(salesTopic);
        saleConsumer.setMessageListener(this);
    }
    public void onMessage( Message msg ) {
        // process the JMS message...
    }
}






3

