Tag Archives: Spring

Spring MyBatis configuration

Here I describe the project configuration to use MyBatis as ORM and benefit of the transactions management provided by Spring.
For that, we have to add the MyBatis-Spring library to the basic MyBatis.

First, the Maven POM is like:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.3</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.1</version>
</dependency>

And now, the Spring configuration file where we define the SqlSessionFactoryBean:

<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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:xml/*Mapper.xml" />
    </bean>
</beans>

The SqlSessionFactoryBean needs a datasource, and also the location of the MyBatis xml mappers.

Now, the configuration is done and the mappers will be managed by Spring using with this:

<!-- this is the parent of our Mappers. It defines the sqlSessionFactory which is common to all our mapper beans -->
<bean id="mapper" abstract="true">
	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- Place MyBatis Mappers here -->
<bean id="entityMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" parent="mapper">
	<property name="mapperInterface"
		value="net.classnotfound.data.mapper.EntityMapper" />
</bean>

We can see that the mappers are instantiated by the org.mybatis.spring.mapper.MapperFactoryBean which needs a reference to the SqlSessionFactory object we defined earlier.
To avoid some oversights (and reduce the mount of lines I have to write ๐Ÿ™‚ ), I use the “abstract” Spring feature to put the session factory in the abstract mapper, then I can reference it as a parent in all my MapperFactories.

Now the entityMapper we defined is “injectable” in our Spring managed beans and we can use our preferred way of transaction management.

Spring Security with JSF 2 and custom login form

Here, I am integrating Spring Security with JSF 2 using a custom login form.

First, the maven dependencies for Spring-Security (I consider that the JSF project is already set-up, if it is not the case, you can check here):

<properties>
    ...
    <spring.security.version>3.2.4.RELEASE</spring.security.version>
</properties>
...
<!-- Spring-Security dependencies -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${spring.security.version}</version>
</dependency>

In the web.xml, we have to configure the Spring-Security filter as follow:

<!-- Enable Spring Filter: Spring Security works on the concept of Filters -->
<!-- Declare the Spring filter -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<!-- Defines urls pattern on which the filter is applied -->
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Note: if you don’t add the forward to it, the managed bean will not be able to send the request to the filter (I experienced that!!).

We need a simple index.xhtml which will be protected by Spring (I don’t describe it here) and a custom login page which receive the credentials typed by the user.
This page contains only the user name, the password and another field method which is here to show how we can get it on the server:

<h:form id="loginFormId" prependId="false">
    <div class="full-box" style="text-align: center">
        <div class="child-box box-c3">
            <h3>Login</h3>
            <div class="fluid-row">
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputLabel for="username" value="User" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:inputText id="username" required="true"
                            requiredMessage="Please enter username (or go to hell...)" />
                        <h:messages for="username" />
                    </div>
                </div>
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputLabel for="password" value="Password" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:inputSecret id="password" required="true"
                            requiredMessage="Please enter password (otherwise you'll die!!)"
                            name="password" />
                        <h:messages for="password" />
                    </div>
                </div>
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputText value="Authentication" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:selectBooleanCheckbox id="method" name="method" />
                        <h:outputLabel for="method" value="LDAP" />
                    </div>
                </div>
            </div>
            <ui:fragment rendered="${!empty param['error']}">
                <div>Connection failed: user and/or password are wrong.</div>
            </ui:fragment>
            <div id="loginBtnPanelId">
                <h:commandButton id="btnLoginId" value="Login" type="submit"
                    action="${loginManager.doLogin()}" styleClass="loginPanelBtn" />
            </div>
        </div>
    </div>
</h:form>

The form is very simple, we can see the 3 fields and a portion which is conditionally rendered if error param is available.
The content of this form is sent to a managed bean which is responsible of forwarding data to the Spring-Security filter:

import java.io.IOException;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

@ManagedBean
@RequestScoped
public class LoginManager {

    public String doLogin() throws IOException, ServletException {
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/j_spring_security_check");
        dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
        FacesContext.getCurrentInstance().responseComplete();
        return null;
    }

}

Now, we need to have a look to the Spring configuration file, the security is configured as follow:

<security:http use-expressions="true">
    <!-- refers to http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html -->
    <security:intercept-url pattern="/faces/login.xhtml"
        access="anonymous" />
    <security:intercept-url pattern="/css/**"
        access="anonymous" />
    <security:intercept-url pattern="/**"
        access="authenticated" />
    <security:form-login login-page="/faces/login.xhtml"
        authentication-failure-url="/faces/login.xhtml?error=1"
        default-target-url="/faces/index.xhtml"
        authentication-details-source-ref="myAuthenticationDetailsSource"
        username-parameter="username" password-parameter="password" />
</security:http>

We can see that we have to enable anonymous access to the login form (otherwise, you will see some strange messages in your browser, I let you guess why). To have a beautiful login page, we also allow anonymous access to the CSS, the rest of the site has a restricted access controlled by Spring.
As we use a custom login form, the form-login element must indicate which one we want to use with the login-page attribute.
To be able to store the custom field (the method if you forgot it), we have to implement a custom class, it is the one we see in the authentication-details-source-ref attribute.

This is how it is defined in the Spring configuration file:

<bean id="myAuthenticationDetailsSource"
    class="net.classnotfound.jsf.spring.security.security.MyAuthenticationDetailsSource">
</bean>

And the class which implements the org.springframework.security.authentication.AuthenticationDetailsSource interface:

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

/**
 * This class provides a custom AuthenticationDetail which stores the connection
 * type method (Oracle/Ldap)
 *
 */
