Securing middleware products

February 9th, 2010 Nicolas Frankel No comments

My work is IT architecture, meaning I focus on the early steps of a project. Once the application is in production, I usually leave it to systems and production engineers. For example, for JVM fine tuning, most of the clients I worked for have people that have the right skills to do that.

Nevertheless, I need sometimes to sully my nails. This happens in two cases: when the client is too small to have such dedicated teams or when its production team are not experienced enough to handle the problem at hand. Believe it or not, it happened to me that I had to show WebSphere administrators how to connect JAAC connectors to a LDAP server.

Anyway, I always value information on how to handle cases out of my usual scope: first, it never hurts to know more. Second, it is sometimes handy to sort what production teams tell you: some is real stuff, some is bulls. Likewise, I invite production teams to learn about development so that they may sort what is told to them too. Learning the other’s craft let you increase comprehension between different teams.

Free checklist audits

This week, I learned about a site that propose free benchmarks to audit your infrastructure’s security. This site is the Center for Internet Security. Proposed benchmarks are two-fold: part document about what is audited, part benchmarking tool. The former is freely downloadable; as for the second part, you must register. The rest of this article will focus on the document.

Though many subjects will always be beyond my reach (I will never accept to secure an Oracle Database), one document is of utmost interest to me: the benchmark on Apache  Tomcat.

This file include rules that, once you comply with them, will make your product more secure. Even if most of them are no-nonsense and you could think about it yourself, the document make a nice check-list. Some rules are really interesting in that I am afraid they are seldom enforced, some because of neglect, some because of lack of knowledge of the product.

Enhancements

Checklists provided by the CIS do lack some things though:

  • risk correlated to statistics. Some security holes aren’t used by many hackers. How should I prioritize?
  • risk correlated to damage. What’s the potential damage of not underdoing this action? For example, session hijacking will compromize users interactions with my application, not my server
  • trade-off. Many security features are not always desirable, and most have a trade-off, often in terms of performance. When I browse a merchant site, crypting my communications is overkill. Only during the payment phase is a real need to keep information secret.

Rules examples

For Tomcat, here’s is a sample of the audited rules.

Separate Web content directory from Tomcat’s system files

Tomcat comes with its own file structure, including a webapp directory where webapps should reside. Yet, nothing prevents webapps to be outside this directory, even on another partition. From a security point-of-view, this will avoid directory traversal exploits: if a malicious user gains access to the webapps directory, he will not have access to the server.

Moreover, from a maintenance point-of-view, you are able to upgrade Tomcat without redeploying your applications.

Disable session façade recycling

Tomcat’s model is to use façade on every entity of the HTTP model: request, response, session, etc. By default, Tomcat’s façades over sessions are reused when processing new requests in order to optimize memory use. Thus, this could lead a new request to have access to informations on sessions that are not tied to it. This is a security risk and should be turned off if one’s want to secure the server.

Disable auto-deployment

Tomcat’s default behaviour is to have a running thread that watches the webapps directory. Once a new war is detected by this thread, it deploys it automatically. Such action is very enjoyable in a development environment. In a production environment, users that have access to the directory could potentially put malicious webapps in it and have it deployed automatically. Thus, disabling auto-deployment increases the security of the Tomcat’ server.

Conclusion

Checklists provided by the CIS are very nice to have for production and security engineers. However, one should carefully evaluate the cost of enforcing the rule agains the risk of not enforcing it. Those are either not detailed enough in the documentation, or not provided at all.

To go further:

Categories: Technical Tags: ,

Maven The complete reference

February 3rd, 2010 Nicolas Frankel 2 comments

This review is about Sonatype’s Maven: The complete reference by Tim O’Brien, John Casey, Brian Fox, Jason Van Zyl, Eric Redmond and Larry Shatzer.

Disclaimer: I learned Maven from Sonatype’s site 3 years ago. I found it was a great tool to learn Maven. Now that I have a little more experience in the tool, I tried to write this review in an objective manner.

Facts

  1. 13 chapters, 267 pages, free (see below)
  2. This book is intended for both readers who wants to learn Maven from scratch and for readers who need to look for a quick help on an obscure feature
  3. A whole chapter is dedicated to the Maven assembly plugin
  4. Another chapter is dedicated to Flexmojos, a Sonatype plugin to manage Flex projects

