JBoss AS 5.0 - Changes To Come

November 30th, 2008 Radim Marek

Together with other bloggers I’ve asked earlier this year the question about the release plan for the long awaited JBoss AS 5.0. Five months later, I’m happy to say, everything suggests the big moment is approaching fast.

Let’s review what we’ve got so far. Available for download is the second candidate release. Next in line, and probably most important is the information coming from the Application Server project lead, Dimitris Andreadis, who confirmed the release date to be December 2008. Another piece of the puzzle is the fact this week the JBoss Microcontainer, core component backing new version’s architecture, reached general availability release 2.0.0. With the rest of the projects being now quite stable, it’s easy to see ‘it’s happening’. Hurray! Or not? Let’s take another look.

I guess the impression from all the projects I’m using is that release candidate is almost final product. Unfortunately during testing of both first and second release candidate of JBoss AS, and now working with regularly updated trunk, the impression is quite different. Broken deployments with even quite regular WAR files, introduction of minor but important changes, and general integration problems don’t give me much of assurance. Having closely watched the process behind introduction of Glassfish v3 Prelude, I have to say I won’t be so wrong to say these two processes were significantly different. Purely subjective test, but one that will form first impression of many users, is to migrate the existing projects. Whereas even the migration to Glassfish (v2 and v3) was relatively straightforward, and I was able to use v3 Prelude without almost any changes long before it reached GA, the same task for JBoss AS 5.0 is pretty tedious. Not saying impossible, but even as a experienced JBoss user, I can’t help myself from feeling a bit frustrated.

Before making any judgement, there’s an important twist. Business - the always first and foremost root of all twists. The release of JBoss AS 5.0 is a matter of the community product only. Hand in hand with restructured and updated jboss.org, it’s important to notice it won’t be supported. Therefore it will take another 6 to 8 months (my rough estimate) to release EAP 5. In that time we might even see JBoss AS 5.1. With this in mind I’m not sure how significant is the December release for all of us - the developers making their living out of it. Do you really want to stay with the bleeding edge technology and experience all teething problems? You have to answer this.

Does this situation make me feel sad? Yes, it does. As I said before, this version is expected for such a long time, the new release will be significant and change the way how new applications are developed. But it has already left a slight bitter taste in my mouth. This year I’ve heard bits and pieces from different sources on the theory how such a open source project should be made commercially more viable, especially by loosening control over the community side of things. So I guess that is it. Six month ago I was asking question why should I use EAP if I ever start-up my own company, and today I’ve got answer.

Ignoring the the ground-breaking technological changes in version 5.0, I’m pretty confident this release will bring change in the way how open source projects are commercialized. RedHat needs to make money, no question about that. I just wonder what kind of impact this transition will bring to the users who made the original user base. In mean time, I’m going to enjoying standalone technologies, which make the JBoss portfolio so tempting - Seam, Messaging, Remoting, Cache, AOP and newly Microcontainer.

Posted in jboss | No Comments »

Generic JSF Converter for Seam

November 16th, 2008 Radim Marek

JBoss Seam provides excellent support for mapping of the managed entities back and forth between the select items and the actual entities. Tag s:convertEntity supplies JSF converter which renders option values and consequently translate them back, using Entity Loader (either Hibernate Session or EntityManager), to the appropriate entity. Whole process relies on the provision of the entity identifier. This is indeed very powerful solution, but unfortunately so far I’ve haven’t got much chances to use it, except the training or with very simple applications. In most scenarios, the problem comes with strict separation of the presentation layer from business logic and therefore persistence support. And without Entity Loader, there’s not much fun with s:convertEntity.

Solution to this problem is quite simple - introduction of the custom JSF converter, where only requirement is to implement javax.faces.convert.Converter interface. There’s plenty of examples available on-line or you can refer to Chapter 15.5 of JSF In Action. If it’s for a single use, this is perfect solution. A bit more systematic approach to keep the code manageable is to create a generic converter.

This particular solution is based on the assumption there’s a collection of objects of the same class, and the need for identifier distinguishing these instances. Following the same approach as with s:convertEntity the first step would be to introduce thecustom Facelet tag.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
  "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib xmlns="http://java.sun.com/JSF/Facelet">
  <namespace>http://laststation.net/utils/jsf</namespace>

  <tag>
    <tag-name>convertGeneric</tag-name>
    <converter>
	  <converter-id>net.laststation.utils.jsf.converter.GenericConverter</converter-id>
    </converter>
  </tag>
</facelet-taglib>	

Save this file as META-INF/cg.taglib.xml and using namespace you can refer it within your XHTML view. Next step is to implement GenericConverter. Example follows.

package net.laststation.utils.jsf.converter;

import static org.jboss.seam.ScopeType.STATELESS;
import static org.jboss.seam.annotations.Install.FRAMEWORK;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.annotations.faces.Converter;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

import java.io.Serializable;
import java.util.Collection;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

/**
 * Supports conversion of an object to/from an object
 *
 * @author radimm
 */
@Name("net.laststation.utils.jsf.converter.GenericConverter")
@Scope(STATELESS)
@Install(precedence = FRAMEWORK)
@Converter
@BypassInterceptors
public class GenericConverter implements javax.faces.convert.Converter {
    private Log log = LogFactory.getLog(GenericConverter.class);
    private String identifier;
    private Collection collection;

