Performance benchmark for Spring Integration

I was looking for any official performance benchmark for Spring Integration framework,

however was unable to find.

I decided to create my own in order to better understand the framework’s performance ability.

I measured my test on a physical server that has 8 CPU’S.

The producers and the consumers are in the same network on different JVM’SMachines.

The application included two Direct (Queue’s) channels:

Producer1 – > Queue1 -> Consumer1 -> Producder2-> Queue2 -> Consumer2

The message is 6 characters String converted to a ByteArray.

The message measurement starting point at Producder1

For executing 3 million messages:

1. Throughput: ~10,000 m/s

2. Latency:     ~0.1244 ms

Pretty good results compared to the current MQ’s market,

Idan.

Related Articles:

(2167)

Consider messaging integration framework in your architecture

Lately I have been dealing with a new architectural design for my company.

The main target was having all components in the same JVM.

Those components suppose to communicate with each other and the “outside” world, according to many different interfaces.

After planning and drawing all the participating components and connections, I decide to have a completely loose coupling integration.

No more procedure calls/Ejb calls/DI calls/ or any restricting call what so ever.

Each time I used those “dependent” calls I found myself struggling with it in the future.

So I chose to adapt myself a messaging framework.

After reading and researching on the net, I found two attractive messaging frameworks: Apache Camel, Spring-Integration. But since a big part of my project is on Spring, I decided to try “Spring-Integration”.

Think about having an engine, which is completely decoupled from your business logic. That engine gives you the ability to have your business component integrated without being “aware” to each other completely!!

Moreover it will be easier to test or change the entire enterprise framework if needed. Business logic components should concentrate on their business logic completely.

You get out of the box integration patterns tools like: aggregators, splitters, network adaptors, filters which make your integration task very easy and useful.

Let’s not forget the boilerplate code you earn – makes your code very clear and efficient.

So I started to play with Spring-Integration and I found my architecture’s components being very independent and clear in many aspects.

Hope you find it useful as I did,

Idan.

 

Related Articles:

(2167)

Aggregating async results using Spring Integration

Hi,

I came across an issue which has very nice solution using Spring Integration.

Many times we have the need for a scenario of dispatching a message to unknown number of destinations.
For this purpose we have the Topic methodology.

But some times in addition we also want to receive answers from all destinations which received the message and aggregate them to to a single result answer.

For this purpose we can use channels combined with Aggregator and ReleaseStrategy interfaces.

In this post I wont concentrate on the “channels implementation”

So let’s say we have a producer who sends it’s message to a Topic.

Now we have a consumer which receives that message.

Using gateway and a processor interface we can send that message in any type we want:


public interface Processor
{
    public void sendResponse(String response);
}

Consumer code:

@Override public void onMessage(Message message)
{
  String resultMessage = "";
    try
    {
          processor.sendResponse(resultMessage);
    }
    catch (Exception e)
    {
         log.error("Error while processing message in channel consumer. errorMsg=" + e.getMessage(), e);
     }
}

Now the message will be delivered to a channel(“In Channel”) We can add to this message an extra information(in case we have different message groups). After adding an extra information we dispatch that message to another channel (“Out channel”) Now here is the magic: We create two pojo’s that later will be bind to interfaces using the XML configuration. ReleaseStrategy:

public class ReleaseStrategy
{
	public boolean canRelease(List results)
	{
            // check if all 5  subscribers sent responses
		if (results.size() == 5)
                {

			return true;
		}
		return false;
	}
}

Aggregator:

public class Aggregator
{
	public String aggregate(List results)
	{
               String finalResult= "SUCCESS_RESULT";
		for (String result: results) {

			if (result.equals("ERROR_RESULT")) {
				finalResult= "ERROR_RESULT";
				break;
			}
		}

		return finalResult;
	}
}

Basically what happens here is that after we return a “true” value via the canRelease method of ReleaseStrategy Interface the Aggregator will be able to receive the aggregated message and dispatch single result to the final destination(could be a Queue where another message consumer will get and process the result) Xml configuration:

