Setting up Spring application & webapp contexts correctly in Java integration tests

When integration testing Spring web applications you would often pull in the applicationContext.xml and the appropriate *-servlet.xml file using the @ContextConfiguration annotation within the junit test class. The problem is that this loads both sets of beans into the same context which is different from when tcServer loads the webapp for real. In a real server, the application context is loaded into the 'root' context and each servlet into it's own separate context which is dependent on the root (see my set of previous articles for more details).

To properly set up the contexts in a test environment so that they are loaded and treated the same as in a running tcServer you need to tell the test that it's a webapp test using the @WebAppConfiguration annotation and then use the @ContextHierarchy annotation to set up the order in which to load the contexts:

    @ContextConfiguration(locations = { "/applicationContext.xml" }),
    @ContextConfiguration(locations = { "/beacock-servlet.xml" })
public class BeacockControllerIntegrationTest {

cvc-complex-type.2.4.c issues - a few things to check

I've battled with the Spring cvc-complex-type.2.4.c issue on a few occasions but with them far enough apart that I can't remember what the steps are to solve it. This time round I thought I would write it down...

You are writing a Spring-based app and you have some of your bean declarations in XML (I also use annotations but that's not important here). You wire your beans, you write your code and you build your application. Everything compiles and builds correctly, you run up your app in your container (in my case the dreaded Glassfish) and BOOM:

Caused by: org.xml.sax.SAXParseException;
    lineNumber: 30; columnNumber: 76;
    cvc-complex-type.2.4.c: The matching wildcard is strict,
    but no declaration can be found for element 'jms:listener-container'.
Here are a few things to check:

Check that you have a element in your XML of the mentioned type, in my case it complained about 'jms:listener-container' and I correctly had this in the config:
Check that you have the mentioned namespace declared correctly, it complained about 'jms:listener-container' and I correctly had this in the beans header part of the XML:
As you can see I've declared the xmlnss:jms and then put the correct schema location URL in as well.

None of this was the problem, in fact the problem wasn't to do with mistakes in the XML configuration, or incorrect namespace URLs or even whether the correct SAX parser was being used (look out for this one though).

The problem was that the spring jms schema file couldn't be found, the Spring XML parser doesn't go to the internet to get the schema files, it looks for them in the Spring jars. I'd completely forgotten to declare the use of sping-jms in my maven config and so it couldn't find the Spring JMS schema.

By adding the following to my Maven project sorted out the issue:

Why couldn't the XML parser have told me that it couldn't find one of the schema files?!?! >:O

Java Date & Time manipulation using Apache Velocity

Apache Velocity is an excellent tool if you need to bang out a quick bit of XML output or a text file with a particular layout and you don't want to do it all in Java. You create a Velocity template with your text in it and use various place-holders for the dynamic data that will be passed into it from your Java code. Velocity them merges the two together to give you a nicely formatted custom-filled file/document/SOAP request/etc.

It's a great tool but does have it's quirks and downsides and one that I hit upon recently was how to display dates in a particular format. You can call methods on any Java object that you pass to the template but only if it's in the Java bean standard format of getX() and the Date formatting methods don't follow this standard.

The solution was found within the optional Velocity-Tools library - DateTool. DateTool has a number of format methods on it which can twist the dates and times into any format that you need, here are some examples:

Date & Time together

This in the template:

$dateTool.format('default', $testDate)
$dateTool.format('full', $testDate)
$dateTool.format('long', $testDate)
$dateTool.format('medium', $testDate)
$dateTool.format('short', $testDate)
Gives this in the output:
03-Jan-2012 00:00:00
Tuesday, 3 January 2012 00:00:00 o'clock GMT
03 January 2012 00:00:00 GMT
03-Jan-2012 00:00:00
03/01/12 00:00

Just Dates

This in the template:
$dateTool.format('default_date', $testDate)
$dateTool.format('full_date', $testDate)
$dateTool.format('long_date', $testDate)
$dateTool.format('medium_date', $testDate)
$dateTool.format('short_date', $testDate)
Gives this in the output:
Tuesday, 3 January 2012
03 January 2012

Just Times

This in the template:
$dateTool.format('default_time', $testDate)
$dateTool.format('full_time', $testDate)
$dateTool.format('long_time', $testDate)
$dateTool.format('medium_time', $testDate)
$dateTool.format('short_time', $testDate)
Gives this in the output:
00:00:00 o'clock GMT
00:00:00 GMT

Beware of JavaScript's parseInt function - 010 does not equal 10...

I use JavaScript & jQuery quite a bit in my day job helping to add a bit of 'shiny' to our web applications. One feature that I added recently kept a track of the percentages that you had typed in the form.  It told you at the bottom of the page how much percentage you had left - I used JavaScript's parseInt function to help me in this respect.

As the application passed through system test it was found that if you typed '020' as a percentage my application said that you had 84% left to assign rather than the expected 80% - any ideas what's going on?

Yes that's right - the leading zero was causing parseInt to treat the number as an octal (base 8) number and so 020 was two lots of 8 = 16. It appears that this octal recognition is being deprecated but who knows when it will actually go so for now I've had to add ", 10" (i.e. a decimal radix) to the end of all of my parseInt calls:

parseInt(percentage, 10);
Double check any code that you use which uses parseInt to make sure it doesn't trip you up in the same way that I way!

Do 'is' boolean methods work in JSPs with JSTL?

When coding in JSTL you often want to use conditional logic (I'm thinking and the like) to be able to structure your page correctly. Auto-generated getter & setter methods will normally create isX() methods for the getters of boolean values (at least in Eclipse it does) but can you access this method directly from JSTL without writing a getX() version?

Does JSTL support 'is' boolean methods though? Ask a random poll of Java we developers and you will get conflicting answers so I decided to investigate, want the short answer?

YES - JSTL does support accessing isX() methods directly as if you were accessing a getX() method, but only if the return type of the isX() method is a primative boolean. If you return an object of any kind (such as Boolean isObjectBooleanTrue()) then JSTL fails to find the method and will give you a rather nasty JSP exception:

javax.el.PropertyNotFoundException: The class 'com.andrewbeacock.BooleanTest' does
not have the property 'objectBooleanTrue'.
So yes, 'is' methods work in JSTL but make sure you ONLY return primitive booleans from them.

How to stop Eclipse reformating your Java enumerations & comments

Eclipse is a wonderful IDE for the Java language and I’ve used it daily for at least the past 4 years but it does have some 'issues'. One is regarding it’s code formatting (or reformatting) support, normally it does a great job of putting stuff in the right place but there are occasions where it just fails to get it right.

When I write enums I like to have each item on it's own row, I find it's easier to read and amend in the future:

public enum Family {
But Eclipse has other ideas and formats it so that it looks like this:
public enum Family {
A way to get around this (and any other times where you have a few lines of code that you don't want collapsing into one is to add the double-slash style code comments to the end of each line:
public enum Family {
    MOTHER, //
    FATHER, //
    DAUGHTER, //
Block comments

I recently wanted to have a decent sized chunk of XML stored within Java's block comments (/* ... */) so that I could refer to it as I coded a mapping class. Everytime I saved the class Eclipse reformatted my XML so that it looked like someone had been sick on the page.

After a little digging I found this gem buried in the original coding conventions document from Sun back in 1997:
Block comments can start with /*-, which is recognized by indent(1) as the beginning of a block comment that should not reformatted.
    Taken from section 5.1.1 of Java Code Conventions

Now I'm pretty damn sure that Eclipse doesn't use indent for it's layout but I tried it anyway and it works a treat! Simply add the minus sign to the start of the block comment section and it will leave the whole block comment alone:
            XML which we don't want

Always note DNS server settings offline

Had a strange experience this evening - complete loss of the internet. My router was suggesting that I had ASDL connectivity, and even an IP address but I wasn't able to load any websites. After a bit of debugging with the help of a remote friend I figured out that I wasn't able to connect to my OpenDNS name servers and so wasn't resolving for me.

I updated my router with Google's DNS settings and was back in play - just goes to show that what appears to be an ISP outage can be a case of name servers not being available at that time.

Make sure you make a note of a few free DNS server details (i.e. both OpenDNS and GoogleDNS) offline so you can try them out if you ever end up 'offline'!

Misleading wiring messages with aliased Spring DataSources

When accessing databases in Spring you commonly use a dataSource.xml file of some description to hold the XML stanzas describing the connection details to various databases or schemas.

When dealing with multiple dataSource requirements you might find that more than one logical dataSource bean name actually points to the same physical connection. Rather than define multiple datasource stanzas with exactly the same details, Spring allows the use of the element to point easily to an existing bean but use a different name:

<bean id="personDataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="jdbc:oracle:thin:@database:port:SID" />
        <property name="username" value="USER" />
        <property name="password" value="PASS" />
        <property name="validationQuery" value="select 1 from dual"/>

    <alias alias="customerDataSource" name="personDataSource"/>
BUT (this is the whole point of this blog post really!)

If you get wiring errors when Spring tried to wire data sources into other beans it DOESN'T see aliased beans as first class citizens, when the error reports which data sources are available it won't list the aliased names, suggesting that you actually have less data sources than you really do!

So although aliases are great (and have saved me loads of lines of duplicated XML config) make sure you consider that they won't be shown in lists of 'available data sources'.