Monday, August 12, 2013

Spring based applications and logging dependencies

There is not much to say on the topic of Spring based applications and adding logging dependencies apart from pointing to the excellent blog entry at the Spring site itself - http://blog.springsource.org/2009/12/04/logging-dependencies-in-spring/

This is an old entry, but is still valid. The essence of the article is that Spring has one core logging dependency - on Apache Commons Logging. Given this dependency, there are two good options for Spring based applications.

1. Use slf4j with any of the slf4j supporting logging frameworks. This can be done by using the jcl to slf4j bridge library that slf4j provides, along with any of the compile time binding to a logging framework. say for eg, with log4j the following would be the maven dependencies:

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>${spring.version}</version>
 <exclusions>
  <exclusion>
   <artifactId>commons-logging</artifactId>
   <groupId>commons-logging</groupId>
  </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jcl-over-slf4j</artifactId>
 <version>1.7.5</version>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.5</version>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.7.5</version>
</dependency>
<dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.17</version>
</dependency>

There are 5 dependencies here - the commons-logging is being explicitly excluded first, then a jcl-over-slf4j library provides a JCL adapter to the slf4j library, then the slf4j api is required, the binding to log4j and finally the log4j library.


2. A better option is to use logback as the logging library. Logback natively supports slf4j api, so the dependencies is much more simplified:

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>${spring.version}</version>
 <exclusions>
  <exclusion>
   <artifactId>commons-logging</artifactId>
   <groupId>commons-logging</groupId>
  </exclusion>
 </exclusions>
</dependency>
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jcl-over-slf4j</artifactId>
 <version>1.7.5</version>
</dependency>
<dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 <version>1.0.13</version>
</dependency>

References:
Springsource Blog entry by Dave Syer: http://blog.springsource.org/2009/12/04/logging-dependencies-in-spring/

Slf4J legacy bridge: http://www.slf4j.org/legacy.html

Logback logging library: http://logback.qos.ch/

Thursday, August 1, 2013

Spring - Autowiring multiple beans of the same type and @Primary annotation

Consider a simple Spring annotation based context, with two beans with @Service annotation, but of the same type:

@Service 
public class CustomerServiceImpl1 implements CustomerService{
 @Override
 public Customer getCustomer(long id) {
  return new Customer(1, "Test1");
 }
}

and

@Service 
public class CustomerServiceImpl2 implements CustomerService{
 @Override
 public Customer getCustomer(long id) {
  return new Customer(1, "Test1");
 }
}

Now, a client which injects in the CustomerService bean as a dependency will fail, as by default the injection of autowired fields is by type and there are two beans in the context of the same type. An error message along these lines is typically what is seen at startup:

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [pkg.CustomerService] is defined: expected single matching bean but found 2: customerServiceImpl2,customerServiceImpl1

A standard fix for this is to inject by bean name instead of by type, this way:

public class ConfigTest
{
    @Autowired
    @Qualifier("customerServiceImpl1")
    private CustomerService customerService;
    ...
}    

Note that I have made use of the bean naming convention for stereotype annotations which is described in more detail here

However there is another way to disambiguate which specific bean to inject in, and this is with the @Primary annotation. This annotation indicates that the target bean should be given precedence when autowiring by type. This begs the question, what happens if more than one bean of the same type is annotated with @Primary, well Spring will raise an exception like before. @Primary is expected to be applied on only bean of a specific type.

@Primary is also supported in Java Configuration, so @Bean methods can also be tagged with @Primary to indicate the higher precedence.

@Configuration
public class TestConfiguration
{
 @Bean
 @Primary
 public CustomerService customerService1() {
  return new CustomerServiceImpl1();
 }
 
 @Bean
 public CustomerService customerService2() {
  return new CustomerServiceImpl2();
 } 
}

Tuesday, July 16, 2013

Spring @Bean and PropertyPlaceHolderConfigurer

I was recently stumped by what I thought was going to be a fairly straightforward implementation - Consider the following Spring Java based bean definition file (@Configuration):

package root;

...

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {
 
 @Value("${test.prop}")
 private String attr;
  
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }
}

Here a bean `sampleService` is being defined, this bean is initialized with an attribute that is populated using a @Value annotation using a property placeholder string ${test.prop}.

The test for this is the following:

@ContextConfiguration(classes=SampleConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class ConfigTest {
 @Autowired
 private SampleService sampleService;
 @Test
 public void testConfig() {
  assertThat(sampleService.aMethod(), is("testproperty"));
 }
}


which with the current implementation of SampleConfig fails, as the place holder ${test.prop} is not resolved at all. The standard fix for this is to register a PropertySourcesPlaceholderConfigurer which is a BeanFactoryPostProcessor responsible for scanning through all the registered bean definitions and injecting in the resolved placeholders. With this change in place the @Configuration file looks like this:

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig { 
 @Value("${test.prop}")
 private String attr;
 
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }
 
 @Bean
 public PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

However, after adding in the Property resolver, the test still fails, this time the value returned by the sampleService is null, not even the placeholder value!

The reason for the issue it turns out, is that with @Configuration which internally uses annotations like @Autowired, @Value, and @PostConstruct, any BeanFactoryPostProcessor beans have to be declared with a static, modifier. Otherwise the containing @Configuration class is instantiated very early and the BeanPostProcessors responsible for resolving annotations like @Value, @Autowired etc, cannot act on it.

This fix is well documented in the javadoc of @Bean, further a message is also logged which provides the workaround:

WARN : org.springframework.context.annotation.ConfigurationClassEnhancer - @Bean method RootConfig.placeHolderConfigurer is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean Javadoc for complete details


So with this fix the new working configuration is the following:

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig { 
 @Value("${test.prop}")
 private String attr;
 
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }
 
 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}


References:

Monday, July 8, 2013

AbstractAnnotationConfigDispatcherServletInitializer - Long and short of it

AbstractAnnotationConfigDispatcherServletInitializer is a newly(3.2+ versions of Spring) introduced Template Method based base class that makes Spring pure java based web application Configuration(@Configuration) without using a web.xml, easier.

The use of this class can be better appreciated using an example. Prior to AbstractAnnotationConfigDispatcherServletInitializer, the way to configure a web.xml less Servlet 3 web application is by implementing a WebApplicationInitializer:

public class CustomWebAppInitializer implements WebApplicationInitializer {

 @Override
 public void onStartup(ServletContext container) {
  AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
  rootContext.register(RootConfiguration.class);
  container.addListener(new ContextLoaderListener(rootContext));
  AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
  webContext.register(MvcConfiguration.class);
  DispatcherServlet dispatcherServlet = new DispatcherServlet(webContext);
  ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", dispatcherServlet);
  dispatcher.addMapping("/");
 }
}

A little more detail of how WebApplicationInitializer works internally is described here

With the introduction of AbstractAnnotationConfigDispatcherServletInitializer, this configuration is now much simpler and far less error prone.

public class CustomWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 @Override
 protected Class<?>[] getRootConfigClasses() {
  return new Class<?>[]{RootConfiguration.class};
 }

 @Override
 protected Class<?>[] getServletConfigClasses() {
  return new Class<?>[]{MvcConfiguration.class};
 }

 @Override
 protected String[] getServletMappings() {
  return new String[]{"/"};
 }
}


Indeed a terribly long name, but the class serves to make the initialization code much more concise and clear.

Sunday, June 30, 2013

Spring MVC - Migrating to Jackson 2

This does not really require a blog entry - migrating from Jackson 1.9.x to Jackson 2.x is extremely simple with Spring MVC 3.1+ based applications. The only thing that needs to be done is to replace the 1.9.x jar with Jackson 2.x jar, with the following new entry in a maven pom.xml file (assuming a maven project)

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.2.0</version>
</dependency>

This is pretty remarkable considering the fact that the core Jackson package names have now been refactored from
"org.codehaus.jackson" to "com.fasterxml.jackson".


So how does this Spring MVC handle such migrations internally -

Spring MVC uses a component called a HttpMessageConverter as a strategy interface to convert the request body to an object representation, and to convert the response object representation to a serialized form to be sent back as a response.

Spring MVC registers a series of HttpMessageConverters to handle request bodies, this happens by default when the MVC is activated, typically using a xml Spring bean definition file this way:

<mvc:annotation-driven />

Or, when using new Java Config style of bean definition:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages="mvcsample.web", 
 includeFilters=@Filter(type=FilterType.ANNOTATION, value=Controller.class))
public class WebConfig {

}


In both cases, a check for the presence of Jackson2 libraries is made by scanning for well-known classes within the jackson2 library:

private static final boolean jackson2Present =
  ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", aClassLoader) &&
    ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", aClassLoader);

and assuming Jackson 2.x libraries are present, an appropriate HttpMessageConverter is registered:

if (jackson2Present) {
 messageConverters.add(new MappingJackson2HttpMessageConverter());
}

