Archive

Posts Tagged ‘spring’

Property editors

July 17th, 2011 3 comments

In Java, property editors are seldom used. Originally, they were meant for Swing applications to transform between model objects and their string representations on the GUI.

Spring found them another use: it’s typically what needs to be done when parsing a Spring beans definition file in order to create beans in the factory. Have you Spring users noticed you can set a number to a property and it is taken as such?

It’s because in every bean factory, there’re some editors registered by default. In fact, there are three kinds of editors:

  1. The first level consist of those default editors.
  2. If you need to go further, you can register editors provided by the Spring framework.
  3. Finally, you can also create your own editors.

The list of editors built-in, pre-registeredor not, is available in the Spring documentation.

For example, the LocaleEditor is built-in and to use it, we only have to provide the correct locale string representation like so:

<bean id="dummy" class="ch.frankel.blog.spring.propertyeditor.Dummy">
	<property name="locale" value="fr_FR" />
</bean>

Interestingly enough, some other editors are not well-known, like the PatternEditor, although they are registered by default.

In order to register other property editors, whether built-in or homemade, just configure the customEditors map property of the org.springframework.beans.factory.config.CustomEditorConfigurer bean. Note that the latter can safely remain anonymous.

The following configuration snippet adds a date property editor so that dates can easily be configured in beans definitions files.

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
    <map>
      <entry key="java.util.Date">
        <bean class="org.springframework.beans.propertyeditors.CustomDateEditor">
          <constructor-arg index="0">
            <bean class="java.text.SimpleDateFormat">
              <constructor-arg  value="dd.MM.yyyy" />
            </bean>
          </constructor-arg>
          <constructor-arg index="1" value="false" />
        </bean>
      </entry>
    </map>
  </property>
</bean>

Note that keys in the custom editors map are the wanted object type, meaning there can be only a single editor for each type – a good thing if there’s one.

Sources for this article can be found here in Eclipse/Maven format.

Categories: Java Tags: ,

Playing with Spring Roo and Vaadin

January 17th, 2011 6 comments

One year ago, under the gentle pressure of a colleague, I tried Spring Roo. I had mixed feelings about the experience: while wanting to increase productivity was of course a good idea, I had concerned regarding Roo’s intrusiveness. I left it at that, and closed the part of my memory related to it.

Now, one year later, I learned that my favourite web framework, namely Vaadin, had set their sight on a Roo plugin. That was enough for me to get back on my feet and try again. This article tries to describe as honestly as possible the good and the bad of this experience related to both Roo and the Vaadin plugin.

Pure Roo

First of all, I download the free STS 2.5, that includes Roo 1.1.1 and install it. No problem at this time. Then, I create a new Spring Roo project inside STS. Unluckily, STS does not create the default maven directories (src/main-test/java-resources): errors appear in my Problems tab. Trying to solve the project, I type the project command into Roo’s shell inside STS. Roo complains I should give it my top-level package, though I already did that with the wizard. OK, I am a nice guy and do as asked:

project --topLevelPackage ch.frankel.blog.roo.vaadin

This time, Roo successfully creates the aforementioned directories as well as a Spring configuration file and a log4j properties file.

Next step is to create my persistence layer. The use of CTRL+SPACE is real nice and helps you much with command parameters. Combined with hint, it’s real easy to get comfortable with Roo.

persistence setup --provider HIBERNATE --database DERBY

Roo nicely updates my Maven POM and let it download the latest version right dependencies (JPA, Hibernate, Derby, etc.). I can always change version if I need a specific one. It even adds JBoss Maven repo so I can download Hibernate. I just need to update my database properties, driver and URL. Uh oh: when I open the file, I see Roo has strangely escaped colons characters with backslash. I just replace the example escaped URL with an unescaped real one.

Meanwhile, I notice an error in the log: “The POM for org.aspectj:aspectjtools:jar:1.6.11.M1 is missing, no dependency information available”. Roo updated my POM with version 1.6.11.M1. If I check on repo1, the latest version is 1.6.10. Replacing 1.6.11.M1 with 1.6.10 removes the error.

Now would be a good time to create my first entity:

entity --class ~.entity.Teacher --testAutomatically

STS now complains that the target directory doesn’t exist, like before it complained for source directories. In order to remedy to that, I just do as before, I launch an instruction. In this case, I order Roo to launch the tests with the perform test command. In turn, Roo launches mvn test under the hood and Maven does create the target directory.