Pros

  1. First of all, this book is 100% free to view and to download. This is rare enough to be state!
  2. Complete reference books are sometimes a mere paraphrase of a product’s documentation. This one is not. I do not claim I’m a Maven expert but I did learn things in here
  3. This book is up-to-date with Maven 2.2. For example, it explains password encryption (available since Maven 2.1.0) or how to configure plugins called from the command line differently using default-cli (since Maven 2.2.0)
  4. A very interesting point is a list of some (all?) JEE API released by the Geronimo project and referenced by groupId and artifactId. If you frown because the point is lost on you, just try using classes from activation.jar (javax.activation:activation): you’ll never be able to let Maven download it for you since it is not available in the first place for licensing reasons. Having an alternative from Geronimo is good, knowing what is available thanks to the book is better

Cons

To be frank, I only found a problem with Maven: The complete reference. Although a whole chapter is written on the Maven Assembly plugin, I understood nothing from it… The rest of the book is crystal clear, this chapter only obfuscated the few things I thought I knew about the plugin.

Conclusion

This book is top quality and free: what can I say? If you’re a beginner in Maven, you’ll find a real stable base to learn from. If you need to update your knowledge, you will find a wealth of information. If you’re a Maven guru, please contribute to the Assembly plugin’s chapter. I can only give a warm thank you for Sonatype’s effort for giving this quality book to the community.

Categories: Book review Tags: , ,

Context root tweaking

February 1st, 2010 Nicolas Frankel No comments

JEE never ceases to amaze me. Even when I think I’m on top and I know all there’s to know about webapps, I’m in for a surprise. Good news is, whatever you think you know about a subject, there’s still room for one more fact. Bad news is, I’m deeply disturbed by what I learned.

Fact is: web applications context root can contain the / characte, meaning an URL such as http://localhost/multipart/context can refer to the root of the multipart/context webapp as well as to the context servlet mapping of the http://localhost/multipart webapp. When I was told that, my first reaction was disbelief. I immediately hurried to run a few tests on the JOnAS and JBoss application servers and it confirmed that was entirely possible.

In fact, if you look at the application.xml XML Schema, you see that the context-root is of a type that extends string (with an id) :

This means the context root can effectively contains anything, including slashes, backslashes and what have you.

The J2EE 1.4 specifications does not enforce additional constraints (p 125) :

Each web module must be given a distinct and non-overlapping name for its context root. [...] See the servlet specification for detailed requirements of context root naming.

I did not see additional requirements in the Servlet 1.4 specifications for the context root.

Tomcat even takes this tweak into account when creating Context with individual XML files. It calls it “multi-level context paths” :

In individual files (with a “.xml” extension) in the $CATALINA_HOME/conf/[enginename]/[hostname]/ directory. The name of the file (less the .xml) extension will be used as the context path. Multi-level context paths may be defined using #, e.g. foo#bar.xml for a context path of /foo/bar.

So, in order to deploy the context.war under the multipart/context root, you’ll have to name the context XML file multipart#context.xml.

The content of the file is the following:

<?xml version='1.0' encoding='utf-8'?>
<Context docBase="${catalina.home}/context.war" />
<!-- this means the context.war should be available at the root of Tomcat -->

In the tests I’ve made, if the multi-level context path shadows a classic context-root with a servlet mapping, the former takes precedence. I do not advise using this since the case is not specified in the specification, it could be handled differently from product to product.

OK, now we’ve established these facts, what is the point in knowing this, aside from setting you as the übergeek in a JEE geek convention? Since http://localhost/multipart/context and http://localhost/multipart are clearly separated web applications, they do not even share context.

In my case, that was the solution for a simple use-case. Imagine monitoring web applications: you know the URL you have to monitor. Now a product, developped in-house for diagnostics purpose, is deployed side-by-side with each webapp in webapp form. It would be very nice if you could reach the diagnostics webapp without looking at the documentation to know its URL. Let’s say it is the business webapp’s URL appended with /diag.

So, if the main webapp’s URL is http://myserver.com/mywebapp and the person in charge of monitoring knows about it, he knows he has to access http://myserver.com/mywebapp/diag and he gets what he wants! On the development side, it means both webapps are different products, are developed by different teams and have different lifecycles.

Categories: JEE Tags: , , ,

Typology of Rich Client technologies

January 22nd, 2010 Nicolas Frankel 2 comments

Chances are, if you are an software architect and need to make applications available over the network, you are asking yourself what client technology to use. In this article, I will try to list the solutions used previously and then elaborate on the solutions available today.

History

