Thursday, January 19, 2012

CDI based @Asynchronous alternative

Arguably one of the most convenient things in EJB after declarative transactions is the @Asynchronous annotation. Applying this annotation to a method will cause it to be executed asynchronously when called (the caller does not have to wait for the method to finish executing).

The downside of this annotation is that it's only applicable to EJB beans. While EJB beans these days are lightweight and nothing to avoid in general, the fact is that in Java EE 6 and especially Java EE 7 other managed beans, specifically CDI ones, play an increasingly important role. These beans unfortunately can not directly take advantage of the platform provided @Asynchronous.

Building such support ourselves in Java EE 7 however is not that difficult. Thanks to the Java 8, and the Interceptors and Concurrency specs it's actually quite simple, but with a small caveat (see below):

We'll start with defining the annotation itself:

@InterceptorBinding
@Target({METHOD})
@Retention(RUNTIME)
@Inherited
public @interface Asynchronous {}

Next we need a helper class that effectively unwraps the dummy Future instance (of type AsyncResult, as provided by the EJB spec) that an asynchronous method returns. Such a wrapper class is needed in Java, since you otherwise can't call a method that returns say String and assign it to Future<String>. This is not specific to this CDI implementation, but is exactly how EJB's @Asynchronous works.

public class FutureDelegator implements Future<Object> {
    
    private final Future<?> future;
    
    public FutureDelegator(Future<?> future) {
        this.future = future;
    }

    @Override
    public Object get() throws InterruptedException, ExecutionException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get();
        if (asyncResult == null) {
            return null;
        }
        
        return asyncResult.get(); 
    }
    
    @Override
    public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        AsyncResult<?> asyncResult = (AsyncResult<?>) future.get(timeout, unit);
        if (asyncResult == null) {
            return null;
        }
        
        return asyncResult.get(); 
    }
    
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return future.cancel(mayInterruptIfRunning);
    }
    
    @Override
    public boolean isCancelled() {
        return future.isCancelled();
    }
    @Override
    public boolean isDone() {
        return future.isDone();
    }
}

With those 2 classes in place the actual interceptor can be coded as follows:

@Interceptor
@Asynchronous
@Priority(PLATFORM_BEFORE)
public class AsynchronousInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;

    @Resource
    private ManagedExecutorService managedExecutorService;

    @AroundInvoke
    public Object submitAsync(InvocationContext ctx) throws Exception {
        return new FutureDelegator(managedExecutorService.submit( ()-> { return ctx.proceed(); } ));
    }
}

There are a few things to take into account here. The first is the priority of the interceptor. I put it on PLATFORM_BEFORE, which is the absolute lowest level, meaning the interceptor will likely hit before any other interceptor. If this interceptor would ship with a library it's more correct to use the lowest range reserved for libraries: LIBRARY_BEFORE.

For the actual parallel execution, the call to ctx.proceed() is scheduled on a thread pool using the Java EE Concurrency provided executor service. While this service was only recently introduced in Java EE 7, it in fact originated from a very old spec draft that was dragged into modern times. Unfortunately that spec felt it needed to use the somewhat archaic @Resource annotation for injection instead of the more modern @Inject. So that's why we use that former one here and not the latter.

A caveat is that the interceptor as given does not work on the current released versions of Weld, but in fact does work on the not yet released SNAPSHOT version. The issue is explained by Jozef on the CDI-dev mailing list.

As a temporary workaround a thread local guard can be used on Weld as follows:

@Interceptor
@Asynchronous
@Priority(PLATFORM_BEFORE)
public class AsynchronousInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Resource
    private ManagedExecutorService managedExecutorService;
    
    private static final ThreadLocal<Boolean> asyncInvocation = new ThreadLocal<Boolean>();

    @AroundInvoke
    public synchronized Object submitAsync(InvocationContext ctx) throws Exception {
        
        if (TRUE.equals(asyncInvocation.get())) {
            return ctx.proceed();
        }
        
        return new FutureDelegator(managedExecutorService.submit( ()-> { 
            try {
                asyncInvocation.set(TRUE);
                return ctx.proceed();
            } finally {
                 asyncInvocation.remove();
            }
        }));
  
    }
}

