Apr 30 2010

Atomikos + ActiveMQ + Hibernate

Category: ActiveMQ,Atomikos,Java,Maven,Spring FrameworkRussell Pitre @ 9:37 pm

I recently tasked myself to put together a sample project using Atomikos TransactionsEssentials. This sample project consists of Spring 3, Hibernate 3.4, Apache ActiveMQ 5.3, and of course Atomikos TransactionsEssentials.

TransactionEssentials is an open source XA transaction manager built on top of their transaction kernel called ‘icatch‘. Essentials has basic support for JDBC/XA, JMS/XA, & JTA/XA. Once you register with Atomikos you will receive a link to download TransactionEsentials and a Maven repository url via email, we’ll proceed with the later.

Once you have the Atomikos maven repository url, either add it to the repository section of your pom.xml or add it to your internal maven repository.


<properties>
	<atomikos.version>3.5.11</atomikos.version>
	<activemq.version>5.3.1</activemq.version>
	<springframework.version>3.0.2.RELEASE</springframework.version>
</properties>

<!-- 
	Atomikos dependencies used for XA
-->
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions-jms</artifactId>
	<version>${atomikos.version}</version>
</dependency>
<dependency>
	<groupId>com.atomikos</groupId>
	<artifactId>transactions-hibernate3</artifactId>
	<version>${atomikos.version}</version>
	<exclusions>
		<exclusion>
			<artifactId>hibernate</artifactId>
			<groupId>org.hibernate</groupId>
		</exclusion>
	</exclusions>
</dependency>

<!-- 
	Microsoft JDBC driver
-->
<dependency>
	<groupId>com.microsoft</groupId>
	<artifactId>sqljdbc</artifactId>
	<version>2.0.0</version>
</dependency>

<!-- 
	Spring framework dependencies