Entities without fields are useless. Let’s add a first name and a name to our teacher.

field string --fieldName firstName
field string --fieldName name

It would be cool to have courses attached.

entity --class ~.entity.Course --testAutomatically
field string --fieldName name
focus --class Teacher
field set --fieldName courses --type Course

Notice that since Roo works in a contextual manner, I have to use the focus command so that I do not create the courses Set inside the Course class but inside the Teacher class.

Vaadin plugin

Until now, there was nothing about Vaadin. Here it comes: following the instructions from Vaadin’s wiki, I download the latest Vaadin Roo plugin snapshot and put in in my Roo local OSGI repository. In order to the new bundle to be seen by Roo, I have to restart it which I don’t know how to do inside STS. Instead, I restart STS.

There comes the magic command:

vaadin setup --applicationPackage ~.web --useJpaContainer false

This command:

  • adds Vaadin dependency
  • adds web directory with images
  • updates the POM to war packaging

Yet, when I try to add my new web project to Tomcat, STS complains it doesn’t find candidate projects. The problem lies in that Eclipse is not synchronized with Maven and as such, my project lacks the Web facet. The solution: right-click on my project, go to the Maven menu and click on “Update project configuration” submenu. When done, I can add the project to Tomcat like any other web project (since it is anyway).

Starting Tomcat and going to http://localhost:8080/vaadin, I can see Vaadin handling my request. I just miss the views over my entities, which is done with the following:

vaadin generate all --package ~.web.ui --visuallyComposable true

Conclusion

Well, that was quick, if not perfect. I do miss some features in Roo:

As for the Vaadin plugin, it lacks updating Eclipse files after having changed the POM. Someone not familiar with m2eclipse inner workings could lose some time with this behaviour.

On the other hand, I have a simple webapp in a matter of minutes, that I can now update how I choose. CTRL+SPACE and hint are Roo killer features. Moreover, like the Vaadin add-on showed, you can add whatever functionality is lacking with your own plugin (or use one already available). What’s really important for me though, and without it, I wouldn’t even consider using Roo is that it is completely removable in 3 easy steps. As such you can use Roo’s productivity boost, not tell anyone and remove Roo just before passing your project to the maintenance team.

Thanks to Joonas Lehtinen and Henri Sara for their work on Roo Vaadin’s plugin and sending me ahead of schedule the wiki draft explaining the Vaadin part.

Here are the sources for this article in Maven/STS format.

To go further:

Categories: JEE Tags: , ,

Why CDI won’t replace Spring

November 14th, 2010 3 comments

CDI is part of JavaEE 6 and that’s a great move forward. Now, there’s a standard telling vendors and developers how to do DI. It can be refined, but it’s here nonetheless. Norms and standards are IMHO a good thing in any industry. Yet, I don’t subscribe to some people’s points of view that this means the end of Spring. There are multiple DI frameworks around here and Spring is number one.

Why is that? Because it was the first? It wasn’t (look at Avalon). My opinion is that it’s because Spring’s DI mechanism is only a part of its features. Sure, it’s great but Guice and now CDI offers the same. What really sets Spring apart is its integration of JavaEE API and of the best components available on the market that are built on top of DI.

A good example of this added value is JMS: if you ever tried to post to a queue before, you know what I mean. This is the kind of code you would need to write:

Context context = new InitialContext();

QueueConnectionFactory queueConnectionFactory = (QueueConnectionFactory) context.lookup("myQConnectionFactory");

Queue queue = (Queue) context.lookup("myQueue");

QueueConnection queueConnection = queueConnectionFactory.createQueueConnection();

QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

QueueSender queueSender = queueSession.createSender(queue);

TextMessage message = queueSession.createTextMessage();

message.setText("Hello world!");

queueSender.send(message);

Now in Spring, this is configured like so:

<jee:jndi-lookup id="queueConnectionFactory" jndi-name="myQConnectionFactory" />

<jee:jndi-lookup id="q" jndi-name="myQueue" />

<bean id="jmsTemplate">
  <property name="connectionFactory" ref="jmsQueueConnectionFactory" />
  <property name="defaultDestination" ref="q" />
</bean>

I don’t care it’s shorter event though it is (but it lacks the code to send the text). I don’t care it’s XML either. My real interest is that I code less: less errors, less bugs, less code to test. I don’t have to write the boilerplate code because it’s taken care of by Spring. Sure, I have to configure, but it’s a breeze compared to the code.