At the beginning, applications were solely deployed on a big machine. Everything happened there. To use the software, you needed to use a poor user interface aptly named a passive terminal. It output text: if you were lucky, you had colors! It was the one tier era.

The next phase started when the cost of  micro-computers went down. Every enterprise wanted to have some. The software industry evolved and moved the applications from the mainframe to the individual computers. It is a move that is still not finished – some companies still have mainframes – but the proof of this is that not many enterprises are migrating from clustered servers to mainframes. Data stayed on the server though: this was the 2-tier era.

Anyway, as software began to flourish on the user’s computer, so did the problems. At first, it was only technical problems: since hard drive space was limited, software vendors toyed with the ability to share libraries among applications. Thus started the infamous DLL hell that sometimes persist today. But the real problems appeared when the number of machines grew exponentially: the deployment of an application on 1′000 or 10′000 computers became a project in itself.

These disadvantages (and the associated growing costs) made some people think lateraly. What if the software was installed on a single node and the user accessed this node through the network? This could solve both the DLL hell and the deployment costs problems. Some devious minds even had the technology to do that just at hand: HTML over HTTP. It was the 3-tier era and we still live in it. Even though you can always add more tier, it doesn’t change the fundamental paradigm.

Limits of the HTML over HTTP model

HTML and HTTP have fundamental flaws for use as an application interface, though. HTML’s real motivation is to navigate through a text document’s maze and HTTP’s only goal is to transmit HTML over the network.

Thus, use of these technologies in ways that were not originally intended now show their limits:

  • browsers are not compatible. That’s sometimes the case not only between two versions of the same browsers but between the same version on two different operating systems
  • the complexity and the costs are transferred from the deployment phase to the development phase. A JEE developer have to know the following stack: Java, Servlet, JSP, HTML, JavaScript and CSS, just to name a few
  • the document centric model of HTTP forces the reload of the entire page, even if just a few elements have changed. The network speed becomes the critical factor
  • users complain about the limited user interactions. Ever tried to filter a combo box in pure HTML?

With the help of Microsoft, AJAX* came to the rescue of the last two problems: AJAX let you update part(s) of the page without a complete reload and give you access to widgets that propose professional user interaction.

Unfortunately, AJAX aggravates the first two problems: what is the support of this new technology among the browsers? Creating the XMLHTTPRequest is a matter or whether the browser is Internet Explorer or not. Even worse, the technology stacks one more component now. You could argue that using an AJAX framework can ease development but the problem stays the same, one more component whatsoever.

For those of you that may think HTML 5 as the panacea, I will respectfully remind you that the HTML 4 specification is dated 1999 and that the HTML 5 specification is still in draft: 10 years in our trade is likely to kill any good idea before its birth. But that’s a post for another time ; back on track, please.

Typology

That said, today’s is flooded with plenty of Rich Client technologies aimed at enhancing or replacing our familiar technologies. I will present here only technologies that keep the single point of deployment paradigm (clustering excluded), meaning applications should be able to update (or be updated) quickly and painlessly.

The following picture is a shot at classifying presentation layer technologies in the Java ecosystem. Notice that some may be used in other ecosystems too since they are technology neutral from a server point of view.

Words of advice:

  • this typology tries to dispatch very different technologies into cleanly separate categories. As such, some are more artificial than others. Moreover, some techs may legitimately belong to more than one category
  • don’t hold it against me if your favorite tech isn’t shown above. I have not a complete knowledge of a very moving and innovating landscape

Evolutions

On the right wing, we see technologies that represent a real evolution of the client. They all run over a virtual machine installed on the client computer.

From there, the main difference is whether the application is displayed through the browser or directly. The former are still somehow tied to the browser, such as Java Applets**, Flex that use the Flash plugin or even Firefox plugins. Each of them has a standalone equivalent.

The latter represent a new frame of mind where applications are clearly distinct from sites and are available separately from the tool used to browse sites. Apart from Air that is inspired by the JVM but with higher level considerations, two technologies are worth noting:

  • The JNLP file format, which is an external deployment descriptor available on the web for any Java application. Implementations include Java Web Start, Sun’s solution and an OpenSource alternative which is no more maintained, NetX. Both have the ability to read the JNLP in order to download, deploy and run the described application. They both use the JVM
  • Eclipse Rich Client Platform, which is a basis to create applications upon. Such applications can have the ability to update themselves virtually for free: only declarative use of such a feature is needed. Eclipse RCP also uses a JVM to run

Enhancement