Future work

The interceptor shown here is just a bare bones copy of the EJB version, but lacks the setup of a request scope. Going further however we can add additional features, like using a completable future, optionally named thread pools, etc.

Arjan Tijms

Monday, January 16, 2012

Easily disable sorting in PrimeFaces 3's DataTable

PrimeFaces provides a convenient and easy to use sorting facility for its DataTable. Together with Facelets, this facility allows us to create re-usable columns that are natural sortable by default. E.g.:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.org/ui"
>
    <p:column headerText="#{headerText}" sortBy="#{value}">
        <h:outputText id="#{id}" value="#{value}" />
    </p:column>    
</ui:composition>

Such a column can be used on a page inside a DataTable as follows:

<my:sortableColumn id="foo" value="#{someBean.someValue}" />

The problem

The above is only a simple example, and real-life usage can be more complex with e.g. default styles and cell editing capabilities added. With such complex tags, it might be desirable to turn off sorting for certain columns programmatically. By default this does not seem to be possible in PrimeFaces. Setting the value attribute in the above example to null or the empty string via an expression prevents sorting, but still renders the sorting icon.

The reason for this is that the PrimeFaces renderer (org.primefaces.component.datatable.DataTableRenderer) checks for the presence of a value expression to determine whether the icon should be rendered, regardless of whether this expression evaluates to something non-empty. So nothing you pass into the value attribute of the above showed tag can make the value expression itself null, nor can any extra attribute accomplish this in the tag's definition.

Custom helper tag

One solution is to build a simple helper tag that takes a parameter and based on that sets the value expression of its parent component to null. This tag can be nested inside a column. Taking it one step further, we can nest the tag inside a table and programmatically disable sorting on all columns. The following shows the implementation of such a tag:

public class ColumnSorterDisabler extends TagHandler {
    
    public ColumnSorterDisabler(TagConfig config) {
        super(config);
    }

    @Override
    public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
        Boolean disableSorting = getRequiredAttribute("disableSorting").getBoolean(ctx);
        if (disableSorting) {
            if (parent instanceof Column) {
                parent.setValueExpression("sortBy", null);
            } else if (parent instanceof DataTable) {
                for (UIComponent child : parent.getChildren()) {
                    if (child instanceof Column) {
                        child.setValueExpression("sortBy", null);
                    }
                }
            }
        }        
    }    
}

After declaring this in a *-taglib.xml, we can use it as follows inside a Facelets tag:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.org/ui"
>
    <my:columnSorterDisabler disableSorting="#{disableSorting}" />

    <p:column headerText="#{headerText}" sortBy="#{value}">
        <h:outputText id="#{id}" value="#{value}" />
    </p:column>    
</ui:composition>

We can now disable sorting on a per-column basis as follows:

<my:sortableColumn id="foo" value="#{someBean.someValue}" disableSorting="true" />

or for an entire table:

<p:dataTable value="#{someBean.someValues}" var="something">
    <my:sortableColumn id="foo" value="#{something.foo}" />
    <my:sortableColumn id="bar" value="#{something.bar}" />
    <my:columnSorterDisabler disableSorting="true" />
</p:dataTable>

One caveat to remember, TagHandlers exist only at 'build-time', so when using expressions to do the disabling the data these point to has to be available during build-time.

The f:attributes tag

Another solution, contributed by my co-worker Bauke Scholtz, is taking advantage of the <f:attribute> tag. This tag does the same thing as an actual tag attribute, but contrary to an actual attribute this one can be conditionally excluded using <c:if>. In that case the implementation of our re-usable column becomes this:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:p="http://primefaces.org/ui"
>
    <p:column headerText="#{headerText}">
        <c:if test="#{empty sortable or sortable}">
            <f:attribute name="sortBy" value="#{value}"/>
        </c:if>
        <h:outputText id="#{id}" value="#{value}" />
    </p:column>    
</ui:composition>