This is true for JMS, but equally for Hibernate, EclipseLink, iBatis, JPA, JDO, Quartz, Groovy, JRuby, JUnit, TestNG, JasperReports, Velocity, FreeMarker, JSF, what have you that is the best of breed (or at least on top) of its category. Morevover,  if nothing exists to fit the bill, Spring provides it: look at Spring Batch for a very good example of a framework that handles the boring and repetitive code and let you focus on your business code.

Do Guice or other frameworks have such integration features included in them? No, they are pure, “untainted” DI frameworks. As such, they can easily be replaced by CDI, Spring not so much.

Categories: JEE Tags: ,

Next book review: Spring Security 3

June 23rd, 2010 No comments

My next book review will be on Spring Security 3 from Packt. I’ve heard of Spring Security since it was previously named Acegi Security but I hadn’t the chance to play with it. A book on the Spring Security model will let me dive into the subject, providing me with the means to see if it warrants further investigation on my part.

The shipment is on its way, the rest is on my shoulders!

Categories: Book review Tags: ,

Chicken and egg problem with Spring and Vaadin

May 3rd, 2010 3 comments

The more I dive into Vaadin, the more I love it: isolation from dirty plumbing, rich components, integration with portlets, Vaadin has it all.

Anyway, the more you explore a technology, the bigger the chances you fall down the proverbial rabbit hole. I found one just yesterday and came up with a solution. The problem is the following: in Vaadin, application objects are tied to the session. Since I’m a Spring fanboy, it does make sense to use Spring to wire all my dependencies. As such, I scoped all application-related beans (application, windows, buttons, resources, …) with session like so:

<?xml version="1.0" encoding="UTF-8"?>
<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"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/aop

    http://www.springframework.org/schema/aop/spring-aop.xsd">

  <context:annotation-config />

  <bean id="application" scope="session">
  <aop:scoped-proxy />
...
</beans>

This works nicely, until you happen to use DI to wire further. By wire further, I mean wiring windows into application, button into windows and then resources (icons) into buttons. It is the last  step that cause a circular dependency. Icon resources are implemented in Vaadin by com.vaadin.terminal.ClassResource. This class has two constructors that both needs an application instance.

The dependency cycle is thus: application -> window -> button -> resource -> application. Spring don’t like it and protests energically to it by throwing an exception which is labeled like so Requested bean is currently in creation: Is there an unresolvable circular reference?

. I think, in this case, that the design of the ClassResource is not adapted. That’s whyI designed a class aligned with Spring deferred instantiation: since the application is session-scoped, Spring uses a proxy that defers instantation from application start (Spring normal behaviour) to session use. The point is to implement the ApplicationResource interface, which needs an interface, but to set application only when needed:

public class DeferredClassResource implements ApplicationResource {

  private static final long serialVersionUID = 1L;
  private int bufferSize = 0;
  private long cacheTime = DEFAULT_CACHETIME;
  private Class<?> associatedClass;
  private final String resourceName;
  private Application application;

  public DeferredClassResource(String resourceName) {

    if (resourceName == null) {

      throw new IllegalArgumentException("Resource name cannot be null");
    }

    this.resourceName = resourceName;
  }

  public DeferredClassResource(Class<?> associatedClass, String resourceName) {

    this(resourceName);

    if (associatedClass == null) {

      throw new IllegalArgumentException("Associated class cannot be null");
    }

    this.associatedClass = associatedClass;
  }

... // standard getters

  @Override
  public String getFilename() {

    int index = 0;

    int next = 0;

    while ((next = resourceName.indexOf('/', index)) > 0
      && next + 1 < resourceName.length()) {
      index = next + 1;
    }

    return resourceName.substring(index);
  }

  @Override
  public DownloadStream getStream() {

    final DownloadStream ds = new DownloadStream(associatedClass
      .getResourceAsStream(resourceName), getMIMEType(),
      getFilename());

    ds.setBufferSize(getBufferSize());

    ds.setCacheTime(cacheTime);

    return ds;
  }

  @Override
  public String getMIMEType() {

    return FileTypeResolver.getMIMEType(resourceName);
  }

  public void setApplication(Application application) {

    if (this.application == application) {

      return;
    }

    if (this.application != null) {

      throw new IllegalStateException("Application is already set for this resource");
    }

    this.application = application;

    associatedClass = application.getClass();

    application.addResource(this);
  }
}

