Archive for January, 2010

Ubuntu Tomcat JasperServer deployment issue

Saturday, January 30th, 2010

I could not get web applications – in this case JasperServer, but I’m sure it applies to anything – placed in /usr/share/tomcat6/webapps/ to autodeploy, and was therefore getting 404 errors. I am not sure if this is because of the Tomcat install which comes with Ubuntu (which is notoriously bad, although I thought these issues had been resolved?).

The JasperServer install guide is excellent, but at the end it (correctly) assumes the autodeploy will work, and that browsing to http://localhost:8080/jasperserver/ will bring up the login page.

To get around this issue, copy /usr/share/tomcat6/webapps/jasperserver/META-INF/context.xml to /etc/tomcat6/Catalina/localhost/jasperserver.xml and restart Tomcat.

Tomcat Version: 6.0.20
Ubuntu Version: 9.0.4

Log4j and Tomcat issue

Monday, January 25th, 2010

Quick one – I had this issue today so wanted to record it for posterity.

Tomcat can get confused if WEB-INF/lib contains the log4j jar, with initialisation errors such as:

java.lang.ClassNotFoundException: org.apache.log4j.Category

You might not even have directly included it – it might be included via a Maven dependency.

The solution is simple; remove log4j! It’s (often) already included in Tomcat, which is the root cause of the issues. If it’s a Maven dependency, add an exclusion.

Spring Security 3 Setup

Sunday, January 24th, 2010

Getting Spring Security setup only involves a few steps, but it can be confusing to work out exactly what they are – especially since almost all documentation refers to Spring Security 2, and there are a couple of differences.

The first thing to do is to add the Spring Security dependencies to your Maven pom.xml. A good explanation of which ones are needed is located here. In summary though, you probably want the following Artifact ids (Group id is org.springframework.security):

  • spring-security-core
  • spring-security-config
  • spring-security-web
  • spring-security-taglibs

(Note – be careful, for some reason the main Maven repository has a few spring-security-* artifacts under the Group id org.springframework – but they aren’t physically located there and you will get ‘Artifact Not Found’ errors).

After they are downloaded, you need to add the following to web.xml:

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

<context-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>
	/WEB-INF/applicationContext-security.xml
     </param-value>
</context-param>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

The extra context configuration puts all the security related information into a separate Spring xml for clarity (plus a different default namespace – we’ll see this in a minute).