public class MyAuthenticationDetailsSource implements AuthenticationDetailsSource {

    /**
     * returns the {@link WebAuthenticationDetails} according to LuxFact rule
     * 
     * @param context
     */
    @Override
    public WebAuthenticationDetails buildDetails(final HttpServletRequest context) {
        return new MyAuthenticationDetails(context);
    }

}

This class provides an implementation of a org.springframework.security.web.authentication.WebAuthenticationDetails which will store our extra parameter, its implementation is very simple:

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.web.authentication.WebAuthenticationDetails;

/**
 * this class stores data used for authentication (mainly the authentication
 * method)
 * 
 */
public class MyAuthenticationDetails extends WebAuthenticationDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final String method;

    public MyAuthenticationDetails(final HttpServletRequest request) {
        super(request);
        method = request.getParameter("method");
    }

    public String getMethod() {
        return method;
    }

}

As we can see, this class does nothing else than getting the custom parameter from the request and storing it.

Now, to use this extra parameter, we need to customize the way a user is authenticated. As this task is, by default, done by Spring, it means that we have to write a new class which implements the org.springframework.security.authentication.AuthenticationProvider interface. We can see its declaration in the Spring configuration file here:

<bean id="myAuthenticationProvider"
    class="net.classnotfound.jsf.spring.security.security.MyAuthenticationProvider">
</bean>

<security:authentication-manager>
    <!-- create a custom AuthenticationProvider class to tune the login 
        process -->
    <security:authentication-provider
        ref="myAuthenticationProvider" />
</security:authentication-manager>

And its implementation:

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class MyAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {

        Authentication res = isValid(authentication);
        if (!res.isAuthenticated()) {
            throw new BadCredentialsException("Bad credentials");
        }
        return res;
    }

    private Authentication isValid(final Authentication authentication) {
        Authentication res = authentication;
        System.out.println("Selected method: "+((MyAuthenticationDetails)authentication.getDetails()).getMethod());
        if ("Admin".equals(authentication.getPrincipal())&&"Password".equals(authentication.getCredentials())) {
            res = createSuccessAuthentication(authentication);
        }
        return res;
    }

    @Override
    public boolean supports(final Class authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

    protected Authentication createSuccessAuthentication(final Authentication authentication) {
        // Ensure we return the original credentials the user supplied,
        // so subsequent attempts are successful even with encoded passwords.
        // Also ensure we return the original getDetails(), so that future
        // authentication events after cache expiry contain the details
        final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), authentication.getAuthorities());
        result.setDetails(authentication.getDetails());

        return result;
    }

}

As we can see, the extra parameter is extracted from the org.springframework.security.core.Authentication.getDetails() method.