On the left wing, we have technologies that want to enhance the current HTTP – HTML – DOM – ECMAScript – CSS stack. This branch is dependent on the browser’s implementation of the previous technologies specifications, especially ECMAScript. The main subdivision criterion is how the files are generated:

  • the first branch manipulates DOM on the client side. This is the domain of ECMAScript with products such as jQuery, Dojo and others.
  • the second branch creates HTML and JavaScript on the server side at runtime. Those frameworks are nowadays clearly component oriented and such is the realm of JSF
  • the third branch also creates HTML and JavaScript on the server side but at compile time. This is the original approach of GWT

Choice criteria

With all these technologies available, I think now is the right time for an enterprise to consider what rich client tech to use since the HTML paradigm is at an end and there are plenty (too much?) to choose from.

Five or so years ago, when doing Java development, you automatically choosed Struts. Nowadays, the question needs to be asked. But first, what criteria shall be used in order to evaluate the solution(s)? IMHO, these criteria shouldn’t all be technically oriented. The provider or the licence type are equally important because the durability is at the heart of the matter: some IS are built to last with 10 years in mind! The solution chosen will become the company’s standard, so it is a matter of investment and nobody likes wasting money, shareholders even less.

*In the rest of the post, AJAX will be the catchall word for both true AJAX and AJAJ (with JSON instead of XML)
**It it my personal opinion that applets, despite technical drawbacks, were years ahead of their time and for this reason, didn’t catch on. The Apache Pivot project is a framework built upon Applet

My first try at Flex

January 21st, 2010 Nicolas Frankel No comments

Flex is now approaching its 4th version. Even since its start, it looked promising. Until some time ago, I didn’t look much into it for it was not Open enough. Two years ago, in order to use Flex application freely, you had to limit yourself to a little subset of Flex.

This has changed. At the end of last year, though, my client gave me the opportunity to prototype a simple application and I dived into it. This development gave me an insight into BlazeDS, Spring BlazeDS and Flex itself. Of course, I realized I barely scratched the surface of it. In order to go further into the user interface itself, I created my resume in Flex.

This screen (I can’t call it an application) has the following features:

  • Resource loading: I made the screen so that the resume is available outside it. I use the URLLoader object and reacts according to success / failure events
  • XML parsing: the resume is available in XML format and each part of the screen uses part of it
  • HTML formatting. Since the XML Schema I use is Europass, I cannot do what I want. In order to display things the way I want them, I had to clutter the XML with HTML tags and use the HTML formatting through Flex
  • Internationalization: the feature is done, I just have to translate the resume itself in English (no small feat for me) and German (will need help!)
  • Mavenization: the entire build is done with the help of Maven and the excellent FlexMojos. The latter let me build Flex without the need of FlexBuilder
  • Components: I used modular components so that the resume displayes at the center of the screen can be shared (provided you supply the resume with valid XML). Anyone interested?

Due to my lack of knowledge, the implementation of only these took me some time. Yet, I’m very positive about the technology.

I only discovered a problem lately: not all the classes documented in the FlexDocs are available freely. Some, such as the AdvancedDataGrid, are not included in framework.swc and are only usable for a fee. Even though I’m French (and as such labeled as a communist in the US), I understand Adobe’s strategy to make some components free and some not. IBM does the same with Eclipse plugins. What I find devious is that the documentation is aggregated and does not make such disctinction.

Anyway, my resume is here.

http://livedocs.adobe.com/flex/3/langref/index.html
Categories: Development Tags: , , , , ,

Discover Spring authoring

December 29th, 2009 Nicolas Frankel 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

HTML UI over a REST backend

December 26th, 2009 Nicolas Frankel No comments

In this article, I will show you that forms sent by browsers to a server can only use GET and POST HTTP methods and which workaround to apply in order to still use a REST backend.

REST web-services are becoming more and more common in today’s landscape. We can only imagine the reasons, but I guess that SOAP’s structured approach is only useful in the most complex use-cases and is overkill the rest of the time. On the contrary, REST is quite easy to setup.

In the Java world, REST has its own specification, JAX-RS with JSR 311, and is supported by all major frameworks :

In my humble opinion, it is not inconceivable that, given the adoption of REST, the next step would be the development of REST backends accessible by standard clients and browsers alike, in order to factorize code and thus decrease costs.

Traditionallly, making a resource accessible on the web is realized through a hyperlink. Hyperlinks use the GET method. Likewise, REST is based on using the HTTP methods where each has an associated verb:

HTTP method Verb
POST Create
GET Read
PUT Update
DELETE Delete

Unluckily, the real world comes into play. In order for this to work, the HTML 4 specification is a big obstacle in the way:

The FORM element [...]

Method: this attribute specifies which HTTP method will be used to submit the form data set. Possible (case-insensitive) values are “get” (the default) and “post”.

The implication is that HTML 4 compliant browsers will only let you read and create but not update nor delete. For example, the versions of Firefox and Internet Explorer I used, respectively 3.5.6 and 6.0 (!) use POST for POST and GET for everything else. That’s a real case against using REST. There are some workarounds, though.

The first one is not to use the HTTP method for the verb but to put it in the URL. Thus

  • to access a customer, one would use http://frankel.ch/get/customer/1
  • and to remove one, http://frankel.ch/delete/customer/1

This clearly violates REST’s principle of using the HTTP method for the verb but this works for simple cases.

The second workaround is a bit more complex but it has two big advantages: it conforms to REST principles and it is usable with most modern-days browsers.

The trick is to use a neat little object created by Microsoft but now implemented everywhere, the XMLHttpRequest object. Yes, this is the object at the foundation of Ajax but is is also the solution of our problem. XMLHttpRequest’s open() method takes two parameters, the first being the HTTP method to use for accessing the url (which is the second parameter). Now you can pass the verb you want, like the following example.

xmlhttp = new XMLHttpRequest();
xmlhttp.open('DELETE', 'http://frankel.ch/customer/1');
xmlhttp.send(null);

Morevover, you can not only use the 4 CRUD verbs but also any verb you want.

This solution has two main limitations:

  • it requires modern-day browsers since the XMLHttpRequest object is not available in more ancient ones
  • it requires JavaScript, so you need to enable it on client browsers and you need to manage browser compatibilities. For example, the above script with Firefox 3.5 but not IE 6 (and to be blunt, I’m not really bothered by it)

It seems this hack will be rendered useless by the HTML 5 specifications which declares (in their draft state) that all 4 basic CRUD verbs will have to be supported.

You can find an example for this article here. Tu use, navigate to http://localhost:8080/httpmethods/ if deployed in Eclipse. It was tested on Firefox 3.5 and works on it flawlessly. On the contrary, it doesn’t work for IE 8 since my script is not crafted to be cross-browsers. For Tomcat users, you have to add JSTL capabilities to Tomcat (meaning adding standard.jar and jstl.jar in the commons/lib directory).

To go further :

Hibernate hard facts part 3

December 13th, 2009 Nicolas Frankel No comments

Hibernate LogoIn the third article of this serie, I will show how to tweak Hibernate so as to convert any database data types to and from any Java type and thus decouple your database model from your object model.

Custom type mapping

Hibernate is a very powerful asset in any application needing to persist data. As an example, I was tasked this week to generate the Object-Oriented model for a legacy database. It seemed simple enough, at first glance. Then I discovered a big legacy design flaw: for historical reasons, dates were stored as number in the YYYYMMDD format. For example, 11th december 2009 was 20091211. I couldn’t or rather wouldn’t change the database and yet, I didn’t want to pollute my neat little OO model with Integer instead of java.util.Date.

After browsing through Hibernate documentation, I was confident it made this possible in a very simple way.

Creating a custom type mapper

The first step, that is also the biggest, consist in creating a custom type. This type is not a real “type” but a mapper that knows how to convert from the database type to the Java type and vice-versa. In order to do so, all you have is create a class that implements org.hibernate.usertype.UserType. Let’s have a look at each implemented method in detail.

The following method gives away what class will be returned at the end of read process. Since I want a Date instead of an Integer, I naturally return the Date class.

public Class returnedClass() {

  return Date.class;
}

The next method returns what types (in the Types constants) the column(s) that will be read fromhave. It is interesting to note that Hibernate let you map more than one column, thus having the same feature as the JPA @Embedded annotation. In my case, I read from a single numeric column, so I should return a single object array filled with Types.INTEGER.

public int[] sqlTypes() {

  return new int[] {Types.INTEGER};

}

This method will check whether returned class instances are immutable (like any normal Java types save primitive types and Strings) or mutable (like the rest). This is very important because if false is returned, the field using this custom type won’t be checked to see whether an update should be performed or not. It will be of course if the field is replaced, in all cases (mutable or immutable). Though there’s is a big controversy in the Java API, the Date is mutable, so the method should return true.

public boolean isMutable() {

  return true;

}