-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>${springframework.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jms</artifactId>
	<version>${springframework.version}</version>
</dependency>

<!-- 
	Hibernate dependencies
 -->
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>3.4.0.GA</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.4.2</version>
</dependency>

<!-- 
	ActiveMQ dependencies
 -->
<dependency>
	<groupId>org.apache.activemq</groupId>
	<artifactId>activemq-core</artifactId>
	<version>${activemq.version}</version>
</dependency>

Here’s the spring configuration:


<?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:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<bean id="userTransactionService" class="com.atomikos.icatch.config.UserTransactionServiceImp" init-method="init" destroy-method="shutdownForce">
		<constructor-arg>
			<props>
				<prop key="com.atomikos.icatch.service">com.atomikos.icatch.standalone.UserTransactionServiceFactory</prop>
			</props>
		</constructor-arg>
	</bean>

	<bean id="AtomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close" depends-on="userTransactionService"> 
	   <!--  When close is called, should we force transactions to terminate or not?  --> 
	   <property name="forceShutdown" value="false" /> 
	</bean>
 
	<bean id="AtomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp" depends-on="userTransactionService"> 
	   <property name="transactionTimeout" value="300" /> 
	</bean>
	
	<!--  
	   Configure the Spring framework to use JTA transactions from Atomikos   
	-->
	<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" depends-on="userTransactionService">
		<property name="transactionManager" ref="AtomikosTransactionManager" />
		<property name="userTransaction" ref="AtomikosUserTransaction" />
	</bean>

	<bean id="datasource" class="com.atomikos.jdbc.AtomikosDataSourceBean" init-method="init" destroy-method="close">
		<property name="uniqueResourceName" value="XADBMS" />
		<property name="xaDataSourceClassName" value="com.microsoft.sqlserver.jdbc.SQLServerXADataSource" />
		<property name="xaProperties">
			<!--
				set the driver-specific XADataSource properties (check your driver docs for more info)
			-->
			<props>
				<prop key="user">dbuser</prop>
				<prop key="password">dbpass</prop>
				<prop key="URL">jdbc:sqlserver://dev-server;databaseName=SomeDB;applicationName=XA-Sample</prop>
			</props>
		</property>
		<property name="minPoolSize" value="1" />
		<property name="maxPoolSize" value="50" />
	</bean>

	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="configLocation" value="classpath:hibernate.cfg.xml" />
		<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
		<property name="dataSource" ref="datasource" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.transaction.factory_class">com.atomikos.icatch.jta.hibernate3.AtomikosJTATransactionFactory</prop>
				<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
			</props>
		</property>
	</bean>

	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>
   
   <!-- ActiveMQ Setup -->
   
	<bean id="jmsXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
		<property name="brokerURL" value="tcp://dev-server:61616" />
		<property name="userName" value="user"/>
		<property name="password" value="password"/>
	</bean>
   
	<!-- Configure the JMS connector; call init to register for recovery! -->
	
	<bean id="amqConnectionFactory" class="com.atomikos.jms.AtomikosConnectionFactoryBean" init-method="init">
		<property name="uniqueResourceName" value="XAactiveMQ" />
		<property name="xaConnectionFactory" ref="jmsXaConnectionFactory" />
		<property name="poolSize" value="5"/>
	</bean>

	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="amqConnectionFactory"/>
		<property name="receiveTimeout" value="2000" />
		<property name="sessionTransacted" value="true" />
	</bean>
        
	<tx:annotation-driven transaction-manager="jtaTransactionManager" />
	
	<context:component-scan base-package="com.company.application"/>
	
	<context:annotation-config/>

And that’s about it for the setup of the infrastructure components. You should be able to @Autowire a JmsTemplate, PlatformTransactionManager (or use @Transactional) and SessionFactory in your application classes.


@Repository
public class SomeEntityDaoHibernateImpl implements SomeEntityDao {

	@Autowired
	private SessionFactory sessionFactory;

	@Autowired
	private JmsTemplate jmsTemplate;
	
	@Transactional(readOnly=true)
	public SomeEntity getSomeEntity(Integer entityId) {
		return (SomeEntity ) sessionFactory.getCurrentSession().get(SomeEntity .class, entityId);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	public void updateSomeEntity (SomeEntity someEntity ) {
		sessionFactory.getCurrentSession().update(someEntity );
		jmsTemplate.convertAndSend("MyCompany.SomeCompany.UPDATE", "Entity updated ["+new Date()+"]: " + someEntity.toString() );
	}


Jul 29 2009

maven-jaxb-plugin

Category: Java,JAXB,Maven,XMLRussell Pitre @ 8:25 pm

I’ve recently started an extranet based webapp that will be consuming a web service hosted on an intranet webapp.   On both the server and client sides i’m using Spring Web Services.  Spring WS provides a nice Object/XML (OXM) mapping abstraction layer that supports a few different oxm frameworks like JAXB, Castor, and XStream.  I haven’t had experience with any of them before this project so I chose JAXB only because it seems to be the most widely used.

A best practice is top-down, or contract first development when designing web services.  A really good place to start with SOA development is Web Service Contract Design and Versioning for SOA by Thomas Erl.

The first step i took was to define the data model for the messages with xml schema. I discovered a great Maven plugin to generate source code from the XSDs for the web service.  Here’s the snippet that i used in my pom.xml

<plugin>
	<groupId>com.sun.tools.xjc.maven2</groupId>
	<artifactId>maven-jaxb-plugin</artifactId>
	<executions>
		<execution>
			<phase>generate-sources</phase>
			<goals>
				<goal>generate</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<schemaDirectory>src/main/resources/com/mycompany/xml/schema</schemaDirectory>
		<includeSchemas>
			<includeSchema>**/*.xsd</includeSchema>
		</includeSchemas>
		<includeBindings>
			<includeBinding>**/*.xjb</includeBinding>
		</includeBindings>
		<verbose>true</verbose>
		<removeOldOutput>true</removeOldOutput>
	</configuration>
</plugin>