The whole Spring configuration file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:security="http://www.springframework.org/schema/security"
    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/security http://www.springframework.org/schema/security/spring-security.xsd">


    <!-- Enable security annotations usage -->

    <bean id="myAuthenticationDetailsSource"
        class="net.classnotfound.jsf.spring.security.security.MyAuthenticationDetailsSource">
    </bean>

    <bean id="myAuthenticationProvider"
        class="net.classnotfound.jsf.spring.security.security.MyAuthenticationProvider">
    </bean>


    <security:authentication-manager>
        <!-- create a custom AuthenticationProvider class to tune the login 
            process -->
        <security:authentication-provider
            ref="myAuthenticationProvider" />
    </security:authentication-manager>

    <security:http use-expressions="true">
        <!-- refers to http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html -->
        <security:intercept-url pattern="/faces/login.xhtml"
            access="anonymous" />
        <security:intercept-url pattern="/css/**"
            access="anonymous" />
        <security:intercept-url pattern="/**"
            access="authenticated" />
        <security:form-login login-page="/faces/login.xhtml"
            authentication-failure-url="/faces/login.xhtml?error=1"
            default-target-url="/faces/index.xhtml"
            authentication-details-source-ref="myAuthenticationDetailsSource"
            username-parameter="username" password-parameter="password" />
    </security:http>

</beans>

Source files are available here.

Adding AOP using Spring

I need to add some behavior to my service beans each time I start a transaction. In fact, I am converting a 2-tiers application in a web application, and previously, the users are authenticated using a real Oracle account. This way, they were able to use some user variables, using a proxy user (I will describe it in another post), now, I need to initialize these variables each time the user requests something.
As I want something transparent to the developer, I decided to add a new behavior to my service. The idea is to add a new annotation, next to the usual @Transactional to manage the variables.
Let’s go for AOP journey ๐Ÿ™‚

First, we need to set-up the Maven dependencies, we need the standard Spring libraries and also AspectJ:

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<spring.framework.version>4.0.5.RELEASE</spring.framework.version>
	<spring.security.version>3.2.4.RELEASE</spring.security.version>
</properties>

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.8.1</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.framework.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.framework.version}</version>
	</dependency>
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjtools</artifactId>
		<version>1.8.1</version>
	</dependency>
	
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-test</artifactId>
		<version>${spring.framework.version}</version>
		<scope>test</scope>
	</dependency>
</dependencies>

With AOP, I discovered some vocabulary, the most important for me are:

  • The advice: it represents the actions we want to be executed;
  • the pointcut: it’s when the advice must be executed, some of them are before, after, or around (I will use this one);
  • The aspect: it is the union of the 2 previous concepts.

Now, I have to define the class which must be called to execute whatever I want, meaning the advice:

package net.classnotfound.aop.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class AroundAdvice {

    public Object doBasicProfiling(final ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        System.out.println("Start advice...");
        Object retVal = pjp.proceed();
        // stop stopwatch
        System.out.println("Finished advice!");
        return retVal;
    }
}

This class needs to define a method with org.aspectj.lang.ProceedingJoinPoint in its method signature. This is mandatory to be able to execute my annotated method.

The annotation is only used as a marker:

package net.classnotfound.aop.annotation;

public @interface Advisable {
    //Nothing to do!
}

The service defines a method which is annotated with my tag:

package net.classnotfound.aop.service;

import net.classnotfound.aop.annotation.Advisable;


public class MyServiceImpl implements MyService {

    @Advisable
    public void doSomething() {
        System.out.println("Does something very important!");
    }

    public void doSomethingElse() {
        System.out.println("Does something else more important!");

    }
}

And the trick is done using the Spring configuration file (I prefer using it instead of the annotation config), in which we put all together and tell Spring when the advice must be called:


<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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="myService" class="net.classnotfound.aop.service.MyServiceImpl" />

    <bean id="aroundAspect" class="net.classnotfound.aop.advice.AroundAdvice" />
    <aop:config>
        <aop:aspect ref="aroundAspect">
            <aop:pointcut id="aroundPointCut"
                expression="execution(* net.classnotfound.aop.service.*.*(..)) && @annotation(net.classnotfound.aop.annotation.Advisable)" />
            <aop:around pointcut-ref="aroundPointCut" method="doBasicProfiling" />
        </aop:aspect>
    </aop:config>
</beans>

We can see the pointcut and the aspect definitions.

And now, each time a method which is in defined in a class from the net.classnotfound.aop.service package and annotated with my Advisable tag, the advice is called before (and after) calling the real method.

Note: to order the execution of different advices, we have to use the order attribute on the aspect element.

Now, I will have to add the real implementation of my business, but it is not in the scope of this blog ๐Ÿ˜€

Source files are available here.