DeferredClassResource is just a copy of ClassResource, but with adaptations that let the application be set later, not only in constructors. My problem is solved, I just need to let application know my resources so it can call setApplication(this) in a @PostConstruct annotated method.

Categories: JEE Tags: ,

Vaadin Spring integration

April 6th, 2010 17 comments

I lately became interested in Vaadin, another web framework but where everything is done on the server side: no need for developers to learn HTML, CSS nor JavaScript. Since Vaadin adress my remarks about web applications being to expensive because of a constant need of well-rounded developers, I dug a little deeper: it will probably be the subject of another post.

Anyway, i became a little disappointed when I wanted to use my favourite Dependency Injection framework, namely Spring, in Vaadin. After a little Google research, I found the Vaadin Wiki and more precisely the page talking about Vaadin Spring Integration. It exposes two ways to integrate Spring in Vaadin.

The first one uses the Helper “pattern”, a class with static method that has access to the Spring application context. IMHO, those Helper classes should be forgotten now we have DI since they completely defeat its purpose. If you need to explicitly call the Helper static method in order to get the bean, where’s the Inversion of Control?

The second solution uses Spring proprietary annotation @Autowired in order to use DI. Since IoC is all about decoupling, I’m vehemently opposed to coupling my code to the Spring framework.

Since neither option seemed viable to me, let me present you the one I imagined: it is very simple and consists of subclassing the Vaadin’s AbstractApplicationServlet and using it instead of the classical ApplicationServlet.

public class SpringVaadinServlet extends AbstractApplicationServlet {

  /** Class serial version unique identifier. */
  private static final long serialVersionUID = 1L;

  private Class clazz;

  @Override
  public void init(ServletConfig config) throws ServletException {

    super.init(config);

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
      config.getServletContext());

    Application application = (Application) wac.getBean("application", Application.class);

    clazz = application.getClass();
 }

  /**
  * Gets the application from the Spring context.
  *
  * @return The Spring bean named 'application'
  */
  @Override
  protected Application getNewApplication(HttpServletRequest request)
    throws ServletException {

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
      request.getSession().getServletContext());

    return (Application) wac.getBean("application", Application.class);
  }

  /**
  * @see com.vaadin.terminal.gwt.server.AbstractApplicationServlet#getApplicationClass()
  */
  @Override
  protected Class getApplicationClass()
  throws ClassNotFoundException {

    return clazz;
  }
}

This solution is concise and elegant (according to me). Its only drawback is that it couples the servlet to Spring. But a class-localized coupling is of no consequesence and perfectly acceptable. Morevoer, this lets you use Spring autowiring mechanism, JSR 250 autowiring or plain old XML explicit wiring.

Categories: JEE Tags: ,

Spring Persistence with Hibernate

March 1st, 2010 No comments

This review is about Spring Persistence with Hibernate by Ahmad Reza Seddighi from Packt Publishing.

Facts

  1. 15 chapters, 441 pages, 38€99
  2. This book is intended for beginners but more experienced developers can learn a thing or two
  3. This book covers Hibernate and Spring in relation to persistence

Pros

  1. The scope of this book is what makes it very interesting. Many books talk about Hibernate and many talk about Spring. Yet, I do not know of many which talk about the use of both in relation to persistence. Explaining Hibernate without describing the transactional side is pointless
  2. The book is well detailed, taking you by the hand from the bottom to reach a good level of knowledge on the subject
  3. It explains plain AOP, then Spring proxies before heading to the transactional stuff

Cons

  1. The book is about Hibernate but I would have liked to see a more tight integration with JPA. It is only described as an another way to configure the mappings
  2. Nowadays, I think Hibernate XML configuration is becoming obsolete. The book views XML as the main way of configuration, annotations being secondary
  3. Some subjects are not documented: for some, that’s not too important (like Hibernate custom SQL operations), for others, that’s a real loss (like the @Transactional Spring annotation)

Conclusion

Despite some minor flaws, Spring Persistence with Hibernate let you go head first into the very complex sujbect of Hibernate. I think that Hibernate has a very low entry ticket, and you can be more productive with it very quickly. On the downside, mistakes will cost you much more than with old plain JDBC. This book serves you Hibernate and Spring concepts on a platter, so you will make less mistakes.

Categories: Book review Tags: , ,

