Unity Logo

JMS Transport with Aegis and OpenJMS

This is standalone code if you want to use Aegis (default) binding and OpenJMS. No configuration files need to be touched. And yes, you need to provide the Echo sample.

 This is the server code:

package com.fts89.jms.server;

import javax.xml.namespace.QName;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.handler.AbstractHandler;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.service.invoker.BeanInvoker;
import org.codehaus.xfire.transport.jms.JMSTransport;

import com.fts89.jms.ConnectionFactoryMgr;
import com.fts89.service.Echo;
import com.fts89.service.EchoImpl;

public class Server {

	public static void main(String[] args) throws Exception {
		XFire xfire = XFireFactory.newInstance().getXFire();

		// Register JMS transport
		JMSTransport transport = new JMSTransport(
				xfire,
				ConnectionFactoryMgr.create());
		xfire.getTransportManager().register(transport);

		// Create service
		ObjectServiceFactory serviceFactory =	new ObjectServiceFactory(
				xfire.getTransportManager());
		serviceFactory.addSoap11Transport(JMSTransport.BINDING_ID);
		Service service = serviceFactory.create(Echo.class);
		service.setInvoker(new BeanInvoker(new EchoImpl()));
		serviceFactory.createEndpoint(
				service,
				new QName("e:EchoJMSEndpoint"),
				"jms://Echo",
				serviceFactory.createSoap11Binding(
						service,
						new QName("e:EchoJMSBinding"),
						JMSTransport.BINDING_ID));

		// Register with xfire
		xfire.getServiceRegistry().register(service);
	}

}

This is the code to get ConnectionFactory from your OpenJMS server. Defaults are used so you might not need to change anything. Just start the OpenJMS server and you should be good to go. If you want to use some other implementation of JMS, replace this code with your own.

package com.fts89.jms;

import java.util.Hashtable;

import javax.jms.ConnectionFactory;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class ConnectionFactoryMgr {
	static public ConnectionFactory create() throws NamingException {
		Hashtable properties = new Hashtable();
	    properties.put(Context.INITIAL_CONTEXT_FACTORY,
	                   "org.exolab.jms.jndi.InitialContextFactory");
	    properties.put(Context.PROVIDER_URL, "tcp://localhost:3035/");

	    Context context = new InitialContext(properties);
	    ConnectionFactory factory =
	        (ConnectionFactory) context.lookup("ConnectionFactory");
		return factory;
	}
}

Here is a function which will direct all logs to console. You can call it at the beginning of main().

private static void setupLogger() {
		// setup logging
		ConsoleAppender appender = new ConsoleAppender(new PatternLayout());
		Logger.getLogger(
				org.codehaus.xfire.transport.DefaultTransportManager.class
				).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.service.documentation.XMLDocumentationBuilder.class
		).addAppender(appender);
		Logger.getLogger(
				org.codehaus.xfire.aegis.XMLClassMetaInfoManager.class
				).addAppender(appender);
		Logger.getLogger(
				org.codehaus.xfire.client.XFireProxy.class
				).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.transport.jms.JMSTransport.class
		).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.handler.HandlerPipeline.class
		).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.transport.jms.JMSChannel.class
		).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.transport.DefaultEndpoint.class
		).addAppender(appender);
		Logger.getLogger(
		org.codehaus.xfire.handler.DefaultFaultHandler.class
		).addAppender(appender);
	}

Finally this is the client code. It uses the same ConnectionFactoryMgr as the server above. Also, currently it throws an exception. To correct it you need to replace "contextClient" with "this" at Client.java (either in Debug mode or change the XFire code). I'll update as soon as I manage to fix the client code.

package com.fts89.jms.client;

import java.lang.reflect.Proxy;
import java.net.MalformedURLException;

import javax.naming.NamingException;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.codehaus.xfire.MessageContext;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.client.XFireProxy;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.handler.AbstractHandler;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
import org.codehaus.xfire.transport.jms.JMSTransport;

import com.fts89.jms.ConnectionFactoryMgr;
import com.fts89.service.Echo;

public class Client {

	public static void main(String[] args) throws MalformedURLException, NamingException {
		XFire xfire = XFireFactory.newInstance().getXFire();
		// Register JMS transport
		JMSTransport transport = new JMSTransport(
				xfire,
				ConnectionFactoryMgr.create());
		xfire.getTransportManager().register(transport);

		// Create a ServiceFactory to create the ServiceModel.
        // We need to add the JMSTransport to the list of bindings to create.
        ObjectServiceFactory sf = new ObjectServiceFactory(xfire.getTransportManager());
        sf.addSoap11Transport(JMSTransport.BINDING_ID);

        // Create the service model
        Service serviceModel = sf.create(Echo.class);

        // Create a proxy for the service
        XFireProxyFactory factory = new XFireProxyFactory(xfire);
        Echo echo = (Echo) factory.create(serviceModel, "jms://Echo");

        // Since JMS doesn't really have a concept of anonymous endpoints, we need
        // need to let xfire know what JMS endpoint we should use
        ((XFireProxy) Proxy.getInvocationHandler(echo)).getClient().setEndpointUri("jms://EchoReceiver");

        // run the client!
        System.out.println(echo.echo("hello"));
	}

}






The code is mostly self-explanatory. For the rest study the code and debug

© 2003-2008 Codehaus