Red Hat

In Relation To Java EE

In Relation To Java EE

Web Beans Sneak Peek Part V: Interceptors and events

Posted by    |       |    Tagged as CDI Java EE

/This is the fifth installment of a series of articles describing the current status of the Web Beans specification. Please read the first, second, third and fourth installments first./

One of the themes of Web Beans is loose coupling. We've already seen three means of achieving loose coupling:

  • component types enable /deployment time/ polymorphism
  • producer methods enable /runtime/ polymorphism
  • contextual lifecycle management decouples component lifecycles

These techniques serve to enable loose coupling of client and server. The client is no longer tightly bound to an implementation of an API, nor is it required to manage the lifecycle of the server object. This approach lets /stateful objects interact as if they were services/.

Web Beans provides two extra important facilities that further the goal of loose coupling:

  • interceptors decouple technical concerns from business logic
  • event notifications decouple event producers from event consumers

Let's explore these features.

Interceptors

Web Beans re-uses the basic interceptor architecture of EJB 3.0, extending the functionality in two directions:

  • any Web Bean may have interceptors, not just session beans
  • Web Beans features a more sophisticated annotation-based approach to binding interceptors to components

Suppose we want to declare that some of our components are transactional. The first thing we need is an /interceptor binding annotation/ to specify exactly which components we're interested in:

@InterceptorBindingType
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Transactional {}

Now we can easily specify that our ShoppingCart is a transactional object:

@Transactional @Component
public class ShoppingCart { ... }

Or, if we prefer, we can specify that just one method is transactional:

@Component
public class ShoppingCart {
    @Transactional public void checkout() { ... }
}

That's great, but somewhere along the line we're going to have to actually implement the interceptor that provides this transaction management aspect. All we need to do is create a standard EJB interceptor, and annotate it @Interceptor and @Transactional.

@Transactional @Interceptor
public class TransactionInterceptor {
    @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}

Finally, we need to /enable/ our interceptor in web-beans.xml.

<interceptors>
    <interceptor>to.relation.in.TransactionInterceptor</interceptor>
</interceptors>

Whoah! Why the angle bracket stew?

Well, the XML declaration solves two problems:

  • it enables us to specify a total ordering for all the interceptors in our system, ensuring deterministic behavior
  • it lets us enable or disable interceptor classes at deployment time

For example, we could specify that our security interceptor runs before our TransactionInterceptor. And we can turn them both off in our test environment.

Interceptor bindings with members

Suppose we want to add some extra information to our @Transactional annotation:

@InterceptorBindingType
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Transactional {
    boolean requiresNew() default false;
}

Web Beans will use the value of requiresNew to choose between two different interceptors, TransactionInterceptor and RequiresNewTransactionInterceptor.

@Transactional(requiresNew=true) @Interceptor
public class RequiresNewTransactionInterceptor {
    @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}

Now we can use RequiresNewTransactionInterceptor like this:

@Transactional(requiresNew=true) @Component
public class ShoppingCart { ... }

But what if we only have one interceptor and we want the container to ignore the value of requiresNew when binding interceptors? We can use the @NonBinding annotation:

@InterceptorBindingType
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Secure {
    @NonBinding String[] rolesAllowed() default {};
}

Multiple interceptor binding annotations

Usually we use combinations of interceptor bindings types to bind multiple interceptors to a component. For example, the following declaration would be used to bind TransactionInterceptor and SecurityInterceptor to the same component:

@Secure(rolesAllowed="admin") @Transactional @Component
public class ShoppingCart { ... }

However, in very complex cases, an interceptor itself may specify some combination of interceptor binding types:

@Transactional @Secure @Interceptor
public class TransactionalSecureInterceptor { ... }

Then this interceptor could be bound to the checkout() method using any one of the following combinations:

@Component
public class ShoppingCart {
    @Transactional @Secure public void checkout() { ... }
}
@Secure @Component
public class ShoppingCart {
    @Transactional public void checkout() { ... }
}
@Transactionl @Component
public class ShoppingCart {
    @Secure public void checkout() { ... }
}
@Transactional @Secure @Component
public class ShoppingCart {
    public void checkout() { ... }
}

Binding an interceptor to /everything/

What if we want an interceptor for /every/ component? Easy, just declare the interceptor without any interceptor binding type!

@Interceptor
public class UberInterceptor { ... }

Interceptor binding type inheritance

One of the awful, embarrassing, mistakes of the Java language is the lack of support for annotation inheritance. Really, annotations should have reuse built in, to allow this kind of thing to work:

public @interface Action extends Transactional, Secure { ... }

Well, fortunately, Web Beans works around this missing feature of Java:

@Transactional @Secure
@InterceptorBindingType
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action { ... }

And now any component annotated @Action will be bound to both TransactionInterceptor and SecurityInterceptor. (And even TransactionalSecureInterceptor, if it exists.)

Events

/Please note that the following section describes functionality that is still under active discussion in the Web Beans expert group!/

The Web Beans event notification facility allows components to interact in a totally decoupled manner. Event /producers/ raise events that are then delivered to event /observers/. This basic schema might sound similar to the observer/observable pattern, but there are a couple of twists:

  • not only are event producers decoupled from observers; observers are completely decoupled from producers
  • observers can specify a combination of selectors to narrow the set of event notifications they will receive
  • observers can be notified immediately, or can specify that delivery of the event should be delayed until the end of the current transaction

Event observers

An /observer method/ is a method of any Web Bean with a parameter annotated @Observes.

public void onAnyDocumentEvent(@Observes Document document) { ... }

The annotated parameter is called the /event parameter/. Observer methods may also specify selectors, which are called /event binding types/. An event binding type is just an annotation:

@EventBindingType
@Target({PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface Updated { ... }

We specify the selector by annotating the event parameter:

public void afterDocumentUpdate(@Observes @Updated Document document) { ... }

The observer method may have additional parameters, which are injected, according to the usual Web Beans semantics:

public void afterDocumentUpdate(@Observes @Updated Document document, @Current User user) { ... }

Event producers

The event producer may obtain an /event notifier/ by injection:

@In @Notifier Event<Document> documentEvent;

The @Notifier annotation implicitly defines a Web Beans component with scope @Dependent and component type @Standard.

A producer raises events by calling the one and only method of the Event interface:

documentEvent.raise(document);

To specify a selector, the producer may either pass an instance of the event binding type to the raise():

documentEvent.raise(document, new Updated(){});

Of may specify the selector at the injection point:

@In @Notifier @Updated Event<Document> documentUpdatedEvent;

Event bindings with members

An event binding type may have annotation members:

@EventBindingType
@Target({PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface Role {
    RoleType value();
}

The member value is used to narrow the messages delivered to the observer:

public void adminLoggedIn(@Observes @Role(ADMIN) LoggedIn event) { ... }

And can be specified by the event producer either statically:

@In @Notifier @Role(ADMIN) Event<LoggedIn> LoggedInEvent;

Or dynamically:

documentEvent.raise( document, new Role() { public void value() { return user.getRole(); } } );

Multiple event bindings

Event binding types can be combined, for example:

@In @Notifier @Blog Event<Document> blogEvent;
...
if (document.isBlog()) blogEvent.raise(document, new Updated(){});

In this case, any of the following observer methods would be notified:

public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }
public void afterDocumentUpdate(@Observes @Updated Document document) { ... }
public void onAnyBlogEvent(@Observes @Bog Document document) { ... }
public void onAnyDocumentEvent(@Observes Document document) { ... }

Transactional observers

Transactional observers receive their event notifications during the before or after completion phase of the transaction in which the event was raised. For example, the following observer method needs to refresh a query result set that is cached in the application context, but only when transactions that update the Category tree succeed:

public void refreshCategoryTree(@AfterTransactionSuccess @Observes CategoryUpdateEvent event) { ... }

There are three kinds of transactional observers:

  • @AfterTransactionSuccess observers are called during the after completion phase of the transaction, but only if the transaction completes successfully
  • @AfterTransactionCompletion observers are called during the after completion phase of the transaction
  • @BeforeTransactionCompletion observers are called during the before completion phase of the transaction

Transactional observers are very important in a stateful component model, because state is often held for longer than a single atomic transaction.

/This is the fourth installment of a series of articles describing the current status of the Web Beans specification. Please read the first, second and third installments first./

So far, we've seen a few examples of /scope type annotations/. The scope of a component determines the lifecycle of the component instances, and makes a particular instance visible to all components executing in a particular context.

For example, if we have a session scoped component, CurrentUser, all components that are called in the context of the same HttpSession will see the same instance of CurrentUser. This instance will be automatically created the first time a CurrentUser is needed in that session, and automatically destroyed when the session ends.

Scope types

Web Beans features an /extensible context model/. It is possible to define new scopes by creating a new scope type annotation:

@Retention(RUNTIME)
@Target({TYPE, METHOD})
@ScopeType
public @interface ClusterScoped {}

Of course, that's the easy part of the job. For this scope type to be useful, we will also need to define a Context object that implements the scope! Implementing a Context is usually a very technical task, intended for framework development only.

We can apply a scope type annotation to a Web Bean implementation class to specify the scope of the component:

@ClusterScoped @Component
public class SecondLevelCache { ... }

We can even use the scope type to obtain an instance of the Context object for the scope:

Component<SecondLevelCache> cacheComponent = container.resolveByType(SecondLevelCache.class);
SecondLevelCache cache = container.getContext(ClusterScoped.class).get(cacheComponent);

Built-in scopes

Web Beans defines four built-in scopes:

  • @RequestScoped
  • @SessionScoped
  • @ApplicationScoped
  • @ConversationScoped

For a web application that uses Web Beans:

  1. any servlet has access to active request, session and application contexts
  2. any JSF request has access to an active conversation context

If the application tries to use a component with a scope that does not have an active context, a ContextNotActive exception is thrown by the Web Beans container at runtime.

The dependent psuedo-scope

In addition, there is the notion of the /dependent psuedo-scope/. We use the term psuedo-scope because there is no Context for this special scope.

A Web Bean may be declared to be a @Dependent component:

@Dependent @Component
public class Calculator { ... }

If this case, a new instance of the component is created each time the Web Beans container injects it. This means that any instance of a dependent component is bound to the object into which it was injected. Different clients always see different instances of a dependent component, no matter what context they execute in.

A open issue that currently exists in the Web Beans specification is the question of the default scope for a Web Bean component that does not explicitly declare a scope type. We've narrowed the options down to @RequestScoped and @Dependent, each of which has advantages and disadvantages.

Implicit dependent components

The built-in @New binding annotation allows /implicit/ definition of a dependent component at an injection point. Suppose we declare the following injected attribute:

@In @New Calculator calculator

Then a component with component type @Component, scope @Dependent, binding annotation @New, API type Calculator and implementation class Calculator is implicitly defined.

This is true even if Calculator is /already/ declared as a Web Beans component, for example:

@ConversationScoped @Component
public class Calculator { ... }

So the following injected attributes each get a different instance of Calculator:

@Component 
public class PaymentCalc {

    @In Calculator calculator;
    @In @New Calculator newCalculator;

}

The calculator field has a conversation-scoped instance of Calculator injected. The newCalculator field has a new instance of Calculator injected, with a lifecycle that is bound to the owning PaymentCalc.

This feature is particularly useful with resolver methods.

Resolver methods

According to the spec:

A Web Beans resolver method acts as a source of objects to be injected, where:
  • the objects to be injected are not required to be instances of Web Beans components,
  • the concrete type of the objects to be injected may vary at runtime or
  • the objects require some custom initialization that is not performed by the Web Bean constructor

For example, resolver methods let us:

  • expose a JPA entity as a Web Bean component
  • expose a JDK class as a Web Bean component
  • define multiple Web Bean components, with different scopes or initialization, for the same implementation class
  • vary a Web Bean component implementation class at runtime

In particular, resolver methods let us use runtime polymorphism with Web Beans. As we've seen, component types are a powerful solution to the problem of deployment-time polymorphism. But once the system is deployed, the component implementation is fixed. A resolver method has no such limitation:

@SessionScoped @Component
public class Preferences {
    
    private PaymentStrategyType paymentStrategy;
    
    ...
    
    @Resolves @Preferred @ApplicationScoped
    public PaymentStrategy getPaymentStrategy() {
        switch (paymentStrategy) {
            case CREDIT_CARD: return new CreditCardPaymentStrategy();
            case CHEQUE: return new ChequePaymentStrategy();
            case PAYPAL: return new PayPalPaymentStrategy();
            default: return null;
        } 
    }
    
}

Consider this injection point:

@In @Preferred PaymentStrategy paymentStrat;

When the container injects this field, the resolver method will be called and the returned PaymentStrategy will be injected into the field and bound to the application context. The resolver method won't be called again in the same application context. On the other hand, if we were to remove the @ApplicationScoped annotation:

@Resolves @Preferred
public PaymentStrategy getPaymentStrategy() {
    ...
}

Then the resolver method defaults to dependent scope, and it will be called /every time/ the field is injected!

Injection into resolver methods

There's one problem with this code. If CreditCardPaymentStrategy is a Web Bean component, it should be created by the Web Beans container, not by calling new. We can solve this problem by using injection into the resolver method:

@Resolves @Preferred @ApplicationScoped
public PaymentStrategy getPaymentStrategy(CreditCardPaymentStrategy ccps,
                                          ChequePaymentStrategy cps,
                                          PayPalPaymentStrategy ppps) {
    switch (paymentStrategy) {
        case CREDIT_CARD: return ccps;
        case CHEQUE: return cps;
        case PAYPAL: return ppps;
        default: return null;
    } 
}

Wait, what if CreditCardPaymentStrategy is a request scoped component? Then the resolver method has the effect of promoting the current request scoped instance into application scope. This is almost certainly a bug. We can fix the bug using the special @New binding annotation described above:

@Resolves @Preferred @ApplicationScoped
public PaymentStrategy getPaymentStrategy(@New CreditCardPaymentStrategy ccps,
                                          @New ChequePaymentStrategy cps,
                                          @New PayPalPaymentStrategy ppps) {
    switch (paymentStrategy) {
        case CREDIT_CARD: return ccps;
        case CHEQUE: return cps;
        case PAYPAL: return ppps;
        default: return null;
    } 
}

Then a new /dependent/ instance of CreditCardPaymentStrategy will be created, passed to the resolver method, returned by the resolver and finally bound to the application context.

Web Beans Sneak Peek Part III: Declaring components using XML

Posted by    |       |    Tagged as CDI Java EE

/This is the third installment of a series of articles describing the current status of the Web Beans specification. You can find the first installment here and the second installment here./

So far, we've seen plenty of examples of components declared using annotations. However, there are a couple of occasions when we can't use annotations to define the component:

  • when the implementation class comes from some pre-existing library
  • when there should be multiple components with the same implementation class

In either of these cases, Web Beans gives us two options:

  • write a /resolver method/
  • declare the component using XML

In a future installment we'll talk more about all the crazy kinds of things we can do with resolver methods. First, let's just prove that Web Beans is not entirely annotation-centric.

We can declare a component in web-beans.xml:

<component>
    <class>java.util.Date</class>
</component>

Then an instance of Date could be injected by another component:

@In Date date;

By default, any component declared in XML has the component type @Component. We can use a custom component type:

<component>
    <class>java.util.Date</class>
    <type>org.jboss.test.Mock</type>
</component>

We can override the default component name:

<component>
    <class>java.util.Date</class>
    <name>now</name>
</component>

Or we can specify a scope for the component:

<component>
    <class>java.util.Date</class>
    <scope>javax.webbeans.SessionScoped</scope>
</component>

We can even specify binding annotations using XML, to distinguish between multiple components with the same implementation class:

<component>
    <class>java.util.Date</class>
    <name>now</name>
    <binding>org.jboss.eg.Now</binding>
</component>

<component>
    <class>java.util.Date</class>
    <name>logInTime</name>
    <scope>javax.webbeans.SessionScoped</scope>
    <binding>org.jboss.eg.LogInTime</binding>
</component>

<component>
    <class>java.util.Date</class>
    <name>startupTime</name>
    <scope>javax.webbeans.ApplicationScoped</scope>
    <binding>org.jboss.eg.StartupTime</binding>
</component>

Where @Now, @LogIn and @Startup are binding annotations used at the injection points:

@In @Now Date currentTime;
@In @LogInTime Date loginTime
@In @StartupTime Date startupTime

As usual, a component may support multiple binding annotations:

<component>
    <class>org.jboss.eg.AsynchronousChequePaymentProcessor</class>
    <binding>org.jboss.eg.PayByCheque</binding>
    <binding>org.jboss.eg.Asynchronous</binding>
</component>

Eventually, Web Beans will also support XML-based configuration of component properties, using literal or EL values, something like this:

<component>
    <class>org.jboss.framework.Captcha</class>
    <property name="strategy">math2digit</property>
    <property name="language">#{user.language}</property>
</component>

However, we've not yet worked out all the details of this. In particular, I would love to support a namespaced approach to component configuration, as seen in Seam or Spring 2.0.

Web Beans Sneak Peek Part I: Introducing Web Beans

Posted by    |       |    Tagged as CDI Java EE

We're now really close to releasing a Community Review Draft for Web Beans. The purpose of the draft is to gather feedback on the component model, dependency management model and extensible context model that we've defined, and hopefully get people excited about Web Beans. We also need to get our work in front of the other EE6-related expert groups, so that they can start thinking about how they can possibly re-use and integrate with some of the mechanisms we have defined. However, the specification is by nature written in highly technical language, so this blog entry is the first in a serious of articles giving a friendly, introductory guide to Web Beans. When the Community Review Draft is released, please take the time to download and review it. But please read this series /first/.

A little history

First, some background. Web Beans was initiated by JBoss to help fill a gap in Java EE 5. The EE 5 platform has strong support for access to transactional resources via mature technologies including EJB3, JTA, JCA and JPA. Of course, the platform also features various widely-used web presentation technologies such as Java Servlets, JSP and JSF. However, the /web tier/ and /transactional tier/ have evolved independently and have missed the opportunity to develop a shared component model for web applications which provide access to transactional enterprise resources. Today, Web Beans is being driven by representatives of JBoss, Sun, Oracle and Google, along with several individual members. The component model is deeply influenced by Google Guice and Seam.

A unified component model for Java EE

Web Beans is a component model that is compatible with technologies in both tiers. Web Beans integrates with both JSF and EJB3, allowing an EJB3 session bean to act as a JSF managed bean, thus unifying the two component models. Additionally, Web Beans provides a /conversation model/ and /persistence context management/, thereby solving state management problems and optimistic transaction management problems that affect JSF and JPA. In sum, Web Beans makes it /much/ easier to build Java EE web applications which access the database via JPA.

While Web Beans provides a sweet spot for the integration of JSF and EJB3, the component model is much more generally useful. In particular, it supports use without either JSF or EJB3. An early question that arose was to what extent Web Beans would be limited to the EE and EJB3 environment. The unanimous decision of the group was that:

  1. A Web Bean does not /have/ to be an EJB
  2. Web Beans should be executable outside the EE environment

The first decision merely recognizes the fact that not every component needs the services that EJB provides (transaction demarcation, authorization, etc). However, Web Beans will not duplicate this functionality, so when these services are needed, the Web Bean should be written as a session bean.

The second decision allows components to be integration/unit testable outside the application server environment, and allows reuse of code in, for example, a batch process.

Some members, notably Bob Lee, argue that the work we've done is just as useful outside of the EE platform and that the component model in particular should be considered for use in Java SE. However, as spec lead, and in view of the language of our JSR proposal, I've made the decision to clearly specify the target environment as Java EE, and limit our discussions to what is needed by EE developers.

If, in future, there was pressure from the community and the JCP to open up some parts of Web Beans (for example, the sophisticated Guice-style dependency injection engine), we could at that time follow the precedent established by JPA in the EJB3 expert group and define behavior outside of the EE platform.

Web Bean components

So what, /exactly/, is a Web Bean?

A Web Bean is an application component containing business logic. A Web Bean may be called directly from Java code, or it may be invoked via Unified EL. A Web Bean may access transactional resources. Dependencies between Web Beans are managed automatically by the Web Beans container. Most Web Beans are /stateful/ and /contextual/. The lifecycle of a Web Bean is always managed by the container.

Let's back up a second. What does it mean to be contextual? Since Web Beans may be stateful, it matters /which/ bean instance I have. Unlike a stateless component model (for example, stateless session beans) or a singleton component model (such as servlets), different clients of a component see the component in different states. The client-visible state depends upon which instance of the component the client has a reference to.

However, like a stateless or singleton model, and like JSF, but /unlike/ stateful session beans, the client does not control the lifecycle of the instance by explicitly creating and destroying it. Instead, a /context/ defines:

  • the lifecycle of an instance
  • the scope of visibility of this instance to clients

So clients (for example, other Web Beans) executing in the same /scope/ will see the same instance. But clients in a different scope will see a different instance.

One great advantage of the contextual model is that it allows stateful components to be treated like services! The client need not concern itself with managing the lifecycle of the component it is using, /nor does it even need to know what that lifecyle is./ Components interact by passing messages, and the component implementations define the lifecycle of their own state. The components are loosely coupled because:

  • they interact via well-defined public APIs
  • their lifecycles are completely decoupled

We can replace one component with a different component that implements the same API and has a different lifecycle (a different scope) without affecting the other component implementation. In fact, Web Beans defines a sophisticated facility for overriding component implementations at deployment time, as we will see in a future installment.

Enough hand-waving. More formally, according to the spec:

A Web Bean component comprises:
  • A component type
  • Either a bean implementation class or a resolver method
  • A set of API types
  • A (possibly empty) set of binding annotation types
  • A scope
  • A component name

Let's see what some of these terms mean, to the component developer.

Component types

All we need to know about /component types/ for now is that a Web Beans developer may define some kind of stereotype as an annotation, for example @Mock, @Staging or @AustralianTaxLaw that allows whole sets of components to be conditionally installed in particular deployments of the system. We'll talk more about this unique and powerful feature in a later installment.

A very simple Web Bean might just use the built-in component type @Component:

@Component
public class Credentials { ... }

The prescence of a component type annotation identifies this class as a Web Bean to the Web Beans container.

API types, binding annotation and dependency injection

Web Beans usually acquire references to other Web Beans via dependency injection. Any injected attribute specifies a contract that must be satisfied by the component to be injected. The contract is:

  • An API
  • A (possibly empty) set of binding annotations

An API is a user-defined class or interface. (If the component is an EJB session bean, the API type is the @Local interface.) A /binding annotation/ is a user-defined annotation that is itself annotated @BindingType.

The container searches for a component which satisfies this contract (implements the API, and supports the binding annotations), and injects that component.

For example, if this was the injection point:

@In @CreditCard PaymentProcessor paymentProcessor;

The following component could be injected:

@CreditCard @Component
public class CreditCardPaymentProcessor 
    implements PaymentProcessor { ... }

Web Beans defines a sophisticated but intuitive /resolution algorithm/ that helps the container decide what to do if there is more than one component that satisfies a particular contract. We'll get into the details in a later installment.

Component scope

The /scope/ defines the lifecycle and visibility of instances of the component. The Web Beans context model is extensible, accommodating arbitrary scopes. However, certain important scopes are built-in to the specification, and provided by the Web Beans container. For example, any web application has access to a /session/ scope:

@SessionScoped @Component
public class ShoppingCart { ... }

We'll talk more about scopes in a later installment.

Component names and Unified EL

All Web Beans may be used by /name/ in Unified EL expressions. It is easy to customize the name of a Web Bean:

@SessionScoped @Component @Named("cart")
public class ShoppingCart { ... }

Then we can easily use the component in a JSF page:

<h:dataTable value="#{cart.lineItems}" var="item">
    ....
</h:dataTable>

Resolver methods and web-beans.xml

Most Web Beans are defined by writing an implementation class and annotating it. However, there are two extra ways to define a Web Bean:

  1. via an XML deployment descriptor named web-beans.xml
  2. by writing a resolver method

We'll cover web-beans.xml in a future installment.

A /resolver method/ is a method that is called by the container to obtain an instance of the component when no instance exists in the current context. For example:

@SessionScoped @Component
public class Login {

    User user;
    ...
    
    public void login() {
        user = ...;
    }
    
    @Resolves @LoggedIn User getCurrentUser() {
        return user;
    }

}

A resolver method is a first-class Web Beans component. Once again, we'll talk more about resolver method in a future installment.

Logging in

Let's illustrate these ideas by fleshing out the previous example. We're going to implement user login/logout. First, we'll define a component to hold the username and password entered during login:

@Component
public class Credentials {
	
    private String username;
    private String password;
    
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    
}

This component is bound to the login prompt in the following JSF form:

<f:form>
    <h:panelGrid columns="2" rendered="#{!login.isLoggedIn}">
        <h:outputLabel for="username">Username:</h:outputLabel>
        <h:inputText id="username" value="#{credentials.username}"/>
        <h:outputLabel for="password">Password:</h:outputLabel>
        <h:inputText id="password" value="#{credentials.password}"/>
    </h:panelGrid>
    <h:commandButton value="Login" action="#{login.login}" rendered="#{!login.isLoggedIn}"/>
    <h:commandButton value="Logout" acion="#{login.logout}" rendered="#{login.isLoggedIn}"/>
</f:form>

The actual work is done by a session scoped component that maintains information about the currently logged-in user and exposes the User entity to other components:

@SessionScoped @Component
public class Login {

    @In Credentials credentials;
    @In @UserDatabase EntityManager userDatabase;

    private User user;
    
    public void login() {
    	
        List<User> results = userDatabase.createQuery(
           "select u from User u where u.username=:username and u.password=:password")
           .setParameter("username", credentials.getUserName())
           .setParameter("password", credentials.getPassword())
           .getResultList();
        
        if ( !results.isEmpty() ) {
           user = results.get(0);
        }
        
    }
    
    public void logout() {
        user = null;
    }
    
    public boolean isLoggedIn() {
       return user!=null;
    }
    
    @Resolves @LoggedIn User getCurrentUser() {
        return user;
    }

}

Of course, @LoggedIn is a binding annotation:

@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD})
@BindingType
public @interface LoggedIn {}

Now, any other component can easily inject the current user:

@Component
public class DocumentEditor {

    @In @Current Document document;
    @In @LoggedIn User currentUser;
    @In @DocumentDatabase EntityManager docDatabase;
    
    public void save() {
        document.setCreatedBy(currentUser);
        docDatabase.persist(document);
    }
    
}

Stay with me, folks!

Hopefully, this gives a flavor of the Web Beans component model. There's lots more to talk about, I hope you'll find the time to follow along with the rest of the series.

I want my free iPhone!

Posted by    |       |    Tagged as Java EE

No, I really didn't get one. I think I deserve it, I'd even buy glasses and send my picture in for the ad. Actually, not interested if it's not a 3G iPhone.

EE6 wishlist part II: JSF

Posted by    |       |    Tagged as Java EE

This is the second installment of a series. Part I is here:

http://blog.hibernate.org/cgi-bin/blosxom.cgi/2007/03/30#ee6part1

I'm a fan of JSF, not because JSF is by any means perfect, but because I like the overall architecture, and judge it's warts and limitations to be more fixable than those of other Web Framworks I've used. Of course, whatever my feelings about other other frameworks, I would be idiotic to ignore JSF. JSF is easily the fastest growing web framework in the Java space. It is already easily the most popular framework after Struts. By virtue of being an open standard, JSF has fostered a fecund ecosystem of extensions and component libraries. But in case you doubt that JSF provides any compelling technical advantages compared to other approaches, here's why I find the model superior:

  • Application components are plain Java objects (JSF managed beans), bound to the user interface and orchestration logic via EL. It is possible to write pure business logic components, with no dependencies to JSF, and use them directly from your JSF pages, without the need for an intermediate presentation layer written in Java.
  • Managed beans are stateful and contextual. While the context model is extremely limited compared to Seam, this problem is fixable, as demonstrated by Seam.
  • The JSF lifecycle, which some people find complex, is perfect for use with an application framework like Seam where business logic is bound directly to the view. In particular, the phased processing of validation, followed by model update, followed by event processing and finally view rendering is exactly what you need if the model objects might be managed entities. Any other lifecycle simply won't work.
  • User interfaces are usually defined using a markup language. Markup languages, being hierarchical, naturally map to the structure of a user interface. (I've never felt very comfortable defining my hierarchical user interface in procedural code, a la Swing, Wicket or GWT.) However, somewhat uniquely, if you do wish to create or manipulate your user interface using procedural code, this is also possible in JSF.
  • Even better, this markup language is not limited to the set of primitives provided by HTML. HTML is, I suppose, a reasonable language for defining hyperlinked textual documents. But it was never designed to be used for designing todays rich internet applications and is clearly inadequate for that task. JSF provides the means to extend HTML with new language elements for defining rich user interfaces. Some people have argued that the use of JSF-specific markup elements breaks the traditional designer/developer role separation. But in HTML, the correct separation of roles is that developers create semantic HTML, and designers create CSS. Furthermore, this argument presupposes that it is impossible for designers to learn what the JSF markup elements do - which in my opinion deeply underestimates the intelligence of a good web designer.
  • The JSF UI component model solves certain problems that affect plain HTML form processing and many other Web Frameworks. Multiple submit buttons on the same form can easily be bound to different server-side actions. Forms with repeating input elements (think of inputs laid out in a grid) are easily mapped back to server-side model objects.

Nevertheless, there are some things which JSF 1.2 doesn't get right, and this has required the development of non-standard extensions to JSF in products like Facelets, Seam, Shale, Ajax4JSF, ICEFaces, Avatar. Certain people have argued that if you need to use non-standardized extensions, you would be better to avoid the standard altogether. There are three problems with this line of reasoning:

  • The primary audience for the JSF standard is not application developers. The primary audience is developers of rich user interface component libraries. Here, JSF is a roaring success! There is an embarrassment of riches in open source (Richfaces, ICEFaces, Trinidad, Woodstock, RCFaces, etc) along with many commercial offerings. JSF provides the standard platform upon which component developers are building.
  • If your choice is between (a) adhering to a standard in 80% of your code while using some open source extension to the standard in the remaining 20% and (b) using a totally non-standard framework for everything, you're not better off with the non-standard. You're 80% worse off.
  • The people who have developed the extensions to the standard are working hard to bring the extensions back into JSF 2.0.

And that's the reason for this wishlist. As JBoss rep on the JSF EG, these are the things I'll be pushing for JSF 2.0.

Asynchronous partial submits and renders

This is a no-brainer and everyone already agrees that it is needed. While JSF 1.2 was being finallized, the Ajax craze happened. JSF is actually a great component model for rich internet applications and projects such as Ajax4JSF, Avatar and ICEFaces have clearly demonstrated this. Unfortunately, coexistence of Ajaxified JSF component libraries is currently a nightmare. This problem can only be conclusively addressed by defining how partial submits and renders work in the spec.

Annotation-based programming model

Like the rest of the Java web tier, JSF is stuck in 2003. Definition of managed beans requires EJB2/Spring-like levels of XML tedium. There are two ways to solve this problem. One option would be to introduce annotations for defining managed bean names, scopes, and dependency injection. The second option would be to simply defer to the component model being defined by the Web Beans group. As the convener of JSR-299, I'm understandably sympathetic to the second option, but I'm not sure how the rest of the JSF EG will react to the suggestion.

Converters, Validators and UI components should also be definable via annotations.

Enhanced lifecycle for non-faces requests

JSF devotes much love and attention to the faces request lifecycle for JSF form submissions. It also talks briefly about something called a non-faces request. The most interesting kind of non-faces request is a HTTP GET request, which - when you think about it - is actually the most common kind of request. Here, the spec is a great disappointment. It's certainly possible to create bookmarkable JSF pages with request parameters, but you lose a level of abstraction, and end up writing servlet-like code.

Seam solves this problem by providing page actions and page parameters, which are similar to the abstractions provided for faces requests. (They also look a lot like the functionality provided by an action-based web framework such as Struts or WebWork.)

JSF 2.0 should define a lifecycle for non-faces requests that includes:

  • validation and model update for request parameters
  • some mechanism for handling validation failures
  • action invocation
  • some facility to redirect the request to a different URL

In other words, non-faces requests are going to need to provide all the things that faces requests currently provide. The only difference being that the submitted values are not coming from JSF input components, but rather from plain HTTP parameters (in a bookmarkable URL, for example).

The interesting question is exactly where should these actions, the mapping of request parameters to model attributes and validation be declared. The solution provided by Seam today is to declare this in an XML document along with the orchestration logic (navigation). But I'm increasingly favorable to the idea of embedding this in the page definition. For example:

<f:view>
   <f:parameter name="customerName" value="#{customerFinder.name}" required="true">
      <f:validateLength max="100"/>
   </f:parameter>
   <f:onRender action="#{customerFinder.findByName}"/>
   ...
</f:view>

Improved orchestration

JSF navigation rules provide the basic functionality you expect if you've ever used something like Struts or WebWork. You can write an action method which returns a String-valued outcome, and define navigation rules in XML that determine the view to be rendered or redirected to. The following improvements are sorely needed:

  • Outcomes shouldn't need to be Strings - anything with a toString() method should work
  • It's much more transparent and elegant if the action method does not need to return an outcome at all - instead, the navigation rule could specify a value expression to be evaluated
  • Navigation rules which perform redirects should be able to specify a list of request parameters to use in the redirect (where the parameter values are defined using value expressions)
  • Navigation rules should be able to specify a HTTP error code as the result
  • It should be possible to write exception handling rules that are triggered when a particula exception type propagates out of a JSF lifecycle phase

The following kind of thing would be possible:

<navigation-rule>
   <from-action>#{customerFinder.findByName}</from-action>
   <navigation-case>
      <if>#{customerFinder.result!=null}</if>
      <to-view-id>/displayCustomer.xhtml</to-view-id>
      <redirect>
         <parameter-name>customerId</parameter-name>
         <parameter-value>#{customerFinder.result.id}</parameter-value>
      </redirect>
   </navigation-case>
</navigation-rule>

(Seam provides all this functionality today by defining it's own XML-based language for navigation rules.)

Error handling

JSF's lack of facilities for exception handling is a major embarrasment, and totally ignorant of current best practices for exception handling in Java. It is impossible to do any centralized handling of exceptions without writing a servlet filter. Even worse, Unified EL has the totally pathalogical behavior of wrapping all exceptions (even runtime exceptions) that occur during invocation of the managed beans in a totally useless ELEvaluationException. Both of these problems should be fixed.

One very exciting and interesting solution to the first problem would be to redesign the JSF Lifecycle object using a chain-of-responsibility pattern. Each lifecycle phase would be an element of the chain and would be responsible for delegating to the next phase. The application would be able to add in new phases at any point in the chain, which would provide for the possibility of centralized exception handling via around-style interception. We could then deprecate the PhaseListener extension point which is useful but limited and inelegant. This approach would make JSF much more extensible.

Standardize Facelets and simplify development of JSF UI components

JSF needs its own templating language. Facelets is the perfect starting point. Support for JSP should be deprecated.

It's lucky that there are so many JSF component libraries out there, since developing controls yourself is a huge pain. The biggest problem is JSP, so introducing a standard JSF-specific template language should improve the situation dramatically and make JSF UI component development much more accessible to regular users. The template language could also make it easy to define components which are composed of other components, just like Facelets does today.

Alternative stateless UI component lifecycle

JSF's UI component tree is stateful, meaning that the tree of components is maintained across faces requests (form submissions). This is a nice feature that lets JSF handle forms with conditionally rendered and repeated inputs, and forms with components that are manipulated programmatically. However, in the simple (and common) case, statefulness is overkill. Most forms don't have conditionally rendered controls or grids of controls. JSF needs an alternative stateless lifecycle to deal with the common case.

One possible option would be to copy Tapestry. Tapestry distinguishes between simple forms (which have no repeated or conditional controls) and complex forms (which do). For simple forms, Tapestry uses a stateless lifecycle. For complex forms, Tapestry serializes some information about the component tree to and from the client, and uses this when reconstructing the component tree during the rewind phase. (The handling of complex forms in Tapestry is very conceptually similar to the stateful model used in JSF.)

Databinding

Databinding is a problem that is currently under-specified and causes many problems for new users. The JSF DataModel class is kind of a sketch of a solution, but it falls far short of what is really needed. I have an inkling of what a better solution might look like, but a lot more work is needed on that before it becomes a concrete proposal.

Model-based validation

JSR-303 is defining a standard facility for model-based validation for the Java platform. This new facility must be integrated with both JPA and JSF. In Seam, Hibernate Validator provides this functionality today, and the integration that Seam provides between JSF and Hibernate Validator is a possible model for JSF 2.0.

Allow use of EL in messages

JSF's use of EL is a really strong point of the whole architecture. However, one minor thing is missing: messages defined in resource bundles and in FacesMessages should support interpolation of embedded value expressions. (Seam already supports this.)

For example, you could have the following text in your JSF page:

#{messages['myapp.welcome']}

And this in messages_en.properties:

myapp.welcome=Welcome, #{user.firstName} #{user.lastName}!

Session invalidation

Amazing as it seems, JSF provides no API for invalidating the HTTPSession.

Security

JSF doesn't provide any special functionality for authentication or authorization. I'm not sure what we should do here (if anything), but we need to at least discuss the problem.

EE6 wishlist part III: Unified EL

Posted by    |       |    Tagged as Java EE

This is the third installment of a series. Parts II is here:

http://blog.hibernate.org/cgi-bin/blosxom.cgi/2007/07/09#ee6part2

The new Unified EL API used by JSF and JSP is a really useful addition to the Java platform. Unfortunately, while a lot of effort was put into designing the Java-level APIs for working with Unified EL, the expression language itself hasn't changed much since the earliest days of JSP. It is now well past time for some new features. A more powerful EL lets us keep presentation logic in our page, and avoids polluting the business model with extra methods.

Here's some suggestions I have, though I'm not at all attached to the suggested syntaxes.

Method parameters

This is one of those what were they thinking?! moments. Unified EL does not support method expressions with parameters. Really.

Suggested syntax:

customer.getOrder(ordernumber).product.name

Switch statement

In JSP or JSF pages it's very useful to be able to handle multiple cases in a single expression.

Suggested syntax:

switch (order.status) { case OPEN: 'Open' case CLOSED: 'Closed' else '' }

Dates and times

Currently, there is no way to compare dates and times in EL. The <, >, <= and >= operators should be extended to support java.util.Date. It may also be worth introducing a syntax for date/time literals.

Collection size operator

Amazingly, there is no simple way to determine the size of a collection in EL!

Suggested syntax:

size customer.orders 

This operator should work for any Collection, Map, String or Iterable. Furthermore, the empty operator should be extended to support Map and Iterable.

Collection constructors

When defining pages, it is useful to be able to iterate over collection literals.

Suggested syntax for creating a java.util.List instance:

{'foo', 'bar', 'baz'}

Suggested syntax for creating a java.util.Map instance:

{'foo'->1, 'bar'->3}

Suggested syntax for creating a java.util.List instance with for a specified range of integers:

{1...100}

Collection iteration

This feature is a kind of poor-man's closure support. It should work for all instances of Iterable.

The following suggested syntax returns the list {2, 3, 4}:

{1, 2, 3} collect { x -> x+1 }

The following returns {2, 3}:

{1, 2, 3} select { x -> x>1 }

The following returns the object 2:

{1, 2, 3} detect { x -> x>1 }

The following returns the object 3:

{1, 2, 3} detect { max, x -> max>=x }

The following returns {3, 2, 1}:

{1, 2, 3} desc

The following sorts the customers by name:

customers asc { c -> customer.name }

An alternative approach might be to copy Python's list comprehensions:

[ x+1 for x in {1, 2, 3} where x>1 ]

which results in {3, 4}.

Conclusion

The point of this is not to turn Unified EL into a programming language. I actually prefer it to be relatively bare-boned compared to OGNL or MVEL. Rather, the point is to remove certainl pain-points where the only current solution is to fall back to writing presentation logic in Java code.

An alternative to improving the Unified EL would be to allow JSF/JSP expressions to be writting in JavaScript, Groovy, or some other scripting language. I'm openminding on that, it would certainly be possible to wrap the JavaScript interpreter behind a Unified EL ExpressionFactory. But I worry that it pushes people in the wrong direction of writing templates that contain procedural code. The last thing I want to see is JSF templates that look like .rhtml files ;-)

EE 6 wishlist part I: EJB Session Beans

Posted by    |       |    Tagged as Java EE

Over the last year or so, we've been thinking hard about what kind of new functionality we want to see in the next rev of the EE platform, and feeding our ideas to Sun to incorporate into the JSR proposals for the next round of EE specifications. These JSRs should become public fairly soon now, but I wanted to give a rundown on the things that are important to me, and why I think they're important. A lot of these items have come out of our experience with Seam, others have been things that have been missing from the platform for a long time. My wishlist is pretty long, so I'm going to spread it over several posts. First up, I'll talk about session beans.

The basic EJB component model - stateful/stateless session beans and message-driven beans - is pretty much spot-on. It's stood the test of time, as a model that covers the overwhelming number of usecases. However, there are occasions when the model is too limiting, and the model is not really complete until we can handle those occasions.

Concurrent session beans

First, it should be possible to write a session bean that supports concurrent access by multiple clients. Of course, this should not be the default concurrency model - as much as possible we would prefer to guide people toward implementing their application so that resources are not shared between concurrent threads and concurrent clients - but there's no escaping that concurrency is occasionally needed.

My suggestion is to allow three concurrency modes for a stateless or stateful session bean.

  • No concurrency, the default, and currently supported behavior: the bean does not support concurrent clients. The container is permitted to throw a ConcurrentAccessException if two requests arrive simultaneously.
  • Bean-managed concurrency: the bean supports concurrent access by multiple threads, and is responsible for managing access to volatile data structures.
  • Container-managed concurrency: the bean supports concurrent clients, and the container is responsible for ensuring that concurrent threads are serialized before entering the bean implementation.

We could pick a concurrency model using an annotation like @ConcurrencyManagement(CONTAINER) or @ConcurrencyManagement(BEAN). For example:

@Stateful   
@ConcurrencyManagement(CONTAINER)
public class Counter {
      private int count;
      public void inc() { count== ; }
      @ReadOnly public int value() { return count; }   
}

In this example, the @ReadOnly annotation indicates that the container should use a read/write locking model.

Alternatively, you could do it the Hard Way:

@Stateful
@ConcurrencyManagement(BEAN)
public class Counter { 
   private int count;
   public synchronized void inc() { count== ; }
   public synchronized int value() { return count; }
}

One major reason why we need concurrent beans is to support the idea of singleton beans which share state between all threads on a single node. Singletons are useful as caches, or for holding application configuration data. (Think of something like servlet context attributes, but for the EJB container.) Actually, introducing singletons could help kill two birds with one stone: the @PostConstruct method of a singleton bean could be used as a container initialization hook, just like startup servlets are used today in the web container. Likewise, the @PreDestroy method could be used to notify the application that the container is being shut down.

Lightweight asynchronicity

The second item on my wishlist is lighweight asynchronicity. Currently, there are two approaches to asynchronous processing in EJB. The first is JMS. JMS is perfectly reasonable for cases where I have well-defined quality of service requirements, such as guaranteed delivery, etc. However, it's overkill for many cases. The second approach is the EJB timer service. I'm actually a great fan of the timer service, though I'm not a fan of the dodgy implementations that exist in most application servers today. But if the timer service is going to become generally useful, it's going to need some major enhancements.

To begin with, you should be allowed to have more than one @Timeout method per bean. (Duh!)

Next, we need to enhance the scheduling capabilities, I've a few ideas for this, from support for business calendars, to support for cron-style patterns, but nothing concrete enough to write down at this point.

Finally, Seam shows how to layer an asynchronous method invocation protocol on top of the timer service. This is a reasonably straightforward addon to EJB3 (that demonstrates the extensibility of the EJB3 model), but I think we should consider defining @Asynchronous methods in the specification.

Stateful web service endpoints

The third item on my wishlist is for stateful web service endpoints. Currently, only stateless session beans may function as web service endpoints. With some integration with WS-Contexts or WS-Addessing (or whatever WS-blahblah is appropriate), we would be able to support a stateful session bean that acts as a web service endpoint. I don't know exactly what this would look like yet, but we are trialing some stuff in Seam/WS that is probably relevant.

Replication callbacks

The fourth item is @PreReplicate and @PostReplicate callback methods. Currently some containers overload the @PrePassivate and @PostActivate callbacks when replicating, while others don't. Passivation has distinctly different semantics to replication, so this is not really appropriate. But some kind of callback is needed.

Optional business interface

The fifth item on my wishlist is a pure ease-of-use concern. Currently, EJB mandates that all session beans have some @Local or @Remote interface. This was not an unreasonable requirement when session beans were understood to exist in a business tier, with a well-defined API sitting between the business logic and the client. But now that we're using session beans everywhere - even for presentation logic - it's clear that defining the local interface for every bean is simply a PITA. Unfortunately, we realised this much too late in the process of writing the spec to do anything about it in EJB 3.0 (I've kicked myself many times over this, I should have known better). Especially in an environment like Seam, where the only client of a bean might be a JSF page with EL expressions, the interface looks totally redundant!

The interface should be optional, and when it is missing, the public methods of the bean class should be taken as the business methods of the session bean.

Simplified JMS/JavaMail sending

The sixth item, which we would also have done in 3.0, were it not for time constraints, is to simplify JMS message and JavaMail sending. Currently, it is possible to inject a Topic or Queue using @Resource, but of course what I'm really interested in is QueueSender or TopicPublisher. This is easy to fix - indeed, we already fixed it in Seam.

Logging

Another (minor) ease-of-use concern is logging. I can't express how awful this is in Java 5:

static Log log = LogFactory.getLog(MySelf.class);

Of course, it should be:

@Logger Log log;

(Just like it is in Seam.)

EJB meta-annotations

My most favoritest wish is to support the use of EJB annotations as meta-annotations. Often, you'll find several EJB beans that share the same pattern of annotations. For example, you might have several Seam components with the following annotations:

@Stateful
@TransactionAttribute(MANDATORY)
@Scope(CONVERSATION)
@RolesAllowed(USER)
@ConcurrencyManagement(CONTAINER)
@Name("createOrder")
public class CreateOrderBean implements CreateOrder { .... }

You could reduce code duplication and raise the semantic level of your code by introducing an @AjaxConversation annotation:

@Stateful
@TransactionAttribute(MANDATORY)
@Scope(CONVERSATION)
@RolesAllowed(USER)
@ConcurrencyManagement(CONTAINER)
public @interface AjaxConversation { .... }

And the bean class would look like this:

@AjaxConversation
@Name("createOrder")
public class CreateOrderBean implements CreateOrder { .... }

With some co-ordination betweem the EJB and Web Beans groups, I hope that this can become a reality.

In the next installment, I'll talk about enhancements we could make at the platform level (packaging, security, dependency injection, etc).

Never been that close to Java Persistence compliance

Posted by    |       |    Tagged as Java EE

EJB3 XML mapping files

The latest release of Hibernate EntityManager (3.1.0 beta8) now support EJB3 XML mapping files (aka deployment descriptors). While annotations are considered a huge step forward for development ease-of-use and productivity, some folks out there stayed concerned about the ability to split metadata from the code. This is now supported in Hibernate Annotations (3.1.0 beta 10) and Hibernate EntityManager in a standard manner. You can partially overrides java annotations or you can write all you metadata through XML. The easiest solution is to add META-INF/orm.xml in your ejb-jar or persistence jar. This file is automatically taken into account by the persistence provider. Alternatively you can add a <mapping-file/> element to your persistence.xml file. Here is a sample for EJB3 XML file

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="[=>http://java.sun.com/xml/ns/persistence/orm]"
               [=>xmlns:xsi=]"=>http://www.w3.org/2001/XMLSchema-instance"
               [=>xsi:schemaLocation=]"=>http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
               version="1.0">
  <package>org.hibernate.test</package>
  <entity class="Car" metadata-complete="true" access="PROPERTY">
      <table name="CARS"/>
      <named-query name="carsByManufacturer">
          <query>select c from Car c where c.manufacturer = :manufacturer</query>
          <hint name="org.hibernate.timeout" value="200"/>
      </named-query>
      <attributes>
          <id name="id">
              <generated-value strategy="AUTO"/>
              <column name="car_id"/>
          </id>
          <basic name="category" optional="false">
              <enumerated>STRING</enumerated>
          </basic>
          <many-to-one name="manufacturer">
              <join-column name="manufacturer_fk"/>
          </one-to-many>
      </attributes>
  </entity>
</entity-mappings>

Glassfish integration

I have been working with the Glassfish team for some times now to make sure Hibernate EntityManager integrates well with Glassfish. Now that the specification has been frozen, the integration is working very smoothly:

  • download Hibernate Core (for HEM 3.1.0 beta 8, you will need Hibernate 3.2 CR1)
  • copy the required hibernate (and third party libs) into $glassfish_home/lib
  • adjust your persistence.xml file to use Hibernate EntityManager
<persistence version="1.0">
    <persistence-unit name="pu">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!-- JNDI name of the database resource to use -->
        <jta-data-source>jdbc/sqlserver</jta-data-source>
        <properties>
            <!-- drop and create tables at deployment if needed -->
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

That's it! Glassfish sets the appropriate Transaction Manager Strategy and Hibernate can guess the appropriate Dialect for most common databases.

Hibernate EntityManager is know to run in all up-to-date EJB3 implementations. Of course, it runs smoothly in JBoss EJB3 and JBoss Embeddable EJB3 .

Mapping of Maps

This has been a long time requested feature, it is now available, you can map you associations using Map<Element, ...> or Map<Embeddable, ...> using an explicit key column(s)

A story about FreeMarker and Velocity

Posted by    |       |    Tagged as Java EE

I have been fed up with Velocity ís ability to ignore and even hide errors and exceptions occurring in the templates used in Hibernate Tools .

This blog tells about why and how FreeMarker became my new interest. If you just want to see the results then go and fetch the code in the TOOLS_FREEMARKER branch...read on to get the full story.

The problems with Velocity

I started to see more and more forum postings and bug reports about issues that were caused by typoís in users templates or even worse errors in the Hibernate Tools. Many of these issues would be solvable within seconds if Velocity would actually tell where in the templates the error occurred and unit tests would have failed if underlying exceptions were exposed; but Velocity simply does not.

I have added every safety-precaution I have been able to apply to Velocity error handling. I have created my own UberSpect and EventHandler implementation that will not allow you to invoke methods that does not exist and I have tweaked the logging settings to be more informative; but it does not (hardly) solve all the problems that can occur.

Logging is excessive in Velocity even at WARN and INFO level, one good reason for this is most likely that the developers know that Velocity is ignoring situations where it should actually fail, thus since there is no easy other way implemented in Velocity they put it in the log for users to discover by accident!

The choice originally fell on Velocity since it was the biggest player around, and I added it naively thinking that the error and log handling could not be that bad if so many people were using it and if there were an issue it would be fixed soon.

As time went by I learned that it was definitely not the case.

The beauty of FreeMarker

Last week I decided to look around for alternatives, the only real alternative I found were FreeMarker; everything else looked either too simple or way to complex for the Hibernate Tools needs. Now that I have spent just 1,5 day converting the existing Velocity templates to FreeMarker Iím more than happy I did.

Here are some examples of the beauty of FreeMarker:

Assume we have the following bean:

public class Table {
 String getName();
}

The bean is available via table in the following code:

${table.namee}

That typo will just be ignored by default in Velocity, with a custom EventHandler it can be convinced to throw an exception which comes out like this:

Caused by: java.lang.IllegalArgumentException: $table.namee is not a valid reference.
at org.hibernate.tool.hbm2x.HibernateEventHandler.referenceInsert([=>HibernateEventHandler.java:11])
        at org.apache.velocity.app.event.EventCartridge.referenceInsert([=>EventCartridge.java:131])
        ... 19 more

No information about which template nor where in the temmplate it went wrong.

In FreeMarker I get the following with no special configuration and custom code:

Expression table.namee is undefined on line 15, column 14 in doc/tables/table.ftl.
The problematic instruction:
----------
==> ${table.namee} [on line 15, column 12 in doc/tables/table.ftl]
----------

Java backtrace for programmers:
----------
freemarker.core.InvalidReferenceException: 
 Expression table.namee is undefined on line 15, column 14 in doc/tables/table.ftl.
    at freemarker.core.TemplateObject.assertNonNull([=>TemplateObject.java:124])
    at freemarker.core.Expression.getStringValue([=>Expression.java:118])
    at freemarker.core.Expression.getStringValue([=>Expression.java:93])
    ...

Nice! And even better, the on line 15, ... works like a link in e.g. Eclipse Console view. Clicking it brings you to the location of the error in the table.ftl. file.

Similar and precise error messages you get if you refer to non existing methods, Just brilliant! The great thing is that if I really wanted FreeMarker to ignore this I could do so by installing a different Exception handler. But that is my choice, not a hard to change behavior.

The built in primitives in FreeMarker is also great, e.g. <#assign> that allows me to store any generated output in a variable for later usage.

${pojo.getPackageDeclaration()}
// Generated ${date} by Hibernate Tools ${version}
<#assign classbody>
 <#include "PojoTypeDeclaration.ftl"/> {
  ..more template code..
 }
</#assign>

${pojo.generateImports()}
${classbody}

This allows me to remove the need to have a magically second-pass which I did with Velocity. There are more gems like these to be found in the excellent FreeMarker documentation .

Another big plus in FreeMarker's favor is the Configuration API . Let us compare, here is our Velocity setup:

engine = new VelocityEngine();
context = new VelocityContext();

EventCartridge ec = new EventCartridge();
ec.addEventHandler(new HibernateEventHandler()); // stricter evaluation
ec.attachToContext( context );
            
Properties p = new Properties();
p.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, 
              "org.apache.velocity.tools.generic.log.CommonsLogLogSystem");
p.setProperty(CommonsLogLogSystem.LOGSYSTEM_COMMONS_LOG_NAME, 
              "org.hibernate.tool.hbm2x.template");

p.setProperty( RuntimeConstants.UBERSPECT_CLASSNAME, HibernateUberspect.class.getName() ); // stricter evaluation

p.setProperty("velocimacro.library",""); // make it shut up about VM_global_library blah
      
p.setProperty("resource.loader", "file, class");
p.setProperty("file.resource.loader.path", directory );
p.setProperty("class.resource.loader.class", ClasspathResourceLoader.class.getName() );

engine.init(p);

Here is the corresponding FreeMarker config:

engine = new Configuration();
context = new SimpleHash(ObjectWrapper.BEANS_WRAPPER);

//Logger.setCategoryPrefix("org.hibernate.tool.hbm2x.template"); 
// Not really needed since the logging is much more sensible.

freeMarkerEngine.setTemplateLoader(new MultiTemplateLoader( 
                                    new FileTemplateLoader(directory), 
                                    new ClassTemplateLoader(this.getClass(),"/"));

Notice the difference? FreeMarker has good practice defaults and actually allows me to use java code to configure it; what a neat concept.

The only two bad things I have found yet with FreeMarker is that itís syntax is based on <#..> which does not compute very well when trying to show it in an XML editor. This has been fixed in the latest release by also allowing [#...] syntax.

Another bigger issue is that ${} and #{} is not escapable. This syntax collides in templates that generates ant build and jsp files.

In Velocity they were just ignored (the only place were it were useful to ignore them). FreeMarker complains because the values are undefined and unfortunately there is no easy-on-the-eyes method to escape these characters. The following show the methods that I found to allow the me to output ${..}:

${r"${build.dir}"}  
${'$í}{build.dir} 
<#noescape>${build.dir}</noescape>

Still the brilliant exception handling, powerful template language and configuration API makes FreeMarker a much better choice for Hibernate Tools.

What now ?

Velocity served me well and is probably serving many projects well; it just did not cut it well for Hibernate Tools. Today I am convinced that I could have saved myself and the Hibernate world from a lot of trouble if I had decided to use FreeMarker from the beginning.

Come and see for your self in the TOOLS_FREEMARKER branch. The code in there will be merged into the main development in the near future unless someone steps up with a very good reason for not doing so ;)

To be fair, I must tell you that Velocity 1.5 is being worked on right now, and it does seem to solve some of these issues, but not completely and Velocity has some external dependencies I would rather not add to the tools project.

back to top