XML configuration in Web Beans

Posted by    |       CDI

The Web Beans specification defines an XML configuration format that uses XML namespaces to achieve typesafety.

Imagine that we have the following class:

public class ShoppingCart {
    
    private final PaymentProcessor paymentProcessor;
    private final User customer;
    
    public ShoppingCart(PaymentProcessor paymentProcessor, User customer) { 
        this.paymentProcessor = paymentProcessor;
        customer = customer;
    }

    ...

}

Of course, we could configure its scope, name and dependencies using annotations:

@SessionScoped
@Named("cart")
public class ShoppingCart {
    
    private final PaymentProcessor paymentProcessor;
    private final User customer;
    
    @Initializer
    public ShoppingCart(@PayBy(CREDIT_CARD) PaymentProcessor paymentProcessor, @LoggedIn User customer) { 
        this.paymentProcessor = paymentProcessor;
        customer = customer;
    }

    ...

}

But suppose that this class is defined in a reusable library, and that this metadata depends upon the application in which it is deployed. Then it would be better to define the metadata in XML. The Web Beans Early Draft defined a configuration format that was similar to other Java EE deployment descriptors:

<web-beans ...>

   <component>

      <class>org.example.ShoppingCart</class>
      <named>cart</named>
      <scope>javax.webbeans.SessionScoped</scope>

      <constructor>
         <param>
            <type>org.example.PaymentProcessor</type>
            <binding>org.example.PayBy(CREDIT_CARD)</binding>
         </param>
         <param>
            <type>org.example.User</type>
            <binding>org.example.LoggedIn</binding>
         </param>
      </constructor>

   </component>

</web-beans>

There are several problems with this approach:

  • it's quite verbose
  • the interesting information (the type names) can't be validated against an XML schema
  • the interesting information can't be autocompleted without special tooling that is aware of the Java types

Even worse, the XML format places a bit too much emphasis upon the actual Java constructs (constructor, param, etc) which is inappropriate if the use case is configuration of a third-party library.

Therefore, the Web Beans public draft defines a different approach, inspired by Spring 2 and Seam 2. The idea is to define an XML namespace corresponding to each Java package. For example, the namespace urn:java:org.example represents the Java package org.example. XML elements in this namespace represent types or members of types in that package.

We can re-write our example as follows:

<WebBeans xmlns="urn:java:javax.webbeans"
          xmlns:eg="urn:java:org.example">

   <eg:ShoppingCart>
      <Named>cart</Named>
      <SessionScoped/>
      
      <eg:PaymentProcessor>
         <eg:PayBy>CREDIT_CARD<eg:PayBy>
      </eg:PaymentProcessor>
      
      <eg:User>
         <eg:LoggedIn/>
      </eg:User>
      
   </eg:ShoppingCart>
   
</WebBeans>

Now, what's really fantastic about this approach is that we can write an XML schema for each namespace, letting us take advantage of autocompletion and validation when we write the XML document. Even better, the RI project plans to create a Java 6 annotation processor (a compiler plugin for javac) that automatically generates this schema as part of the compilation process. So every time you compile your code, you'll immediately see any resulting errors in your XML configurations! Thus, this approach tackles one of the main causes of the XML hell that affects Java development.

Personally, I'm pretty bewitched by any solution which is simultaneously more typesafe and less verbose (usually typesafety costs in verbosity). However, at least one of the members of the Web Beans EG is concerned that the typesafe XML format is inconsistent with the format used by other Java EE deployment descriptors, and potentially confusing.

Therefore, I would like to gather feedback from the community on this issue. Which style do you prefer? Please let us know what you think in comments.


Back to top