Notice how the tag attribute sortBy has been replaced by a child tag. This approach is really convenient since it simply uses JSF's build-in functionality. To disable sorting for all columns at once, the helper tag based approach is still useful though. Note that just like the helper tag, a <f:attribute> tag only exists at build-time, so here too only data that's available during that time can be used.

Arjan Tijms

Friday, January 6, 2012

Passing action methods into Facelets tags

The problem

JSF, via Facelets, has various mechanisms to easily reuse view content. One of those is the Facelets tag, which allows one to reuse markup and/or components.

One notorious problem with these Facelets tags is that you can't directly pass action methods (method expressions) into them. There's a workaround where you break the expression into two parts, the base (which should be a value expression) and the name of the method as a plain string. Inside the tag these two are then combined again, e.g. via the array notation syntax. See e.g.

Another approach is to create a small helper tag that converts the value expression in some way into a method expression. There have been a couple of implementations of this idea:

Finding a solution

In this blog I would like to present another variant on the tag handler idea, which doesn't require nesting the content and also doesn't parse any embedded EL expression manually. It supports EL parameters provided by the calling view. It's not perfect however, since it does not support parameters being passed into the method from the target component (e.g. an ActionEvent for an actionListener).

The idea is to wrap the value expression (which represents the original method expression passed into the Facelets tag) inside a custom method expression. This method expression simply gets the value from the embedded value expression, which as "side-effect" executes this method.

The resulting method expression has to be stored somewhere. The request scope would be an option, but then it would be directly available outside the Facelets tag, which isn't a good example of encapsulation.

An alternative is the javax.el.VariableMapper, a "magic" little thing that is able to scope value expressions to the duration of a Facelets tag (it's magical since remember that the tag doesn't exist any more after the component tree has been build). This however requires a value expresion again, so in an odd twist we wrap the method expression that we just created in a value expression again.

So, how can this work? Wasn't the entire point of this exercise to go to a method expression? Well, as it turns out a value expression can be accepted wherever a method expression is required, iff this value expression directly returns a method expression.

E.g. the Apache EL implementation's org.apache.el.parser.AstIdentifier contains the following code fragment that accomplishes this:

// case A: ValueExpression exists, getValue which must
// be a MethodExpression
VariableMapper varMapper = ctx.getVariableMapper();
ValueExpression ve = null;
if (varMapper != null) {
    ve = varMapper.resolveVariable(this.image);
    if (ve != null) {
        obj = ve.getValue(ctx);
    }
}
// (case B omitted)
if (obj instanceof MethodExpression) {
    return (MethodExpression) obj;
} 

Code

Without further ado, here's the code for the TagHandler that implements all the wrapping:

public class MethodParamHandler extends TagHandler {

    private final TagAttribute name;
    private final TagAttribute value;
    
    public MethodParamHandler(TagConfig config) {
        super(config);
        this.name = this.getRequiredAttribute("name");
        this.value = this.getRequiredAttribute("value");
    }
    
    public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
        String nameStr = name.getValue(ctx);
        
        // The original value expression we get inside the Facelets tag, that's actually the method expression passed-in by the user.
        ValueExpression valueExpression = value.getValueExpression(ctx, Object.class);
        
        // A method expression that wraps the value expression and uses its own invoke method to get the value from the wrapped expression.
        MethodExpression methodExpression = new MethodExpressionValueExpressionAdapter(valueExpression);
        
        // Using the variable mapper so the expression is scoped to the body of the Facelets tag. Since the variable mapper only accepts
        // value expressions, we once again wrap it by a value expression that directly returns the method expression.
        ctx.getVariableMapper().setVariable(nameStr, ctx.getExpressionFactory().createValueExpression(methodExpression, MethodExpression.class));    
    }

}

The rather trivial adapter that wraps the value expression is shown below. The main method of interest here is invoke(). Note how unfortunately the params parameter has to be ignored.

public class MethodExpressionValueExpressionAdapter extends MethodExpression {

    private static final long serialVersionUID = 1L;
    
    private final ValueExpression valueExpression;

    public MethodExpressionValueExpressionAdapter(ValueExpression valueExpression) {
        this.valueExpression = valueExpression;
    }
    