I can’t guess how the following method is used but the API states:

Return a deep copy of the persistent state, stopping at entities and at collections. It is not necessary to copy immutable objects, or null values, in which case it is safe to simply return the argument.

Since we just said Date instances were mutable, we cannot just return the object but we have to return a clone instead: that’s made possible because Date’s clone() method is public.

public Object deepCopy(Object value) throws HibernateException {

  return ((Date) value).clone();
}

The next two methods do the real work to respectively read from and to the database. Notice how the API exposes ResultSet object to read from and PreparedStatement object to write to.

public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {

  Date result = null;

  if (!rs.wasNull()) {

    Integer integer = rs.getInt(names[0]);

    if (integer != null) {

      try {

        result = new SimpleDateFormat("yyyyMMdd").parse(String.valueOf(integer));

      } catch (ParseException e) {

        throw new HibernateException(e);
      }
    }
  }

  return result;
}

public void nullSafeSet(PreparedStatement statement, Object value, int index) throws HibernateException, SQLException {

  if (value == null) {

    statement.setNull(index, Types.INTEGER);

  } else {

    Integer integer = Integer.valueOf(new SimpleDateFormat("yyyyMMdd").format((String) value));

    statement.setInt(index, integer);
  }
}

The next two methods are implementations of equals() and hasCode() from a persistence point-of-view.

public int hashCode(Object x) throws HibernateException {

  return x == null ? 0 : x.hashCode();
}

public boolean equals(Object x, Object y) throws HibernateException {

  if (x == null) {

    return y == null;
  }

  return x.equals(y);
}

For equals(), since Date is mutable, we couldn’t just check for object equality since the same object could have been changed.

The replace() method is used for merging purpose. It couldn’t be simpler.

public Object replace(Object original, Object target, Object owner) throws HibernateException {

  Owner o = (Owner) owner;

  o.setDate(target);

  return ((Date) original).clone();
}

My implementation of the replace() method is not reusable: both the owning type and the name of the setter method should be known, making reusing the custom type a bit hard. If I wished to reuse it, the method’s body would need to use the lang.reflect package and to make guesses about the method names used. Thus, the algorithm for creating a reusable user type would be along the lines of:

  1. list all the methods that are setter and take the target class as an argument
    1. if no method matches, throw an error
    2. if a single method matches, call it with the target argument
    3. if more than one method matches, call the associated getter to check which one returns the original object

The next two methods are used in the caching process, respectively in serialization and deserialization. Since Date instances are serializable, it is easy to implement them.

public Serializable disassemble(Object value) throws HibernateException

  return (Date) ((Date) value).clone();
}

public Object assemble(Serializable cached, Object owner) throws HibernateException {

  return ((Date) cached).clone();
}

Declare the type on entity

Once the custom UserType is implemented, you need to make it accessible it for the entity.

@TypeDef(name="dateInt", typeClass = DateIntegerType.class)
public class Owner {

  ...
}

Use the type

The last step is to annotate the field.

@TypeDef(name="dateInt", typeClass = DateIntegerType.class)

public class Owner {

  private Date date;

  @Type(type="dateInt")
  public Date getDate() {

    return date;
  }

  public void setDate(Date date) {

    this.date = date;
  }
}

You can download the sources for this article here.

To go further:

Lombok reduces your boilerplate code

December 6th, 2009 Nicolas Frankel Comments off

In this article, I show you the power of the product I stumbled upon this week: Project Lombok enables you to modify bytecode at compile code. First, I will detail what features Lombok brings you out-of-the-box. In the second part of this article, I will describe how to extend it to generate you own code.

Introduction

Since the dawn of JEE, complaints have been filed regarding the complexity of coding components. I consider EJB v2 a very good example of this complexity: for just a simple EJB, you have to provide the EJB class itself and a home and an interface for each access type (local and remote). This makes it complex, error-prone and more importantly gives you less time to focus on business code where the real value is. Two initiatives show the will to decrease the amount of boilerplate code needed when coding:

  • the Spring Framework’s motto is to decrease JEE complexity. The boilerplate code is written once in the Spring framework and only used by projects.
  • EJB v3 has taken into account the lessons from Spring and aim to reduce boilerplate code too, making local and remote interfaces unnecessary. Eventually, the next version of the specification will make the local and remote home optional too.

The goal of Project Lombok is exactly the same as the previous initiatives but in order to do so, it uses another mechanism.

Annotation processing