Discover Spring authoring

December 29th, 2009 No comments

In this article, I will describe a useful but much underused feature of Spring, the definition of custom tags in the Spring beans definition files.

Spring namespaces

I will begin with a simple example taken from Spring’s documentation. Before version 2.0, only a single XML schema was available. So, in order to make a constant available as a bean, and thus inject it in other beans, you had to define the following:

<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />

Spring made it possible, but realize it’s only a trick to expose the constant as a bean. However, since Spring 2.0, the framework let you use the util namespace so that the previous example becomes:

<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>

In fact, there are many namespaces now available:

Prefix Namespace Description
bean http://www.springframework.org/schema/bean Original bean schema
util http://www.springframework.org/schema/util Utilities: constants, property paths and collections
util http://www.springframework.org/schema/jee JNDI lookup
lang http://www.springframework.org/schema/lang Use of other languages
tx http://www.springframework.org/schema/tx Transactions
aop http://www.springframework.org/schema/aop AOP
context http://www.springframework.org/schema/context ApplicationContext manipulation

Each of these is meant to reduce verbosity and increase readibility like the first example showed.

Authoring

What is still unknown by many is that this feature is extensible that is Spring API provides you with the mean to write your own. In fact, many framework providers should take advantage of this and provide their own namespaces so that integrating thier product with Spring should be easier. Some already do: CXF with its many namespaces comes to mind but there should be others I don’t know of.

Creating you own namespace is a 4 steps process: 2 steps about the XML validation, the other two for creating the bean itself. In order to illustrate the process, I will use a simple example: I will create a schema for EhCache, the Hibernate’s default caching engine.

The underlying bean factory will be the existing EhCacheFactoryBean. As such, it won’t be as useful as a real feature but it will let us focus on the true authoring plumbing rather than EhCache implementation details.

Creating the schema

Creating the schema is about describing XML syntax and more importantly restrictions. I want my XML to look something like the following:

<ehcache:cache id="myCache" eternal="true" cacheName="foo"
maxElementsInMemory="5" maxElementsOnDisk="2" overflowToDisk="false"
diskExpiryThreadIntervalSeconds="18" diskPersistent="true" timeToIdle="25" timeToLive="50"
memoryStoreEvictionPolicy="FIFO">
  <ehcache:manager ref="someManagerRef" />
</ehcache:echcache>

Since I won’t presume to teach anyone about XML, here’s the schema. Just notice the namespace declaration:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://blog.frankel.ch/spring/ehcache" xmlns="http://blog.frankel.ch/spring/ehcache"
  elementFormDefault="qualified">
  <xsd:complexType name="cacheType">
    <xsd:sequence maxOccurs="1" minOccurs="0">
      <xsd:element name="manager" type="managerType" />
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="cacheName" type="xsd:string" />
    <xsd:attribute name="diskExpiryThreadIntervalSeconds" type="xsd:int" />
    <xsd:attribute name="diskPersistent" type="xsd:boolean" />
    <xsd:attribute name="eternal" type="xsd:boolean" />
    <xsd:attribute name="maxElementsInMemory" type="xsd:int" />
    <xsd:attribute name="maxElementsOnDisk" type="xsd:int" />
    <xsd:attribute name="overflowToDisk" type="xsd:boolean" />
    <xsd:attribute name="timeToLive" type="xsd:int" />
    <xsd:attribute name="timeToIdle" type="xsd:int" />
    <xsd:attribute name="memoryStoreEvictionPolicy" type="memoryStoreEvictionPolicyType" />
  </xsd:complexType>
  <xsd:simpleType name="memoryStoreEvictionPolicyType">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="LRU" />
      <xsd:enumeration value="LFU" />
      <xsd:enumeration value="FIFO" />
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:complexType name="managerType">
    <xsd:attribute name="ref" type="xsd:string" />
  </xsd:complexType>
  <xsd:element name="cache" type="cacheType" />
</xsd:schema>

And for those, like me, that prefer a graphic display:

Mapping the schema

The schema creation is only the first part. Now, we have to make Spring aware of it. Create the file META-INF/spring.schemas and write in the following line is enough:

http\://blog.frankel.ch/spring/schema/custom.xsd=ch/frankel/blog/spring/authoring/custom.xsd

Just take care to insert the backslash, otherwise it won’t work. It maps the schema declaration in the XML to the real file that will be used from the jar!

