Sunday, 26 June 2011

Integrating: Jetty, Spring, AspectJ, Wicket, Hibernate, MySQL, ActiveMQ and Atomikos (web archive scope)

Overview


The Spring framework has long provided an attractive alternative to J2EE application servers (especially prior to the arrival of JavaEE 6). Development teams often opted to go for a setup that uses Spring to manage the application context, coupled with a plain Servlet/JSP container and a good ORM solution.

Indeed, the "Jetty/Tomcat + Spring + Hibernate" stack has served many projects. As growth and complexity kicks in, things like JMS and (not long after that) XA transactions, start becoming a necessity.

It is at that point that teams start discussing the use of an application server, in order to gain a "certified" stack that combines all of the above (and more) facilities. However, some teams want to keep on using the "roll your own" path, by adding these aspects into the mix.

In this entry I will describe a setup that combines the most common JEE APIs using a custom assembly of components. The setup comprises of:

  • Jetty 7.3.1 (Servlet/JSP)
  • Spring 3.0.5 (CDI)
  • AspectJ 1.6.10 (because it is cool)
  • Atomikos 3.7.0 (JTA with XA support)
  • Hibernate 3.6.0 (JPA)
  • ActiveMQ 5.5.0 (JMS)
  • MySQL (JDBC, using driver 5.1.15)

Note that all of the above are integrated at the Web Archive level (i.e. the libraries are all included in WEB-INF/lib with nothing placed in the JVM classpath). This is because I often choose to "embed" Jetty when working in this mode, using my own custom launcher.

The basics: a Spring-enabled WAR, with Wicket managing the presentation


Since we will use Spring to inject all of the resources (JTA, JDBC connections, JPA Persistence Units, JMS, ...), the first step is to create a Spring-enabled WAR. In this step, we will also integrate Apache Wicket to take over page generation (sorry, but I have long hated JSF and JSP with a passion, so these are the first thing I want to get rid of.

So, we start by updating our web.xml as follows:




 My own near-JEE stack

 
  Wicket mode (development/deployment)
  wicket.configuration
  
  
  development
 

 
  my.app.filter.wicket
  org.apache.wicket.protocol.http.WicketFilter
  
   applicationClassName   my.Application  
 
 
  
  my.app.filter.wicket
  /*
 

 
  Main Spring context configuration file
  contextConfigLocation  
  /WEB-INF/applicationContext.xml
 

 
  
  org.springframework.web.context.ContextLoaderListener
 

 
  BASIC
 


This is all that is needed for web.xml. The rest of the magic lies totally within Spring's configuration file (/WEB-INF/applicationContext.xml).




 
 

 
 

 
 

 
 



Note that the references to META-INF/spring/... are presented in the following sections.

Adding the Atomikos JTA implementation


The next step is to create the META-INF/spring/tx-services.xml where we instantiate the Atomikos transaction manager and bind it as our JTA implementation. Note that this is where we need to explaing to Spring that we are using AspectJ and therefore the @Transactional annotation must be handled via @Configurable at the class implementation level.




 
 
  
  
 
 
 
  
 

 
 
  
  
 

    
        
    

    
    


Integrating ActiveMQ as a JMS provider that uses Atomikos for transaction management


The next step is to create the META-INF/spring/jms-services.xml where we define the ActiveMQ broker and tell it to interact with Atomikos for participating in transactions...




 
 
  
  
         
    
   
  
  
   
    
    
    
    
    
    
   
  
 

 
 
  
  
  
 

 
  
   
  
  
   
  
 

 

 
  
  
 

 

 
  
 


Integrating Hibernate as a JPA provider that uses Atomikos for transaction management


Last but not least, the META-INF/spring/db-services.xml will add Hibernate to the mix, telling it to interact with Atomikos for participating in transactions.

Important Note 1: that I have a lot of ${database.variable} that I usually load from a property file; you should replace this with whatever values are suitable for your case.

Important Note 2: The hibernate.transaction.factory_class is explicitly shown as commented out, as I have seen quite a few people using it (due to picking up old Atomikos documentation) when it is NO LONGER NEEDED for things to work properly (see the Atomikos forum thread referenced in the comment).




 
  XADBMS
  
   com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
  
  
   
    ${database.url}
    ${database.username}
    ${database.password}
   
  
  
  
  

 

 
 
  
   
  
 

 
    
        
        
        
            
                
                
                
            
        
        
            
                
                 org.hibernate.cfg.ImprovedNamingStrategy
                
                
                 ${database.hibernate.hbm2ddl}
                
                
                
                    com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup 
                 
            
        
    


Important Note 3:Remember to use JTA mode for transactions in your persistence.xml, as in:


...

2 comments:

Tarka said...

I would not recommend using ActiveMQ with XA, its support is incomplete; specifically Propagation.REQUIRES_NEW will have some expected results. See these bug reports:

https://issues.apache.org/jira/browse/AMQ-3022
https://issues.apache.org/jira/browse/AMQ-3479

Interesting facts said...

Thanks for the share. Keep posting such kind of information on your blog. I bookmarked it for continuous visit. Thanks once again.
html5 player| html5 video player