Version 5 of the Java language introduced the concept of annotations, code meta-data that could be processed at compile time and/or runtime. Unfortunately, in JDK 5, processing annotations at compile is a 2-step process. First, you have to run the apt executable to process annotations, perhaps creating or modifying source files, then compile your sources with javac. That was not the best approach, so Java 6 removes apt and make javac able to manage annotations, streamlining the process to obtain a simpler single step computing. This is the path taken by Lombok.

Project Lombok

Lombok’s driving feature is to create code you need from annotations in order to reduce the amount of boilerplate code you have to write. It provides you with the following annotations that will change your code (if not your life) forever:

For example, while learning to code the OO way, you were drilled into making your fields private and into writing public accessors to access these fields:

public class Person {

  private String name;

  public String getName() {

    return name;
  }

  public void setName(String name) {

    this.name = name;
  }
}

Since this is a bother to write, some (if not all) IDE have a feature to generate the accessors. It has some drawbacks:

  • You have to manually remove the accessors if you remove the field
  • It clutters your real code with boilerplate code
  • Corollary: it takes a real effort to check whether an accessor already exist for a field in a long class

Moreover, creating accessors manually is error-prone: I once searched for hours for a bug in code developed by a fellow developer and finally found the setter was wrong.

Since getter / setter is only meta-data for a field, Lombok’s stance is to treat it like such: in Java, meta-data is managed with annotations. Look at the following code:

import org.lombok.Getter;
import org.lombok.Setter;

public class Person {

  @Getter @Setter
  private String name;
}

I decompiled the generated class (using JAD) and it creates exactly the same bytecode, only the source code is more concise and less error-prone.

When thinking, I found 3 arguments against using Lombok:

  1. The first argument against using such a strategy is that you can’t create a protected accessor like that. You’re wrong, Lombok is configurable:
  2. import lombok.AccessLevel;
    import org.lombok.Getter;
    import org.lombok.Setter;
    
    public class Person {
    
      @Getter @Setter(AccessLevel.PROTECTED)
      private String name;
    }

    And its true for all the provided annotations! Just look at them.

  3. The second argument against using Lombok is that you don’t know what it does behind the scene. It’s true, but the same could be said for AOP or CGLIB or whatever framework you’re using.
  4. The last argument and IMHO the only one valid enough is that it renders debugging more complex: but so is the use of Java dynamic proxies that Spring uses throughout its code, and still many projects use them.

Use and installation

Using Lombok is a 3-step process:

  1. Put the JAR on the classpath
  2. Add the annotation you want to use
  3. Compile with javac

There’s a catch, though. Notice the last statement and the emphasis on javac. Since most (if not all) the developers you and I know focus a little bit on productivity, chances are you’re using a IDE. I do not know about NetBeans and fellows, but my favorite IDE Eclipse does not use javac to compile but its own internal compiler.

Our friends from Lombok thought about that and Lombok is able to hook into Eclipse compiling process too. In order to do so, just launch lombok.jar and follow the instructions on you screen: it will just add 2 lines to your eclipse.ini.

A word of advice (since I made the mistake): if you launch Eclipse with a command that takes parameters, such as a Windows shortcut, these parameters take precedence and eclipse.ini is silently ignored. Just to let you know…

Lombok extensions

To my knowledge, there’s currently only a single extension of Lombok called Morbok. It lets you create your classical private static final logger with just an annotation.

The advantage of this is that Morbok automatically uses the fully qualified class name as the name of the logger so no more copy paste error. The disadvantage is that if you do not use Commons Logging as you logging framework, you have to configure each @Logger annotation with the framework you want to use, there’s no overall configuration: IMHO, that’s something that could be covered in the next version (is there’s one).

Architecture

First things first, Lombok needs a JDK 6 to compile since annotation processing is done in Java 5 with APT. For now, Lombok hooks into the compiling process immediately after the environment has built the AST for the class.

It then passes the structure thus formed to each of its referenced handlers. There’s a single handler for each annotation: HandleGetter for @Getter, HandlerSetter for @Setter and so on. Handlers are, guess what, responsible for handling annotations.

Extending Lombok

Extending Lombok is a 3-step process:

  1. Create the annotation. Since the annotation is used at compile-time, it can be safely be discarded afterwards so its retention policy can be left to its default value (namely RetentionPolicy.SOURCE)
  2. Create the handler. A handler is a class that directly implements lombok.javac.JavacAnnotationHandler<T extends Annotation>. Why directly? Because Lombok uses the ServiceProvider service and it’s one of its limitations
  3. Reference the fully qualified class name of the handler in a file named lombok.javac.JavacAnnotationHandler under META-INF/services