Tips: Some time, we need to define an execution order, in my case, it is important that my advice is triggered after the transaction started, to do that, nothing more complicated than adding an order attribute:

<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <tx:annotation-driven order="50"/>
[...]
    <aop:config>
        <aop:aspect ref="aroundAspect" order="100">
[...]
        </aop:aspect>
    </aop:config>
</beans>

By adding this attribute, we tell the AOP engine to process the transactional annotation before mine.

Starting of Spring context in web application

Using Spring in a web application, we need to load the context when the application starts. Fortunately, it can be done in a simple way, by adding the right listener in the application web.xml.

Using Maven, you need to add the Spring-web dependency in your pom.xml:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.0.0.RELEASE</version>
  <scope>compile</scope>
</dependency>

And in the web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Access Spring context from web application

As I am using JSF with Spring, the beans managed by Spring are not accessible in my page, I used this Siegfried Bolz’s blog as a basis and used the facade pattern to hide access to the context.

The Spring context is loaded when the application starts using ContextLoaderListener in the apllication web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

We need the following dependency:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.0.0.RELEASE</version>
</dependency>

Define the object which will reference the Spring context:

package net.classnotfound.spring.context;

import org.springframework.context.ApplicationContext;

public class AppContext {
    private static ApplicationContext ctx;

    /**
     * Injected from the class "ApplicationContextProvider" which is automatically
     * loaded during Spring-Initialization.
     */
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ctx = applicationContext;
    }

    /**
     * Get access to the Spring ApplicationContext from everywhere in your Application.
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
}

Now, define the object that give you access to it:

package net.classnotfound.spring.context;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
 * This class provides an application-wide access to the 
 * Spring ApplicationContext! The ApplicationContext is 
 * injected in a static method of the class "AppContext". 
 * 
 * Use AppContext.getApplicationContext() to get access 
 * to all Spring Beans. 
 * 
 * @author Siegfried Bolz 
 *
 */
public class ApplicationContextProvider implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        AppContext.setApplicationContext(applicationContext);

    }

}

And now this is the facade object which gives access to the Spring beans:

package net.classnotfound.spring.context;

import org.springframework.context.ApplicationContext;

public class ServiceFacade {

	private static ServiceFacade instance = new ServiceFacade();
	
	private static ApplicationContext applicationContext;

	private ServiceFacade() {
		applicationContext = AppContext.getApplicationContext();
	}

	public static ServiceFacade getInstance() {
		return instance;
	}

	//Add here the method to get the different services available 
	// in the Spring Context
	public SpringBean getMyBean() {
		return (SpringBean) applicationContext.getBean("myBean");
	}
}

Don’t forget to ask Spring to create the bean:

<bean id="contextApplicationContextProvider" 
      class="net.classnotfound.spring.context.ApplicationContextProvider"/>

To use it:

SpringBean bean = ServiceFacade.getInstance().getMyBean();

Done!

Bitronix configuration

After a first attempt to configure the JBoss transaction manager includingย  JMS, I finally decided to try the Bitronix transaction manager.

Here is the detail of the configuration.

First of all, you need to add the bitronix jars to your project, using Maven, it’s done very easily (unlike JBossTS, which needs a lot of different dependencies):

<dependency>
    <groupId>org.codehaus.btm</groupId>
    <artifactId>btm</artifactId>
    <version>2.1.3</version>
</dependency>