< ?xml version="1.0" encoding="UTF-8"?>

Idan.

Related Articles:

(2167)

Spring integrating with remote Topic

Hi,
I am going to demonstrate how to receive messages from a remote topic.

The remote Topic is placed in a Jboss application server.

1. Add topic implementation jars into spring lib class-path

2. We going to create jmsTemplate makes the java code pretty minimal and simple:

public class TgwMDB implements MessageListener
{

	@Override
	public void onMessage(Message msg)
	{
	}
}

3. Most of the configuration is at the applicationContextXml:

3.1 Declare jmsTemplate:

 	jnp://server.ip:1099
	org.jnp.interfaces.NamingContextFactory
	org.jboss.naming:org.jnp.interfaces

3.2 declare jndiTopicConnFactory.

	

3.3 declare ConnectionFactory:


3.4. declare DestinationResolver:

3.5 declare DefaultMessageListenerContainer which will act as a cached message listener

		 // this property pubSubDomain turns the listener from Queue to Topic.

 


You ready now to receive messages.

Idan.

[ad]

Related Articles:

(2167)

Ejb Injection to Spring from Jboss

Hi,

Here is how we lookup from Spring to jboss:

So let’s say we have Interface implemented in jboss:

com.DestBean

The jndi loopup: /DestBean/remote.

in Spring side:

1. Create a bean which trigger the method:

public class TriggerBean
{
	@Autowired
	DestBean destBean;

	public void test()
	{
		boolean result = destBean.setSomething(1, 2);
		System.out.println("the result is="+  result);
	}
}

Now let’s configure applicationContext.xml:




	
		
		java.naming.provider.url">serverhost:port
		java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
		java.naming.factory.url.pkgs=jboss.naming:org.jnp.interfaces
		
	

pay attention that business-interface attribute should have the value of the class-path of your remote interface placed in the target server.

And that’s it!

Idan.

[ad]

Related Articles:

(2167)

Ejb lookup from StandAlone/Tomcat to Jboss5+

Hi,

Lately I was trying to do EJB lookup from my Web Application (Tomcat 6) to my Jboss project(Jboss5.1)

That should be pretty simple but without the right jars it just wont work.

So:

1. Take all jars from the client dir of jboss (Jboss_home_dir/Client/) and put them under the Lib dir of your web project which deployed under tomcat.

2. The client code which does the EJB look up will look like that:


private void ejbCall() throws NamingException
	{

		Properties p = new Properties();
		p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
		p.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
		p.put(Context.PROVIDER_URL, "jnp://remote.server.ip:1099");
		InitialContext context = new InitialContext(p);
		String lookupStr = "jndi-remote-lookup-string";
		DispactherBeanRemote dispactherBean = (DispactherBeanRemote) context.lookup(lookupStr);
		MomDispatcherResponseMsgDTO momDispatcherResponseMsgDTO =  dispactherBean.dispatchMsg();
		System.out.println("dispactherBean ="+ momDispatcherResponseMsgDTO.toString());
	}

Again, dont forget to add all the jars from the jboss client. Else you will get lots of weird exceptions,

[ad]

Idan.

Related Articles:

(2167)

Define jboss logs in the application level.

Hi,
The next post will demonstrate how to define jboss logs for a specific application
in a way that it will write all it’s logs to an independent log file.

(tested on Jboss5.1 AS)

Under jboss-dir/conf we have file named: jboss-log4j.xml

1. let’s add new appender:

  
     
     
     
     
     

     
       
     
   

2. let’s add category:

   
     < priority value="debug" />
     < appender-ref ref="projectName" />
   

Now on each class we want to use the Logger(which is imported from org.apache.log4j.Logger) we need to use it this way:

public class Someclass

      private final static Logger logger = Logger.getLogger(Someclass.class);
      public dispatchMsg()
      {
         logger.debug("My first log msg");
      }
}

Idan.

[ad]

Related Articles:

(2167)

Creation and Use of Singleton under Jboss5.1 with EJB3.0 Annotations.

Hi,

I had a case where I needed to use the same variable shared between couple of stateless beans.

