Tuesday 13 December 2011

Spring and the transaction annotation (part1)

Okay, I know this is documented in the spring documentation, but it's easy to forget and it can really trip you up, but if you are calling from within a class to another method on the same class that is marked as transactional you won't get the transaction you are expecting.

But how are you supposed to catch these bugs in test code? Easy mock comes to the rescue again....

Let me explain

Spring has made it really easy to test your code. It ships with a full test harness and enables you to override the classpath with certain resources when running certain testcases. So how does this help?
Well, mock out the jpa layer! That way you can see AND TEST when a transaction starts and when it ends.

  

so that basically says to Spring "hey, if you want to use that entity manager bean, you know, the one that implements javax.persistence.EntityManagerFactory, then use EasyMock's factory method called 'createStrickMock'."

so how does this work in code then?

I'll get to that in part 2!

Vargs bites agian

This caught me out the other day. Perhaps it shouldn't have done, but I thought it was interesting enough to write down.

The method looked like
public void myMethod(String... something);

I was trying to mock it out and was expecting it to be called with an empty argument list...

I initially tried to clever and though, "well, I know that arguments are autoboxed into an array, so I guess this will happen"
     EasyMock.expect(myObject.myMethod(EasyMock.arrEq(String[]{})));


hmmmm... no joy.... it went pop at runtime...

turns out that vargs is even more surprising that I first thought....

the expectation I was looking for was
     EasyMock.expect(myObject.myMethod());

simple when you've seen it!

Thursday 3 November 2011

Spring with easymock

I was busy the other day setting up my spring environment so I could inject a load of easymock objects into my spring beans. After a bit of a google it turns out its really easy!

To override a bean in a test you just need to insert the following classpath override annotation into your junit test class and point it to your XML file with the spring bean you want to make an easymock object redefined therein.

@ContextConfiguration(locations = { "classpath:persistenceOverride.xml" })
public class MyTest extends AbstractJUnit4SpringContextTests
{
    @Test
    public void yourTestHere()
    {
    }
}

and the xml...
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" 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
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/jee 
    http://www.springframework.org/schema/jee/spring-jee-3.0.xsd 
    http://www.springframework.org/schema/util 
    http://www.springframework.org/schema/util/spring-util-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">


 <bean class="org.easymock.EasyMock" factory-method="createStrictMock" id="entityManagerFactory">
  <constructor-arg type="java.lang.Class" value="javax.persistence.EntityManagerFactory"> </constructor-arg>
</bean> 
</beans> 

The things to node here are the factory-method definition that lets spring know how we want to create our mocked entity manager factory (i.e. org.easymock.EasyMock.createStrickMock(javax.persistence.EntityManagerFactory.class());

Thursday 13 October 2011

Glassfish, clusters and ejbtimers

After days lost to this feature, I thought I'd write a quick how-to guide on getting the ejbtimer app to behave on a cluster with UCP enabled in the database (so we have a solution which enables FCF to work).

(i.e. setting the resource type to javax.sql.XADataSource and the driver implementation to the oracle.ucp.jdbc.PoolXADataSourceImpl)

The Problem
When publishing an application to the glassfish cluster, I'd get lots of EOFException on a node of the cluster. Some nodes would start, others would not and have this EOFException thrown when trying to read EJB__TIMER__TBL.BLOB. Looked like a race condition on startup yo me... so back to my app to figure out what I was doing wrong....

The Solution
Turned out, nothing! It was all because I was being too cautious on exposing the ejbtimer resources only to the cluster. Basically I was only letting the node see the EJBTimer resource I had setup  pointing to an oracle database. It turns out that when I allowed the DAS to see the same resource, all behaved itself. I guess the DAS must get envolved on startup of the ejb-timer-service... who would have thought!