If there happen to be both the 1.9.x jars and the 2.x jars of Jackson in the classpath, then preferentially the 2.x HttpMessageConverter is registered before the 1.9.x HttpMessageConverters.

This way Spring MVC seamlessly handles the upgrade of Jackson libraries

Wednesday, June 19, 2013

Spring MVC Error handling flow

There are broadly three ways of handling an exception flow using Spring MVC, the objective being to intercept any application exception and present a friendly and informative view back to the user.

1. Using error-page tag in web.xml file:

This is a servlet specs driven approach, where the exceptions that bubble up from the application are intercepted based on either the HTTP response code or the exception type and the handler for the exception is specified using the location sub-tag this way:

<error-page>
    <error-code>500</error-code>
    <location>/500</location>
</error-page>
<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/uncaughtException</location>
</error-page>

If it is a Spring MVC based app, and if the intent is for a Spring MVC view to present the message, then a location should ideally be a Spring controller which can show the content and this can be done for the 2 locations above purely using Spring MVC configuration:

<mvc:view-controller path="/500" view-name="500view"/>
<mvc:view-controller path="/uncaughtException" view-name="uncaughtexception"/>


2. Registering a HandlerExceptionResolver:


HandlerExceptionResolver(s) are responsible for mapping the exception to views, the simplest approach is to register a SimpleMappingExceptionResolver that can map exception types to view names. The following is a way to register SimpleMappingExceptionResolver using Spring xml bean definition(based on Roo samples):

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="uncaughtException">
 <property name="exceptionMappings">
  <props>
   <prop key=".DataAccessException">dataAccessFailure</prop>
   <prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop>
   <prop key=".TypeMismatchException">resourceNotFound</prop>
   <prop key=".MissingServletRequestParameterException">resourceNotFound</prop>
  </props>
 </property>
</bean>

OR using Java Configuration based bean definition:

@Bean
public HandlerExceptionResolver handlerExceptionResolver() {
 SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
 exceptionResolver.setDefaultErrorView("uncaughtException");
 Properties mappings = new Properties();
 mappings.put(".DataAccessException", "dataAccessFailure");
 mappings.put(".NoSuchRequestHandlingMethodException", "resourceNotFound");
 mappings.put(".TypeMismatchException", "resourceNotFound");
 mappings.put(".MissingServletRequestParameterException", "resourceNotFound");
 exceptionResolver.setExceptionMappings(mappings );
 return exceptionResolver;
}


3. Using @ExceptionHandler

This is my preferred approach and there are two variations to using the @ExceptionHandler annotation.

In the first variation, @ExceptionHandler can be applied to the level of a controller class in which case the exceptions raised by the same controller @RequestMapped methods are handled by the @ExceptionHandler annotated methods.

@Controller
public class AController {
    @ExceptionHandler(IOException.class)
    public String handleIOException(IOException ex) {
      return "errorView";
    }
}

In the second variation of @ExceptionHandler, the annotation can be applied to ALL controller classes by annotating a method of @ControllerAdvice annotated class:

@ControllerAdvice
public class AControllerAdvice {
    @ExceptionHandler(IOException.class)
    public String handleIOException(IOException ex) {
      return "errorView";
    }
}


These essentially are the approaches to handling application exceptions in Spring MVC applications.

Monday, June 10, 2013

Google guava "live" transformation - forcing an eager transformation

One of the utility classes provided by Google Guava Library, Lists, has a utility method to transform lists of one type to another. The interesting feature of this transformation is that the transformation is "live", in the sense that any changes to the source list is visible in the destination list. This is done by doing the transformation only on demand by applying a transformation on request.

This is best shown with an example:

Account a1 = new Account(1, "business", "num1");
Account a2 = new Account(2, "business", "num2");
Account a3 = new Account(3, "business", "num3");

List<Account> list = Lists.newArrayList(a1, a2, a3);

List<Integer> ids = Lists.transform(list, new Function<Account, Integer>() {
 @Override 
 public Integer apply(Account input) {
  return input.getId();
 }
});

assertThat(ids, contains(1, 2, 3));

a2.setId(12);
assertThat(ids, contains(1, 12, 3));


Here a list of "Account"(s) is being transformed to a list of its corresponding ids. Any change in the id of the original objects is reflected in the transformed list.

Now, there are situations where an eager transformation may be desired - for eg. needing to cache the transformed list, or serializing the transformed list. The way to force an eager transformation is to make a copy of the lazy list, using another utility method provided by the Lists class:

Lists.newArrayList(ids)