hanseflow - Unternehmensberatung für Salesforce

Lernen Sie uns kennenLernen Sie uns kennen

JMS (Java Messaging System) ist ein System, um asyncrone Kommunikation verteilter Systeme zu ermöglichen. In Verbindung damit wird eine Unterstützung für das Senden und Empfangen von Objekten anhand mit ActiveMQ realisiert. ActiveMQ ist ein Weitverbreitetes Message-Queue System, welches synchrone/ asynchrone JMS Kommunikation ermöglicht. Dadurch kann sichergestellt werden, dass bei
Nichtverfügbarkeit des Systems keine Nachrichten (String, Objekte) verloren gehen.

Folgende Anleitung ist für Anfänger geschrieben und enthält simplen Java – Code, jedoch ist für dieses Tutorial etwas Vorwissen bzgl. Spring nötig, da wir den Entwicklungsaufwand minimieren wollen und JMS anhand des Spring Frameworks umsetzen. Dafür benötigen wir einige Libs, welche auf Spring.io zu finden sind.

ActiveMQ muss nur entpackt und per cd in die bin Folder gestartet werden. Nach dem Start kann die Oberfläche per “http://localhost:8161/admin/” erreicht werden. Username und Passwort: admin/admin

Um Spring einsetzen zu können und somit auf das JMSTemplate zuzugreifen, welches uns eine Vielzahl von Methoden für JMS zur Verfügung stellt, benötigen wir eine kleine *.xml Datei. Dafür legen wir uns neben der normalen “src” Folder eine “conf” Sourcefolder an und legen darin eine “applicationContext.xml” mit folgendem Inhalt an:

applicationContext

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

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jms="http://www.springframework.org/schema/jms"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/jms
                           http://www.springframework.org/schema/jms/spring-jms.xsd
                           http://activemq.apache.org/schema/core
                           http://activemq.apache.org/schema/core/activemq-core.xsd">

	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL">
			<value>tcp://localhost:61616</value>
		</property>
	</bean>

		<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="CustomerQueue" />
	</bean>

	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="defaultDestination" ref="destination" />
	</bean>

</beans>

Dort legen wir die Adresse von ActiveMQ, unsere Queue (für die zu sendenen Objekte) und das JMSTemplate für die ConnectionFactory etc. fest.

Nun benötigen wir ein Objekt, welches über per JMS verschickt werden soll.

Customer Class

package de.abacus.jmsexample.domain;

import java.io.Serializable;

public class Customer implements Serializable {
	
	private static final long serialVersionUID = 3258332634646933972L;
	private Integer customerId;
	private String name;
	
	public Integer getCustomerId() {
		return customerId;
	}
	
	public void setCustomerId(Integer customerId) {
		this.customerId = customerId;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}

Danach schreiben wir uns eine kleine Sender Class, welche den Versand von Objekt übernehmen soll.

Sender Class

package de.abacus.jmexample.service;

import javax.jms.JMSException;
import javax.jms.ObjectMessage;
import javax.jms.Session;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import de.abacus.jmsexample.domain.Customer;

public class Sender {

	public void sendMessage(final Customer customer) {

		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		JmsTemplate jmsTemplate = (JmsTemplate) context.getBean("jmsTemplate");

		jmsTemplate.send(
				
				new MessageCreator() {
					
					@Override
					public ObjectMessage createMessage(Session session)
							throws JMSException {

						ObjectMessage message = session.createObjectMessage();
						message.setObject(customer);

						return message;
					}
				});
	}
}

Die Sender Klasse umfasst eine „Hauptmethode“, welche sich um den Versand von
ObjectMessages kümmert. Neben der Erstellung eines ApplicationContext, um die Beans
für die ConnectionFactory, Destination (ActiveMQ) und das jmsTemplate aufzurufen, das jmsTemplate initialisiert.
Innerhalb des jmsTemplates wird ein MessageCreator erstellt, der vom Spring Framework
als Interface bereitgestellt wird und eine JMS Message versendet kann. Innerhalb dieses
Interfaces wird eine ObjectMessage erstellt, welche im Gegensatz zu einer TextMessage
echte Java Objekte versenden kann.
Per „message.setObject(customer);“ wird das in der Test Klasse erstellte Objekt
übergeben, das zuvor in der Hauptklasse als Parameter mitgegeben wird.

Nun benötigen wir eine Receiver Klasse, welche das Objekt in Empfang nimmt.

Receiver Class

package de.abacus.jmexample.service;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;

import de.abacus.jmsexample.domain.Customer;

public class Receiver {

	private Customer customer;

	public Customer receiveMessage() throws JMSException {

		@SuppressWarnings("resource")
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		JmsTemplate jmsTemplate = (JmsTemplate) context.getBean("jmsTemplate");

		Message receivedMessage = jmsTemplate.receive("CustomerQueue");
		ObjectMessage msg = (ObjectMessage) receivedMessage;

		customer = (Customer) msg.getObject();

		return customer;
	}

}

Innerhalb der Receiver Klasse befindet sich am Anfang wieder der ApplicationContext, um
das jmsTemplate per Beans verwenden zu können. Per „Message
receivedMessage = jmsTemplate.receive(“CustomerQueue”);“ fragt die Receiver Klasse
das Objekt ab, welches in die ActiveMQ Queue gelegt wurde.
Die erhaltene Nachricht wird durch „ObjectMessage msg = (ObjectMessage) receivedMessage;“ wieder in eine ObjektMessage gecastet und kann, wie gehabt, weiterverwendet werden. Anhand von „customer = (Customer) msg.getObject();“ wird das empfangene Objekt in ein Customerobject umgewandelt.

Das ganze JMS System soll durch einen JUnit Test ausgelöst werden.

JUnit Test

package de.abacus.jmsexample.service;

import java.util.Random;

import javax.jms.JMSException;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import de.abacus.jmexample.service.Receiver;
import de.abacus.jmexample.service.Sender;
import de.abacus.jmsexample.domain.Customer;

@SuppressWarnings("deprecation")
public class ReservationJmsTest {
	private Receiver receiver;
	private Sender sender;
	private Customer customer;

	private Random rnd;

	@Before
	public void setUp() throws Exception {

		@SuppressWarnings({ "resource", "unused" })
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		sender = new Sender();
		
		customer = new Customer();
		customer.setName("Abacus");
		customer.setCustomerId(generateRnd());

		sender.sendMessage(customer);

	}

	@After
	public void tearDownAfterClass() throws Exception {
	}

	@Test
	public void isObjectDelivered() throws JMSException {

		receiver = new Receiver();
		customer = receiver.receiveMessage();

		Assert.assertNotNull(customer);
		
		System.out.println("Objekt erhalten");

	}

	public int generateRnd() {
		rnd = new Random();
		int min = 1;
		int max = 1000;
		int randomNum = rnd.nextInt((max - min) + 1) + min;
		return randomNum;

	}

}

Im Test wird prinzipiell nur ein Customer Objekt erstellt, Name/ID gesetzt und die Methode sendMessage() ausgelöst. Die eigentliche Testmethode umfasst die Erstellung des Receivers und die initialisierung des Customer Objekts. “Assert.assertNotNull(customer);” überprüfen wir, ob der erhaltene customer nicht null ist.

Viel Spaß 🙂

Das Projekt kann hier heruntergeladen werden.

No Comments

Sorry, the comment form is closed at this time.