Now, the configuration, using Spring, as usual (you can retrieve some elements I used with the Narayana 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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <!-- enable transaction demarcation with annotations -->
    <tx:annotation-driven/>
    <tx:jta-transaction-manager/> 

    <!--  Bitronix Transaction Manager embedded configuration -->
    <bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
        <property name="serverId" value="spring-btm" />
        <property name="DefaultTransactionTimeout" value="300" />
    </bean>

    <!-- create BTM transaction manager -->
    <bean id="bitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />

    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
        <property name="transactionManager" ref="bitronixTransactionManager"/>
        <property name="userTransaction" ref="bitronixTransactionManager"/>
    </bean>

<!-- Datasource config -->
    <bean id="dataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
        <property name="className" value="com.informix.jdbcx.IfxXADataSource" />
        <property name="uniqueName" value="expElecCliCoredb" />
        <property name="maxPoolSize" value="5" />
        <property name="driverProperties">
            <props>
                <prop key="user">${user}</prop>
                <prop key="password">${pwd}</prop>
                <prop key="serverName">${serverName}</prop>
                <prop key="databaseName">${database}</prop>
                <prop key="portNumber">${port}</prop>
                <prop key="ifxIFXHOST">${host}</prop>
                <prop key="ifxIFX_LOCK_MODE_WAIT">5</prop>
                <prop key="ifxIFX_XASPEC">Y</prop>
                <prop key="ifxDB_LOCALE">en_us.819</prop>
            </props>
        </property>
    </bean>

    <!-- XA JMS Connection Factory, ensure that the jms server has been yet created (with depends-on or order definitions) 
    otherwise the factory is not available and you will receive an exception 
    (javax.jms.JMSException: error looking up wrapped XAConnectionFactory at /XAConnectionFactory)-->
    <bean id="xaJmsConnectionFactory" class="bitronix.tm.resource.jms.PoolingConnectionFactory"
        init-method="init" destroy-method="close">
        <property name="className" value="bitronix.tm.resource.jms.JndiXAConnectionFactory" />
                <property name="uniqueName" value="jmsConnectionFactory" />
        <property name="minPoolSize" value="10" />
        <property name="maxPoolSize" value="10" />
        <property name="driverProperties">
            <props>
                <prop key="name">/XAConnectionFactory</prop>
            </props>
        </property>
    </bean>

    <!--     The producer sends the messages to be processed on the queue -->
    <bean id="notificationsProducer" class="net.classnotfound.cli.core.service.component.NotificationsProducer">
        <property name="connectionFactory" ref="xaJmsConnectionFactory"/>
        <property name="notificationsQueue" ref="notificationsQueue"/>
    </bean>

    <bean id="notificationService" class="net.classnotfound.core.service.NotificationServiceImpl">
        <property name="authorMapper" ref="authorMapper"/>
        <property name="notificationsProducer" ref="notificationsProducer"/>
    </bean>
</beans>

Concerning this configuration, we can see that the way we configure the datasources is almost the same for database as for JMS. The tricky part comes from HornetQ which creates the JMS connection factory but we cannot access it as a standard Spring bean. It’s why we have to get it from JNDI, resulting in a different configuration using dedicated Bitronix component: bitronix.tm.resource.jms.JndiXAConnectionFactory.

This connection factory is now used by the JMS producer. When we send a JMS message, this call is proxied by Bironix to enlist this action in the transaction.

To start the transaction, we do it as usual using the well-known @Transactional annotation. Doing this, the transaction is automatically started, and when we send the JMS message, it is included in the transaction.

Here an example of its usage:

    public void sendNotification(final String message) throws Exception {
        notificationsQueueConnection = connectionFactory.createConnection();
        notificationsQueueSession = notificationsQueueConnection.createSession(true, 0);
        notificationsQueueProducer = notificationsQueueSession.createProducer(notificationsQueue);

        TextMessage textMessage = notificationsQueueSession.createTextMessage(message);
        notificationsQueueProducer.send(textMessage);
    }

It’s important to note that the session is created in the send method, because following the JMS specification, “Any call to the Connection.createSession method must take place within the transaction”. I tried to create the session in a @PostConstruct, there is no error, you can send your message but… Nothing happens ๐Ÿ™

Done!

JBoss transaction manager (Non XA)

This is my configuration for using the transaction manager implementation provided by JBoss outside of a JEE container. This configuration works for database transaction but not for JMS transaction;
The configuration is done with Spring which delegates the transaction management to the JBoss implementation. Even if I used all the stuff to be able to manage XA transactions, it is not working with JMS. It seems that the messages are not included in the transaction and with the lack of clear documentation to properly configure it, I finally gave up and decided to use an alternative provider.
I present here the configuration to use the JBoss transaction manager I used for database transaction management:

<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven/>
<tx:jta-transaction-manager/> 

<!--     Transactionmanager Config  (uses CORBA??) -->
<!--     <bean class="com.arjuna.ats.jta.TransactionManager" factory-method="transactionManager" id="arjunaTransactionManager"></bean> -->
<!--     <bean class="com.arjuna.ats.jta.UserTransaction" factory-method="userTransaction" id="arjunaUserTransaction"></bean> -->

<!--     Transactionmanager Config  (local, without CORBA??-again...) -->
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple" id="arjunaTransactionManager"></bean>
<bean class="com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple" id="arjunaUserTransaction"></bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" >
    <property name="transactionManager" ref="arjunaTransactionManager"/>
    <property name="userTransaction" ref="arjunaUserTransaction"/>
</bean>

<!-- Datasource config (use XA!)-->
<bean id="ifxXADataSource" class="com.informix.jdbcx.IfxXADataSource">
    <property name="user" value="${user}" />
    <property name="password" value="${pwd}" />
    <property name="serverName" value="${serverName}" /> 
    <property name="databaseName" value="${dbName}" /> 
    <property name="portNumber" value="${port}" />
    <property name="ifxIFXHOST" value="${host}" /> 
    <property name="ifxIFX_LOCK_MODE_WAIT" value="5" /> 
    <property name="ifxIFX_XASPEC" value="Y" />
    <property name="ifxDB_LOCALE" value="en_us.819" />        
</bean>

<bean id="dsXAConnectionFactory" class="org.apache.commons.dbcp.managed.DataSourceXAConnectionFactory">
    <constructor-arg><ref bean="arjunaTransactionManager"></ref></constructor-arg>
    <constructor-arg><ref bean="ifxXADataSource"></ref></constructor-arg>
</bean>

<bean id="pool" class="org.apache.commons.pool.impl.GenericObjectPool">
    <property name="maxActive" value="20"/>
    <property name="minIdle" value="5"/>
</bean>

<bean id="poolableConnectionFactory" class="org.apache.commons.dbcp.PoolableConnectionFactory">
    <constructor-arg name="connFactory" ref="dsXAConnectionFactory"/>
    <constructor-arg name="pool" ref="pool"/>
    <constructor-arg name="stmtPoolFactory"><null></null></constructor-arg>
    <constructor-arg name="validationQuery"><null></null></constructor-arg>
    <constructor-arg name="defaultReadOnly" value="false"/>
    <constructor-arg name="defaultAutoCommit" value="false"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.managed.ManagedDataSource" depends-on="poolableConnectionFactory">
    <constructor-arg name="pool" ref="pool"/>
    <constructor-arg name="transactionRegistry" value="#{dsXAConnectionFactory.getTransactionRegistry()}"/>
</bean>

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.framework.version>4.0.0.RELEASE</spring.framework.version>
    <apache.tomcat.version>7.0.50</apache.tomcat.version>
</properties>

<dependencies>
    <!-- Logging dependencies -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.1</version>
    </dependency>
    <dependency>
        <groupId>ant</groupId>
        <artifactId>ant-apache-log4j</artifactId>
        <version>1.6.5</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>com.informix.jdbc</groupId>
        <artifactId>ifxjdbc</artifactId>
        <version>4.10</version>
    </dependency>
    <dependency>
        <groupId>com.informix.jdbc</groupId>
        <artifactId>ifxjdbcx</artifactId>
        <version>4.10</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.jbossts</groupId>
        <artifactId>narayana-all</artifactId>
        <version>4.17.16.Final</version>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.jboss.spec.javax.transaction</groupId>
        <artifactId>jboss-transaction-api_1.1_spec</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.jbossts.jts</groupId>
        <artifactId>jbossjts-jacorb</artifactId>
        <version>4.17.13.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.logging</groupId>
        <artifactId>jboss-logging</artifactId>
        <version>3.1.0.GA</version>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
</dependencies>

Simple Spring configuration

Spring configuration for use of a simple transaction manager (non XA). The data source must be defined in a JNDI repository (Tomcat in my case).

application.xml:

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

	<bean id="entityManagerFactory"
                class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="org.hibernate.dialect.Oracle10gDialect" />
                <property name="generateDdl" value="false" />
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.connection.SetBigStringTryClob">true</prop> <!-- should be done via system properties -->
                <prop key="hibernate.jdbc.batch_size">0</prop>
                <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>
            </props>
        </property>
    </bean>

	<!-- DBCP data source -->

	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName" value="jdbc/applicationDatasource" />
		<property name="resourceRef" value="true" />
	</bean>

	<!-- the transaction manager -->
	<tx:annotation-driven transaction-manager="txManager" />

	<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<!-- exceptions translation -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

	<!-- persistance annotations -->
	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

</beans>

Maven dependencies:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.framework.version>3.0.7.RELEASE</spring.framework.version>
    <hibernate.version>3.6.9.Final</hibernate.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
</dependencies>

To start automatically the Spring Ccontext, add in your web.xml:

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>