Spring 3.0 + Hibernate 3.3.2 + JBoss Cache 2 + JTA = Fail

I’ve spent the past two days trying to get a distributed secondary Hibernate cache working with a Spring 3 application.  The application is web-based running on JBoss 5.1 so I figured the best approach would be to use JBoss Cache, since it’s automatically configured and available in JNDI when you use the “all” configuration.

Hibernate 3.3.2 is configured inside of Spring using the Annotation-based session factory bean.  Because I’m using JTA to manage transactions and Hibernate’s current session, I need to make sure that the secondary cache, whatever I choose, is aware of the transaction manager.  I originally had EHCache 2.0.1 hooked into Hibernate via Hibernate configuration parameters passed into Spring’s bean.  I was not setting the cache factory parameter on this bean.  Everything works fine in this configuration and it recognizes the JTA transactions.

This application needs to be clustered horizontally – ensuring each component of the solution is failover-ready.  JBoss Cache 2 is baked into JBoss AS 5.1 and a logical choice to pick.  Hibernate has an extension JAR and it’s a simple interface, especially when you’re pulling out the cache from JNDI.

The problem?  The JTA transaction manager that Spring proxies isn’t available to JBoss Cache.  JBoss Cache (on JBoss AS) runs at the container-level inside of a different classloader.  Spring holds onto the reference to the transaction manager proxy inside of a ThreadLocal variable which is NOT accessible to the container.  To get around this, I tried using Hibernate’s implementation of the JBoss Transaction Manager lookup class, thinking since it’s JTA it’ll work.

It didn’t.

When I tried bringing up the application, I ran into errors surrounding the current transaction.  At one point, the transaction was timing out during a cache pre-load process the application has.  In another configuration, the application loaded but after a few minutes the app exceptioned out with a stale JDBC connection to the database.  It was obvious to me that the JTA transaction surrounding the cache didn’t sync with the Spring JTA transaction.

I eventually gave up on JBoss Cache and am going with EHCache 2.0 using JGroups to synchronize each node.  The “all” configuration of JBoss AS 5.1 has both JGroups and JBoss Cache preconfigured.  I hooked into the synchronous JGroups UDP configuration, using the same JVM parameters the JBoss XML files use so that my app doesn’t need a special deployment for each server.  Theoretically, the configuration will work in a cluster without having to change anything around.

We’ll see how the clustering works later on but for now, single node in cluster mode is working just fine.

Microsoft WCF Web Services & Java

I spent a good 50+ hours on trying to consume a Microsoft WCF secure web service with a Java solution.  I tried Spring Web Services, Axis2, and looked at Metro/Tango and decided Axis2 was the “easiest” solution.  The web service I’m connecting to implements WS-Security, WS-SecureConversation, WS-Policy, WS-Trust and WS-Addressing (at least) and it’s provided through a .NET 3.5 WCF endpoint.

It doesn’t work.

Axis2 can’t handle SpNego which is a WCF closed protocol allowing two WCF machines to negotiate the credentials between them.  The client has spent way too much money paying me to continue to figure out a Java solution, so I wrote a .NET 3.5 C# client.  Took me literally five lines of code and it’s working.  That’s great for .NET developers but a whole lotta horse shit for the rest of the world.  I’m hoping Axis2’s Rampart module is updated to play nice with WS-SecureConversation and a .NET WCF web service.  Until then, I’m using the .NET client to download the data and I’m storing the SOAP body into a database table.  On the Java side, I’m still using JAXB2 to unmarshall the data into Java objects and process it through our existing persistence framework.

Go me!

An idea for a college course :: Unit Testing

After spending a significant amount of time this week on writing JUnit tests for a Spring Web app, I’ve come to a conclusion.  College courses, even in the grad classes I am taking don’t spend enough time on the concepts behind unit tests.  Granted JUnit and NUnit has been covered in the classes I’ve had but really only the testing framework is discussed.

Test-driven development (TDD) teaches us how to write a test first, make it fail, stub out your methods, and then code until your test passes.  The practicality of TDD in the real world is limited because a requirement is to have your system well designed up front.  Getting to a point where you’ll know method names ahead of time means you’ve spent a significant amount of time thinking about the design and analyzing that design. 

We all know that is rarely the case.

There needs to be a course on the concepts that we need to keep in mind when designing a system so it can be tested later.  What kind of concepts?  Understanding exactly what you shouldn’t do to make tests difficult – limited coupling and high cohesion.  I started to get a better idea of those concerns when I took a training course on the Spring Framework.  Spring lets you use plain old Java beans for most of your core controllers which lets you test the functionality of the controller and not have to test the framework.  Keeping those concepts in mind during your development will help out later.

In this last semester I took a software engineering course.  In one of the lessons, a simple rule came up that I felt was totally appropriate for this theoretical Unit Testing course.  Any methods you create should only take the exact type of arguments you’ll use in that method.  If the method calculates a pay increase for an employee, the method should take float for the current pay and a float for the percentage increase.  Creating a method signature with an Employee object and something like an AnnualReview object doesn’t define the method, it only confuses the developer.  How can you write a JUnit when you don’t know what the method is going to use?

So that’s enough of my rant for now.  I think I’ve written more in this post than I did for my final paper in the class.  Ha!

Springs of a Different Color

So I spent most of the past few months learning the bleeding edge of the Spring Framework, 2.5.x.  The training I went to covered this version, the books I had covered the same.  My first assignment?  Using Spring 2.0 and Web Flow 1.  Talk about crushed.  Now I have to unlearn everything and go back to a previous version.  This happens a lot, from what I’ve seen.  Companies aren’t willing to upgrade because of fear of stuff breaking; but they’ll write shit loads of work-around code to keep old solutions working.  That eventually bites them in the ass when the product they’re on goes off support and they’re forced to do a huge conversion.

Fun stuff.