    @Override
    public Object invoke(ELContext context, Object[] params) {
        return valueExpression.getValue(context);
    }
    
    @Override
    public MethodInfo getMethodInfo(ELContext context) {                
        return new MethodInfo(null, valueExpression.getExpectedType(), null);
    }

    @Override
    public boolean isLiteralText() {
        return false;
    }
    
    @Override
    public int hashCode() {
        return valueExpression.hashCode();
    }
    
    @Override
    public String getExpressionString() {
        return valueExpression.getExpressionString();
    }
    
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        
        if (obj instanceof MethodExpressionValueExpressionAdapter) {
            return ((MethodExpressionValueExpressionAdapter)obj).getValueExpression().equals(valueExpression);
        }
        
        return false;
    }
    
    public ValueExpression getValueExpression() {
        return valueExpression;
    }
}

The tag handler has to be registered in a *-taglib.xml file, e.g.:

<tag>
    <tag-name>methodParam</tag-name>
    <handler-class>com.example.MethodParamHandler</handler-class>
    <attribute>
        <name>name</name>
        <required>true</required>
        <type>java.lang.String</type>
    </attribute>
    <attribute>
        <name>value</name>
        <required>true</required>
        <type>java.lang.String</type>
    </attribute>
</tag>

Using the tag handler

So the above takes care of implementing the converting tag handler. Let's take a look at how we would use this.

Suppose we have a Facelets tag in the following using-view fragment, where the action attribute binds to a method in a backing bean taking an EL parameter:

<p:dataTable id="table" value="#{someBean.someValues}" var="someValue">
    <my:deleteActionColumn action="#{someBean.delete(someValue)}" update="table" />
</p:dataTable>

The tag could then be defined as shown below. The interesting bit is the <my:methodParam> tag, which converts the value expression "action" to the method expression "actionMethod". The tag can be placed at many locations, but reasonable choices would be as the first child of the root or directly above the component using it. I choose the latter here.

<ui:composition
    xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:my="http://example.com/my"
>
    <p:column styleClass="some_style">
    
        <my:methodParam name="actionMethod" value="#{action}"/>
    
        <p:commandLink id="someId" action="#{actionMethod}" process="@this" update="#{update}">
            <h:graphicImage value="/icons/delete.png" alt="#{i18n['something.delete']}" title="#{i18n['something.delete.tooltip']}" width="15" height="15" />
        </p:commandLink>
    </p:column>
    
</ui:composition>

This Facelets tag too again has to be explicitly declared in a *-taglib.xml, e.g.:

<tag>
    <tag-name>deleteActionColumn</tag-name>
    <source>faces/tags/deleteActionColumn.xhtml</source>
    <attribute>   
        <name>action</name>        
        <type>javax.el.MethodExpression</type>
    </attribute>
</tag>

Any other alternatives?

At first sight the composite component mechanism would seem to be an alternative, as it explicitly supports passing in method references. However, the composite component isn't a true substitute for Facelets tags. Namely, it inserts a parent component in the tree instead of simply its content. This doesn't work for tables, panel groups, and all other kinds of components that require children of a specific type or in a specific order to be present.

You can sometimes do some magic with composite components by using the componentType attribute (see e.g. JSF composite component binding to custom UIComponent), but this only gets you so far and sometimes you really simply need the raw body of a tag to be inserted into the using page.

Another alternative solution, arguably the one and only Real Solution™, is having this fixed by Facelets. Indeed, many years ago there was an issue created for this at the Facelets JIRA: http://java.net/jira/browse/FACELETS-263 with a similar issue even having a patch submitted for it: http://java.net/jira/browse/FACELETS-273. Unfortunately, neither of those issues ever got resolved.

Hopefully the alternative solution provided here is useful for those situations where the existing workarounds are not completely satisfactory. Do note again that the solution presented here is also not ideal, but seems to work nicely in a rather straightforward way for action methods that don't use framework provided parameters, but can optionally take user supplied EL parameters.

An implementation of this is readily available in the new OmniFaces library, from where you can find the documentation and the full source code. There's also a live demo available.

Arjan Tijms