    public Object getAsObject(FacesContext ctx, UIComponent component, String s) {
        if (s == null)
            return null;

        if (collection != null) {
            for (Object item : collection) {
                String id = getItemIdentifier(item, s);

                if (id != null && id.equals(s)) {
                    return item;
                }
            }
        }

        return null;
    }

    public String getAsString(FacesContext ctx, UIComponent component, Object o) {
        return getItemIdentifier(o, identifier);
    }

    protected String getItemIdentifier(Object o, String property) {
        PropertyDescriptor desc;
        Object result;

        try {
            desc = new PropertyDescriptor(property, o.getClass());
            result = desc.getReadMethod().invoke(o);

            return result.toString();
        } catch (Throwable e) {
            log.error("Unable to get object identifier!", e);
        }

        return null;
    }

    public Collection getCollection() {
        return collection;
    }

    public void setCollection(Collection collection) {
        this.collection = collection;
    }

    public String getIdentifier() {
        return identifier;
    }

    public void setIdentifier(String identifier) {
        this.identifier = identifier;
    }
}

Implementation is quite straightforward, following the same principles as I’ve shown in the post Extending Seam components. It’s important to keep this component stateless (or at least bound them to EVENT scope) to make sure the supplied collection and the identifier are used only within a single call. Provided code is nothing close to perfect, it’s supposed to serve as an example to various different implementations. Also it’s supposed to be an example how easy is to write custom Facelet tag.

To use this converter just place code similar to following example where appropriate:

		<cg:convertGeneric collection="#{mycomponent.countries}" identifier="code"/>
	

Where countries is collection like List<Country> countries, and code is property of the objects within it. Using all the power of EL expressions and Seam functionality - like factories - there’s a plenty of use cases for this converter.

Complete source code is available for download as maven project (see links below). This example omits use of JSPs, because I hope nobody is really using them these days - especially with Seam projects.

Links:


Posted in seam | No Comments »

JBoss Minimal Configuration Profile

November 13th, 2008 Radim Marek

Throughout the last three years and especially after publishing my post JBoss minimal configuration with Tomcat I’ve been asked many times what is actually the idea behind JBoss AS Minimal Configuration profile.

So what exactly you’ll get with following command?

	./run.sh -c minimal

As the name implies, minimal profile consists only from bare configuration set needed to start everything what makes JBoss AS - the microkernel itself. To benefit from its dynamic loading functionality, three services need to be started from JBoss AS code itself:

  • Service Controller to manage dependency and service lifecycle management
  • Main Deployer responsible for deployment process delegation
  • SAR Deployer that accepts JBoss Service Archives (SAR), both packaged and *-service.xml files for already loaded MBean classes.

Although this is enough to call the newly started java process ‘JBoss’, to make it usable, more is still required. From this point rest of the control is handed over to the main configuration file ./conf/jboss-service.xml (via SAR Deployer). Minimal profile has following services configured:

  • Logging service (log4j)
  • Basic Thread Pool
  • Naming service (JNDI)
  • Deployment scanner

As you can see, modulary developed from it’s bones, the JBoss server and all its services are implemented using the component-based approach. For version 4.X this effort is based on Java Management Extensions (JMX). Easy to use MBeans with extended lifecycle, dependency and injection support are registered to the MBean Server, which acts as invocation bus providing ideal decoupling of services.

Having minimal profile allows developers to start developing regular application with added benefit of dynamic redeployment. You can think about this functional set as an powerful application framework. Deployment scanner discovers new archives and Main/SAR deployers will deploy them. What else do we need?

For more information, please, check JBoss JMX Microkernel documentation.

Sounds interesting? It kind of does, but writing this at the end of the year 2008, we need a little bit more to get the right thrill.

And to have some is quite simple, because the long awaited release of JBoss AS 5.0 is going to stir the landscape of application framework market as we know it. Ignoring for now its Java EE 5 certification, the main change involves refactored kernel from it’s JMX origin to pure POJO development and deployment framework. JBoss Microcontainer - project behind the re-implementation - is not just a new backbone of the application server, but either as a standalone library for your application or used as part the JBoss AS minimal configuration profile, it delivers something the competitors are trying to produce for long time - completely modular POJO based application platform.

To see some of it’s features, including dynamic loading, Spring or Guice integration, OSGi support or seamless aspect configuration you can start with the first chapter of the User Guide (Draft) or review basics in the article A Look Inside JBoss Microcontainer from Javalobby.

Posted in jboss | 4 Comments »

IntelliJ IDEA 8.0

November 6th, 2008 Radim Marek

Over a year after the previous version, I’m happy to announce the next version of my favourite development environment is here. The release notes are full of new features and improvements, most of them welcomed to my everyday workflow, especially:

  • First class JBoss Seam support
  • Templates with FreeMarker and Velocity
  • Bunch of new Java refactorings
  • Thread dump analyzer
  • Improved Maven support: create new module from archetype, Repository Browser, pom.xml validation and editing assistance

The next best thing I’m now looking forward is the announcement of the Python support. It is supposed to be developed as standalone plugin and be available for this version later on.

If you’re interested to evaluate IntelliJ IDEA 8.0 and get longer than usual 30 days evaluation period and potentially cut down the price of the license a bit, please, do not hesitate to contact me.

Links:

Posted in Java | No Comments »