Before going further, and for the more curious, just notice that in spring-beans.jar (v3.0), there’s such a file. Here is it’s content:

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd

It brings some remarks:

  • Spring eat their own dogfood (that’s nice to know)
  • I didn’t look into the code but I think that’s why XML validation of Spring’s bean files never complain about not finding the schema over the Internet (a real pain in production environment because of firewall security issues). That’s because the XSD are looked inside the jar
  • If you don’t specify the version of the Spring schema you use (2.0, 2.5, 3.0, etc.), Spring will automatically upgrade it for you with each major/minor version of the jar. If you want this behaviour, fine, if not, you’ll have to specify version

Creating the parser

The previous steps are only meant to validate the XML so that the eternal attribute will take a boolean value, for example. We still did not wire our namespace into Spring factory. This is the goal of this step.

The first thing to do is create a class that implement org.springframework.beans.factory.xml.BeanDefinitionParser. Looking at its hierarchy, it seems that the org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser is a good entry point since:

  • the XML is not overly complex
  • there will be a single bean definition

Here’s the code:

public class EhCacheBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {

  private static final List&amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;gt; PROP_TAG_NAMES;

  static {

  PROP_TAG_NAMES = new ArrayList();

    PROP_TAG_NAMES.add("eternal");
    PROP_TAG_NAMES.add("cacheName");
    PROP_TAG_NAMES.add("maxElementsInMemory");
    PROP_TAG_NAMES.add("maxElementsOnDisk");
    PROP_TAG_NAMES.add("overflowToDisk");
    PROP_TAG_NAMES.add("diskExpiryThreadIntervalSeconds");
    PROP_TAG_NAMES.add("diskPersistent");
    PROP_TAG_NAMES.add("timeToLive");
    PROP_TAG_NAMES.add("timeToIdle");
  }

  @Override
  protected Class getBeanClass(Element element) {

    return EhCacheFactoryBean.class;
  }

  @Override
  protected boolean shouldGenerateIdAsFallback() {

    return true;
  }

  @Override
  protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {

    for (String name : PROP_TAG_NAMES) {

      String value = element.getAttribute(name);

      if (StringUtils.hasText(value)) {

        builder.addPropertyValue(name, value);
      }
    }

    NodeList nodes = element.getElementsByTagNameNS("http://blog.frankel.ch/spring/ehcache", "manager");

    if (nodes.getLength() &amp;amp;amp;amp;amp;amp;gt; 0) {

      builder.addPropertyReference("cacheManager",
        nodes.item(0).getAttributes().getNamedItem("ref").getNodeValue());
    }

    String msep = element.getAttribute("memoryStoreEvictionPolicy");

    if (StringUtils.hasText(msep)) {

      MemoryStoreEvictionPolicy policy = MemoryStoreEvictionPolicy.fromString(msep);

      builder.addPropertyValue("memoryStoreEvictionPolicy", policy);
    }
  }
}

That deserves some explanations. The static block fills in what attributes are valid. The getBeanClass() method returns what class will be used, either directly as a bean or as a factory. The shouldGenerateIdAsFallback() method is used to tell Spring that when no id is supplied in the XML, it should generate one. That makes it possible to create pseudo-anonymous beans (no bean is really anonymous in the Spring factory).

The real magic happen in the doParse() method: it just adds every simple property it finds in the builder. There are two interesting properties though: cacheManager and memoryStoreEvictionPolicy.

The former, should it exist, is a reference on another bean. Therefore, it should be added to the builder not as a value but as a reference. Of course, the code doesn’t check if the developer declared the cache manager as an anonymous bean inside the ehcache but the schema validation took already care of that.

The latter just uses the string value to get the real object behind and add it as a property to the builder. Likewise, since the value was enumerated on the schema, exceptions caused by a bad syntax cannot happen.

Registering the parser

The last step is to register the parser in Spring. First, you just have to create a class that extends org.springframework.beans.factory.xml.NamespaceHandlerSupport and register the handler under the XML tag name in its init() method:

public class EhCacheNamespaceHandler extends NamespaceHandlerSupport {

  public void init() {

    registerBeanDefinitionParser("cache", new EhCacheBeanDefinitionParser());
  }
}

Should you have more parsers, just register them in the same method under each tag name.

Second, just map the formerly created namespace to the newly created handler in a file META-INF/spring.handlers:

http\://blog.frankel.ch/spring/ehcache=ch.frankel.blog.spring.authoring.ehcache.EhCacheNamespaceHandler

Notice that you map the declared schema file to the real schema but the namespace to the handler.

Conclusion

Now, when faced by overly verbose bean configuration, you have the option to use this nifty 4-steps techniques to simplify it. This technique is of course more oriented toward product providers but can be used by projects, provided the time taken to author a namespace is a real time gain over normal bean definitions.

You will find the sources for this article here in Maven/Eclipse format.

To go further

  • Spring authoring: version 2.0 is enough since nothing changed much (at all?) with following versions
  • Spring’s Javadoc relative to authoring

Spring can inject Servlets too!

September 28th, 2009 1 comment

In this article, I will show you that Spring dependency injection mechanism is not restricted solely to Spring-managed beans, that is Spring can inject its beans in objects created by the new keywords, servlets instantiated in the servlet container, and pretty anything you like. Spring classical mode is to be an object factory. That is, Spring creates anything in your application, using the provided constructor. Yet, some of the objects you use are outer Spring’s perimeter. Two simple examples:

  • servlets are instantiated by the servlet container. As such, they cannot be injected out-of-the-box
  • some business objects are not parameterized in Spring but rather created by your own code with the new keyword

Both these examples show you can’t delegate to Spring every object instantiation.

There was a time when I foolishly thought Spring was a closed container. Either your beans were managed by Spring, or they didn’t: if they were, you could inject them with other Spring-managed beans. If they weren’t, tough luck! Well, this is dead wrong. Spring can inject its beans into pretty much anything provided you’re okay to use AOP.

In order to do this, there are only 2 steps to take:

Use AOP

It is done in your Spring configuration file.

<?xml version="1.0" encoding="UTF-8"?>
<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.0.xsd

http://www.springframework.org/schema/context

	http://www.springframework.org/schema/context/spring-context-2.5.xsd">

  <This does the magic />
  <context:spring-configured />

  <-- These are for classical annotation configuration -->
  <context:annotation-config />
  <context:component-scan base-package="ch.frankel.blog.spring.outcontainer" />

</beans>

You need also configure which aspect engine to use to weave the compiled bytecode. In this cas, it is AspectJ, which is the AOP component used by Spring. Since i’m using Maven as my build tool of choice, this is easily done in my POM. Ant users will have to do it in their build.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
...
  <properties>
    <spring-version>2.5.6.SEC01</spring-version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${spring-version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring-version}</version>
    </dependency>
    <dependency>
      <groupId>aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.5.4</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <configuration>
          <complianceLevel>1.5</complianceLevel>
          <aspectLibraries>
            <aspectLibrary>
              <groupId>org.springframework</groupId>
              <artifactId>spring-aspects</artifactId>
            </aspectLibrary>
          </aspectLibraries>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Configure which object creation to intercept

This is done with the @org.springframework.beans.factory.annotation.Configurable annotation on your injectable object.

@Configurable
public class DomainObject {

  /** The object to be injected by Spring. */
  private Injectable injectable;

  public Injectable getInjectable() {

    return injectable;
  }

  @Autowired
  public void setInjectable(Injectable injectable) {

    this.injectable = injectable;
  }
}

Now with only these few lines of configuration (no code!), I’m able to inject Spring-managed beans into my domain object. I leave to you to implement the same with regular servlets (which are much harder to display as unit test).

You can find the Maven project used for this article here. The unit test packaged shows the process described above.

To go further:

Top Eclipse plugins I wouldn’t go without

August 8th, 2009 4 comments

Using an IDE to develop today is necessary but any IDE worth his salt can be enhanced with additional features. NetBeans, IntelliJ IDEA and Eclipse have this kind of mechanism. In this article, I will mention the plugins I couldn’t develop without in Eclipse and for each one advocate for it.

m2eclipse

Maven is my build tool of choice since about 2 years. It adds some very nice features comparing to Ant, mainly the dependencies management, inheritance and variable filtering. Configuring the POM is kind of hard once you’ve reached a fairly high number of lines. The Sonatype m2eclipse plugin (formerly hosted by Codehaus) gives you a tabs-oriented view of every aspect of the POM:

  • An Overview tab neatly grouped into : Artifact, Parent, Properties, Modules, Project, Organization, SCM, Issue Management and Continuous Integration,
  • m2eclipse Overview tab Read more…