The real coding takes place in step 2: the interface has a single method handle(AnnotationValues<T> annotation, com.sun.tools.javac.tree.JCTree.JCAnnotation ast, JavacNode annotationNode). Notice the 2nd parameter package? It’s denotes Sun private implementation. It has some big drawbacks:

  • The documentation is sparse if not completely unavailable. You go into unknown territory here
  • Since the com.sun.tools.javac is not part of the public API, it can change at a moment’s notice. You can break your code with each update
  • Remember that previously, I talked about this being only good for Java? That’s still true. If you want this new annotation to work under Eclipse, that’s another handler to write

Example

As an example, I coded an embryo for a @Delegate annotation. Such an annotation on a field indicates that the declaring class should have the same public methods as the field’s class and each method’s body should be a call to its delegate’s method.

public class Delegator {

  @Delegate
  private DelegateObject object;

  ...
}

public class DelegateObject {

  public void doSomething() {
    ...
  }
}

The previous code should generate the same bytecode as the following code:

public class Delegator {

  private DelegateObject object;

  public void doSomething() {

    object.doSomething();
  }
  ...
}

As yet:

  • it does not handle generics
  • the only handler provided is for javac
  • it is not configurable

The final implementation is left for the brave readers: original sources are here in Eclipse/Maven format.

Conclusion

Some improvements could quickly be made to Lombok. First, I don’t like the monolithic structure the JAR has. IMHO, it could be nicely decoupled into 3 separate JARs: the Lombok agent itself, the provided annotations and associated handlers and finally, the installer.

Moreover, coding two handlers for each annotation is a lost of time. What if you need to support NetBeans too? Perhaps using the Service Provider is a mistake…

Finally, depending on Sun’s internal compiler API is too big a risk. I think that if Lombok could provide a facade to this API, it could be less risky for enterprise to take this road and the bridging could be made by people who understand the API (the Lombok team) and not base developers (like myself).

All in all, and despite these flaws, Lombok looks like a very promising project that could well mimic Spring’s success. That’s what I wish it anyway because it’s real sideway thinking that brings much added value: good luck for the future!

To go further:

Apache Maven 2 Effective implementation

December 5th, 2009 Nicolas Frankel 1 comment

Apache Maven 2 Effective implementation
This review is about Packt’s Apache Maven 2 Effective Implementation by Maria Odea Ching and Brett Porter.

Facts

  1. 12 chapters, 436 pages, 39.99$
  2. This book is intended for people that already have a good experience of Maven. The ‘About Maven’ part is as small as it can get, it is the opposite of what could be ‘Maven for Dummies’, where you learn to type mvn something.
  3. A good portion of the book is about tools that are part of the Maven ecosystem: Continuum for the CI part and Archiva for the repository part.
  4. A chapter is dedicated to testing, which test to pass automatically, what frameworks to use and how to configure the whole lot.

Pros

  1. People that wrote the book really know Maven intimately and it shows. I’m not a newbie myself and I learned some things that I have put to good use since then (or intend to in the near future).
  2. There’s an interesting multi-module structure described that is designed for big projects. It shows Maven structure can be quite adaptable and module design should be custom tailored to each project’s needs. A module for each layer / artifact is only the first step.
  3. The part about Maven plugins is very interesting. Since Maven adopts a plugin architecture, knowing what plugins can do what, why and how to use it is invaluable.
  4. So is the part about testing: a good idea is that some tests should not be passed everytime, but instead launched manually or attached to a specific module.

Cons

  1. The tools used are Continuum and Archiva but there’s no justification for this choice. One could think that’s because they’re both Apache but that’s just not enough. Java.net’s Hudson seems the most used CI server and Sonatype’s Nexus is the reference for Maven repositories (although I have a soft spot for JFrog’s Artifactory).
  2. What I regret most is the part taken by reporting. My personal stance on this is that only very few organizations use these features, mainly Open Source organizations. Since you now have products such as Sonar, describing in detail how to configure Maven reporting is a waste of time. Since the book is already oriented toward tools, why doesn’t it just teach how to use Sonar (since it cites Sonar anyway)?

Conclusion

All in all, Apache Maven 2 Effective implementation is not a great book but rather a good book to have when you already worked with Maven so as to stand back a little and build your projects more effectively with Maven in the future.

Categories: Book review Tags: ,