The new filter does exactly as expected – intercepts calls to /* (sub-directories included) and applies the Spring Security rules (which we have yet to define).

As specified above, create the file /WEB-INF/applicationContext-security.xml. This file looks like a normal Spring config file, except instead of the default namespace being beans it is security – this means that all references to tags which are normally valid need to be prefixed with beans: (see below for an example).

Pay attention to this config – it is this file which is slightly different from Spring 2

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans
       xmlns="http://www.springframework.org/schema/security"
       xmlns:beans="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <http auto-config="true">
    	<intercept-url pattern="/client/**" access="ROLE_USER" />
    	<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    </http>

<authentication-manager alias="authenticationManager">
	<authentication-provider>
	  <user-service>
		<user name="ned" password="ned" authorities="ROLE_USER" />
	  </user-service>
	</authentication-provider>
</authentication-manager>	

</beans:beans>

Breaking this file down, the ‘key’ tag is http. The auto-config attribute tells Spring Security to add in all the ‘normal’ configuration properties. As you get more comfortable with Spring Security, you may want to override some of these defaults (e.g. the form to show that captures login information).

The user-service tag adds a single valid user, ned. In a more likely scenario, the user-service will be hooked up to a database to get a list of valid users – that’s an exercise for another day.

The intercept-url patterns are fairly self-explanatory, with one caveat: Spring Security resolves them top-to-bottom, and chooses the first one that matches. Therefore, make sure your more granular, specific patterns are at the top and a catch-all like “/**” goes at the bottom.

Set the above into your Spring application, then try and access your_site/client/whatever.html. All being well, you should be prompted with the default Spring Security login page. Put in the credentials you entered into the user-service and you’re all set. Congratulations, you just secured your website using Spring Security!

SiteMesh with Spring MVC

Monday, January 18th, 2010

SiteMesh is an open source framework that implements the Decorator pattern. It essentially takes the output stream from a web application, and adds elements to (’decorates’) it. Why would we want that? Put simply, it is an incredibly clean way of adding headers/footers/anything, with the underlying jsp (or whatever) having no knowledge of that fact it will decorated. In combination with Spring MVC, this creates a powerful weapon for your developer arsenal.

This tutorial assumes you have an existing Spring MVC project

To enable SiteMesh, first either include the jar in your lib folder or add it as a Maven dependency (opensymphony | sitemesh). Next, add the following to your web.xml:

<filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>
        com.opensymphony.module.sitemesh.filter.PageFilter
    </filter-class>
</filter>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Now we create a new file decorators.xml in WEB-INF. This file tells SiteMesh which files to map, and which ‘decorator’ (which we haven’t got to yet) to use. IMPORTANT – in most guides you see, it will tell you to map WEB-INF/jsp or similar. Remember, Spring MVC is handling the jsp references, so you actually want to point at your html folders/files (Spring MVC totally abstracts the jsp file layer).

<?xml version="1.0" encoding="ISO-8859-1"?>

<decorators defaultdir="/WEB-INF/decorators">
    <decorator name="master" page="master.jsp">
        <pattern>/*</pattern>
    </decorator>
</decorators>

The file master.jsp above is the decorator. Create a file called /WEB-INF/decorators/master.jsp containing the following:

<%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>

<html>
  <head>
    <title>
    :: nedlowe.co.uk :: <decorator:title /> ::
    </title>
  </head>
  <body>
    <div id="header">
       <a href="http://www.nedlowe.co.uk/">http://www.nedlowe.co.uk/</a>
    </div>
    <div id="main">
      <decorator:body />
    </div>
  </body>
</html>

And you’re done! Load any page in your Spring MVC application – and you should see the output has been decorated.

The two decorator tags above look at the pre-decorated page, pull out the respective head and body, and insert them into the output stream. For more complicated usage, see the SiteMesh homepage.

Now let’s look forward to SiteMesh 3!

Converting Spring MVC XML bean definitions into annotations

Sunday, January 17th, 2010

As of Spring 2.5, annotations can be used on Spring MVC classes instead of defining each and every page in the *-servlet.xml definition file. However, most online guides still reference the old practice. Below is a simple guide to migrating to (in my opinion), the much cleaner annotation approach.

‘Normal’ Pages
Previously, ‘normal’ pages would:

  • Implement the Controller interface
  • Implement the handleRequest method
  • Have a simple *-servlet entry along the lines of:
<bean name="/contact_success.html" class="com.package.contact.ContactSuccessController" />

Switching this to annotations is simple:

Firstly, add the context:component-scan element to your *-servlet.xml file, along with the Spring MVC annotation handlers:

<context:component-scan base-package="com.yourpackage.name" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

For the above to work you will also need to add the context namespace URI to your main beans definition (third line down) and the schema to use (6th and 7th lines down):

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">

Annotate your class with the @Controller annotation, and a @RequestMapping annotation which specifies which URL is mapped by this controller:

@Controller
@RequestMapping("/contact_success.html")
public class ContactSuccessController {
  // Rest of class
}

The method which handles the request (which – unlike the previous case where we implemented an interface – can have any name) should be annotated with @RequestMapping(method = RequestMethod.GET).

So the bean definition in *-servlet.xml is removed, and the class becomes:

@Controller
@RequestMapping("/contact_success.html")
public class ContactSuccessController {
  @RequestMapping(method = RequestMethod.GET)
  public ModelAndView handleRequest()  {
     return new ModelAndView("contact/contactSuccess");
  }
}

Note that unlike the traditional xml based approach, the @RequestMapping annotation specifying which URL to map can be set at the method level (allowing multiple URLs to be mapped by a single Controller).

‘Form’ Pages

Form pages are a little more complicated. Previously, they would have:

  • Extending the superclass SimpleFormController
  • Overridden methods onSubmit and formBackingObject
  • Had a complicated bean definition containing all form options (e.g. which validator to use, which success page, etc)

To migrate these, first enable context:component-scan, along with the new Spring MVC annotation bean definitions as per the previous case.

Next, annotate the form class as per the ‘normal’ case. The method annotated with @RequestMapping(method = RequestMethod.GET) handles the initial ’setup’ of the form – basically what was previously handled in formBackingObject. This method also returns the view to use for the form. The command object will be initialised here, then stored in the model).

@Controller
@RequestMapping("/contact.html")
public class ContactFormController  {

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView setupForm(ModelMap model) {

		ContactForm contactForm = new ContactForm();
		model.addAttribute("contactForm", contactForm);

        return new ModelAndView("contact/contactForm");
	}

 // CLASS NOT COMPLETE YET!!!
}

The method which is called when the ‘Submit’ button is pressed is annotated in a similar manner, except the RequestMethod is POST instead of GET. However, the differences then get larger:

  • There is no automated validation (assuming a validator is specified of course). See below how this is handled.
  • The validator will return a status. If there is an error we simply return the same view. If not, we set the SessionStatus to complete and return the name of the Success view to use.
  • To get at our command object we need to pull it out of the model – using the @ModelAttribute("contactForm") annotation.

As mentioned above, we need to call the validator directly. To do this, we need to @Autowire the validator into the class (as per normal Spring injection). Since we are no longer relying on Spring MVC calling the validator, we can improve the validate method on the validator to become typesafe, instead of passing in a generic object as before.

Complete class:

@Controller
@RequestMapping("/contact.html")
public class ContactFormController  {

	@Autowired
	ContactFormValidator contactFormValidator;

	@RequestMapping(method = RequestMethod.GET)
	public ModelAndView setupForm(ModelMap model) {

		ContactForm contactForm = new ContactForm();
		model.addAttribute("contactForm", contactForm);

        return new ModelAndView("contact/contactForm");
	}

	@RequestMapping(method = RequestMethod.POST)
	public ModelAndView onSubmit(@ModelAttribute("contactForm") ContactForm contactForm,
			                      BindingResult errors,
			                      SessionStatus sessionStatus) {
		contactFormValidator.validate(contactForm, errors);
		if (errors.hasErrors()) {
			return new ModelAndView("contact/contactForm");
		}
		else {
			// Business Logic
			sessionStatus.setComplete();
			return new ModelAndView(new RedirectView("contact_success.html"));
		}
	}
}

Breaking Up A Large Hibernate Class

Monday, January 11th, 2010

Over time, Hibernate classes can get very large – especially when modelling a complicated object (for example a financial transaction).

At this point, the @Embedded annotation comes to the rescue. The class annotated with @Embedded will be linked into the parent class as if it were one large class.

This even works with collections – the collection can be defined in the child (@Embeddable) class.

@Entity
public class PretendClass {
  @Id
  private Long transactionId;

  @Embedded
  private PretendChildClass pretendChildClass = new PretendChildClass();

}

@Embeddable
public class PretendChildClass {

  @OneToMany(mappedBy = "transaction", targetEntity = TransactionAttributeImpl.class, cascade = CascadeType.ALL)
  @MapKey(name = "transactionAttributeType")
  @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
  private Map<TransactionAttributeType, TransactionAttribute> transactionAttributeMap = new HashMap<TransactionAttributeType, TransactionAttribute>();	

}

One caveat – we ought to be programming to interfaces rather than implementations. Assuming we marked an interface as @Embedded, Hibernate will scan the interface and not import any of the fields defined in the class. In this case, one simply adds the @Target annotation:

  @Embedded
  @Target(value = PretendChildClassImpl.class)
  private PretendChildClass pretendChildClass = new PretendChildClassImpl();

If using Criteria, this extra ‘level’ in the class hierarchy is simply referenced via a full-stop:

  List<Transaction> transactionList;
  Criteria crit = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(TransactionImpl.class);
  crit.createAlias("embeddable_child_class.variable_we_want", "transactionExtRef"); // THE IMPORTANT LINE
  crit.add(Restrictions.eq("transactionExtRef.transactionExtRefType", transactionExtRefType))
       .add(Restrictions.eq("transactionExtRef.transactionExtRefValue", transactionExtRefValue));
  transactionList = crit.list();
  return transactionList;