In a stand alone java program we would set it as Static.

But since we are under Server application container(this case Jboss) we know that the container has pool of EJB’S sessions which is being created for us.

A static variable in such environment might get duplicated(specially in Cluster mode) and therefor wont serve out target.

So for this purpose we will create Singleton class which will hold our “static” variables.
that Singleton class will have only one instance throughout our application deployment.

Some code:

First we create the Singleton interface:

import javax.ejb.Local;

@Local
public interface SingletonBeanLocal
{
	 int getAttribute();
	 void setAttribute(int x);

}

Now we will create Singleton Management class:

* Note: We must implement Management class in order to achieve Singelton MBean.

import org.jboss.ejb3.annotation.Management;

@Management
public interface SingletonBeanManager
{
	 int getAttribute();
	 void setAttribute(int x);
}

Now we are going to implement these Interfaces:

import javax.ejb.Local;
import org.jboss.ejb3.annotation.Service;

@Service(objectName = "jboss:custom=Singleton")
@Local(
{ SingletonBeanLocal.class })
public class SingletonBean implements SingletonBeanManager, SingletonBeanLocal
{
	private int xyz = 0;

	@Override
	public int getAttribute()
	{
		return xyz;
	}

	@Override
	public void setAttribute(int x)
	{
		xyz++;
	}
}

The @Service and @Management combined together will install a Singleton MBean which can also be controlled via JMX console.

Since this Mbean is registered as service it will be the only one installed and it’s “local” variables” could be use as “Static” in our terms.

Now all we need is to Lookup/Inject to the Singleton Mbean and retrieve/set our variables.

Hope you got it,
Idan.
[ad]

Related Articles:

(2167)

Accessing Jboss JMX programmatically

Hi,

The next example will explain how to retrieve attributes from the JMX console via java.

The reason why you want to access the JMX console would be the need of having values which you wont be able to retrieve via the common API.

For example if we want to get the current subscribers of a specific Topic/Queue resource for any purpose
we wont be able to get it via the common JMS API.

We need to access to the JMX(locally or remotely) and read the attribute we desire.

Some code:

An example of connecting to the JMX and accessing the current number of subscribers which listening to a Topic:


public static int getCurrentTopicSubscribers()
	{

		try
		{
		//use this code when you are connecting remotely(outside the jboss container).
			//------------------------------------
//			Hashtable ht = new Hashtable();
//			ht.put(Context.INITIAL_CONTEXT_FACTORY,
//					"org.jnp.interfaces.NamingContextFactory");
//			ht.put(Context.PROVIDER_URL, "localhost:1099");
//			ht.put(Context.SECURITY_PRINCIPAL, "admin");
//			ht.put(Context.SECURITY_CREDENTIALS, "admin");
//			System.out.println("nt 1- Gotting InitialContext...... ");
//			Context ctx = new InitialContext(ht);
			//---------------------------------

                       //(Connection within the jboss container)
		 MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
			server = (MBeanServerConnection) ctx.lookup("jmx/invoker/RMIAdaptor");
			if (server != null)
			{
				monitorJMS();
			}
			else
			{
				log.error("Couldnt connect to JMX server");
			}
		}
		catch (Exception e)
		{
			log.error("Couldnt connect to JMX server");
		}

After we have connection we can easily retrieve the attributes from the JMX:

public static void monitorJMS() throws Exception
	{
		ObjectName objectName = new ObjectName(
				"jboss.messaging.destination:name=DispatcherTopic,service=Topic");
		System.out.println("DurableMessageCount = "
				+ (Integer) server.getAttribute(objectName, new String("DurableMessageCount")));
		System.out.println("AllSubscriptionsCount = "
				+ (Integer) server
						.getAttribute(objectName, new String("AllSubscriptionsCount")));
	}

Idan.
[ad]

Related Articles:

(2167)

Using JMS in Tomcat

Hi all,
Recently I had to use JMS topic in my application. problem was I was working with Tomcat web application.
Tomcat doesnt ship with JMS capabitilites but you can configure and use external JMS and plug it into Tomcat.

There are couple of JMS vendors. I chose to use ActiveMQ.

So first you need to add the following jars to your tomcat lib dir:

activemq-all-5.4.0.jar
commons-logging-1.1.jar

Next, add the resource below to conf/server.xml:










next, add this code to context.xml:




Next, We need to add ActiveMQ props into tomcat class path:

JAVA_OPTS=-Dwebconsole.type=properties
-Dwebconsole.jms.url=tcp://localhost:61616
-Dwebconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/ jmxrmi

In order to start and init our JMS queue we need to add the following code to some class and start it as service so it will get started on server startup:

BrokerService broker = new BrokerService();
// configure the broker
broker.addConnector(“tcp://localhost:61616″);
broker.start();

//use broker.stop() to stop the service.

Now let’s create small application to demonstrate some Topic movemonet:

Producer:

InitialContext initCtx = new InitialContext();
Context envContext = (Context) initCtx.lookup(“java:comp/env”);
ConnectionFactory connectionFactory = (ConnectionFactory) envContext.lookup(“jms/ConnectionFactory”);
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic(“jms/topic/MyTopic”);
MessageProducer producer = session.createProducer(destination);
TextMessage msg=session.createTextMessage();
msg.setText(“Message sent”);
producer.send(msg);

Reciever:
(Now We create some Client in order to retrieve any message which will be dispatch onto our JMS topic)

public class Reciever {

protected Topic queue;

protected String queueName = “jms/topic/MyTopic”;

protected String url = “tcp://localhost:61616″;

protected int ackMode = Session.AUTO_ACKNOWLEDGE;

public static void main(String[] args) {
Reciever rec=new Reciever();
try {
rec.run();
} catch (Exception e) {
e.printStackTrace();
}

}

public void run() throws JMSException{

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
TopicConnection connection = (TopicConnection)connectionFactory.createTopicConnection();

connection.start();
MessageConsumer consumer = null;
Session session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
queue = session.createTopic(queueName);
consumer = session.createConsumer(queue);

System.out.println(” Waiting for message (max 5) “);

for (int i = 0; i < 5; i++) {
Message message = consumer.receive();
processMessage(message);

}

System.out.println(“Closing connection”);
consumer.close();
session.close();
connection.close();

}
public void processMessage(Message message) {

try {

TextMessage txtMsg = (TextMessage) message;

System.out.println(“Received a message: ” + txtMsg.getText());

} catch (Exception e) {

e.printStackTrace();

}
}

Idan.

Related Articles:

(2167)

Sending Object to Restful Web service Straight forward.

Hi,

We all know that Restful services works with HTTP protocol. restful services support xml/jamson.

Problem: I have object and I want to send it “as is” to a restful service.

Solutions: 1. not straight forward: We need to convert that object manually to XML string and send it.
2. Straight forward:
2.a Annotate the object with those annotations:
Class annotations:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
Fields annotations:
@XmlElement(name=”fieldName”)

example: (This has been tested on Jboss5.1.1 AS)

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class SomeObject implements Serializable
{
	@XmlElement(name="m")
	int m = 1;
	@XmlElement(name="g")
	int g = 2;
}

Now in order to send it we need to marshell our object using StringWriter and Marshaller.
Example:

Client side:

                SomeObject  myObject= new SomeObject();
		HttpURLConnection conn = null;
		StringWriter stringWriter = new StringWriter();

		try
		{
			Marshaller m = JAXBContext.newInstance(SomeObject.class).createMarshaller();
			m.marshal(myObject, stringWriter);

			URL url = new URL("http://localhost:8080/MYPROJECT_WEB/hello
                        /testObjects");
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/xml");


			OutputStream os = conn.getOutputStream();
			os.write(stringWriter.toString().getBytes());
			os.flush();

			BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));

			String output;
			System.out.println("Output from Server .... n");
			while ((output = br.readLine()) != null)
			{
				System.out.println(output);
			}

		}
		catch (Exception e)
		{

			e.printStackTrace();

		}
		finally
		{
			conn.disconnect();

		}

Server side:

@POST
   @Path("testObjects")
    @Consumes("application/xml")
    @Produces("text/plain")
	public String testObjects(GrandSun sun)
	{
		System.out.println(sun.toString());
		return "Success";
	}

Idan.

Related Articles:

(2167)

Creating Restful Services using EasyRest for Jboss

Hi,
Here is how we creating simple GET method using EasyRest(Supported perfectly by Jboss).
The method expecting one input of type String and print out it’s value.

First of all if you using Enterprise Application project make sure you add the Rest methods to the Web project.

The class which holds the method logic named: “RestFacade”

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

@Path("hello")
public class RestFacade
{
	@GET
	@Path("sayHello")
	public void sayHello(@QueryParam("input") String input)
	{
		System.out.println(input);
	}
}

* With QueryParam we declaring our rest method to expect input parameter(in our example it’s String).
* with GET we declaring our method to work when GET being invoked.

Now we need to add the following code to WEB.XML:

< ?xml version="1.0" encoding="UTF-8"?>

	YOUR_PROJECT_NAME
	
		index.html

	
	
		resteasy.scan
		true
	

	
		org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap


	
		Resteasy
		org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher


	
		Resteasy
		/*



* make sure you add the right project name and don’t forget to add the listener as shown below.

This is the url in order to trigger the method:

http://localhost:8080/MY_PROJECTWeb/hello/sayHello?input=TestingMyMethod

and the output is: 14:24:01,296 INFO [STDOUT] TestingMyMethod

Idan.

Related Articles:

(2167)

Circular dependency bug at Jboss5.1.1 AS

Hi,  
I have been struggeling this for a week now. This is a seriouse bug at Jboss5.1 and EJB3.

Example for Circular dependence:

In CompanyCoreBean

  @EJB(name = "CompanyCoreBean")
  private CompanyCoreBeanLocal companyCoreBean;

CompanyCoreBean is injected to itself

leading to this jboss error:

DEPLOYMENTS MISSING DEPENDENCIES:
Deployment

“jboss.j2ee:ear=WMA_EXPLODED.ear,jar=

WMA_EXPLODEDEJB.jar,name=CompanyCoreBean,service=EJB3” is missing the following dependencies:
Dependency “<UNKNOWN jboss.j2ee:ear=WMA_EXPLODED.ear,jar=

WMA_EXPLODEDEJB.jar,name=CompanyCoreBean,service=EJB3>”

(should be in state “Installed”, but is actually in state “** UNRESOLVED Demands ‘jndi:WMA_EXPLODED/CompanyCoreBean/local-com.mirs.wma.core.sessionBeans.CompanyCoreBeanLocal’ **”)

Dependency “<UNKNOWN

 

There is an open Jira about the issue. but I had to overcome this one.

So the walk around is using the Annotation @IgnoreDependency. which will Ignore it’s own dependency on deployment.

@IgnoreDependency
@EJB(name = "CompanyCoreBean")
private CompanyCoreBeanLocal companyCoreBean;

Idan.

[ad]

Related Articles:

(2167)

Commit data in the middle of Transaction inside the Container

Hi,

Many times I was dealing an issue inside the Application server’s container(Jboss, Weblogic).

I had the need to commit data(Logs, Database) in middle of Transaction.

For example let’s say I want to update some records in the Database and then do some logic on the UPDATED records within the same transaction.

This wont be possible until the current Transaction will finish it’s work.

So the walk through is starting  new Transaction within the current Transaction.

When the container is already performing a transaction, then starting a new transaction will result in the original being suspended. When the new transaction has committed, the original transaction will be resumed.

I am using EJB3.0. The annotation for starting new Transaction within running transaction is

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
protected void doSomeDatabaseUpdate(...)
{
   //Some logic that must be committed before the main transaction finish
}

The result:
The method doSomeDatabaseUpdate will be invoked inside new transaction
and when finished the data will be committed.
Afterwards we can continue with our logic on the updated
data within the main transaction.
Idan.

Related Articles:

(2167)