Categorie: Java

Internationalization in JSF with UTF-8 encoded properties files

29 October 2010

Introduction

To internationalize your (web)application, the normal approach is to use the ResourceBundle API in combination with properties files which contains externalized text. The ResourceBundle API will load the proper text based on the current Locale and the default (fallback) locale. This sounds nicer than it actually is. Deep under the covers, the ResourceBundle API uses Properties#load(InputStream) method to load the properties files. This method uses by default the ISO-8859-1 encoding. This is explicitly mentioned in its javadoc as well. Here’s an extract of relevance:

The load(InputStream) / store(OutputStream, String) methods work the same way as the load(Reader)/store(Writer, String) pair, except the input/output stream is encoded in ISO 8859-1 character encoding. Characters that cannot be directly represented in this encoding can be written using Unicode escapes ; only a single ‘u’ character is allowed in an escape sequence. The native2ascii tool can be used to convert property files to and from other character encodings.

In a nutshell, you can’t have something like the following as UTF-8 in your properties files:

some.dutch.text = Één van de wijken van Curaçao heet Saliña.

When incorrectly decoded using ISO-8859-1, it would end up as mojibake:

�én van de wijken van Curaçao heet Saliña.

For example the character ç ‘LATIN SMALL LETTER C WITH CEDILLA’ (U+00E7) exist in UTF-8, which is a 16-bit multi-byte encoding, of two bytes 0xC3 and 0xA7. In ISO-8859-1, which is an 8-bit single-byte encoding, those two bytes are separately represented as à and §, see also this ISO-8859-1 codepage. Note that the second byte of É ‘LATIN CAPITAL LETTER E WITH ACUTE’ (U+00C9), which is 0×89, doesn’t represent a valid character in ISO-8859-1. In many environments such a character will be replaced by a question mark ?.

The old solution

The common approach is (was) to escape the characters outside the ASCII range into unicode escape sequences like \uXXXX where XXXX is the unicode codepoint of the character in hexadecimal. So, for example the ç has to be escaped as \u00E7. Doing this manually is a pita, you can use the JDK-supplied native2ascii tool to convert an UTF-8 encoded properties file to an ISO-8859-1 encoded properties file.

/path/to/jdk/bin/native2ascii -encoding UTF-8 text_nl.utf8.properties text_nl.properties

This way the above example will end up like

some.dutch.text = \u00c9\u00e9n van de wijken van Cura\u00e7ao heet Sali\u00f1a.

The better solution

Although using the native2ascii tool is to a certain degree automatable (ant, maven, etc), this is still a maintainability pain and prone to human errors. Fortunately, since the new i18n enhancements in Java 1.6, the Properties API got a new method Properties#load(Reader) which you could feed with an InputStreamReader wherein you can specify the character encoding. To use this in a ResourceBundle, you could make use of -also new since Java 1.6- ResourceBundle.Control class wherein you can control the loading of the propertiesfiles yourself. Therein you can use the -also new- PropertyResourceBundle constructor taking a Reader instead of InputStream.

Here’s a JSF-targeted example of such a ResourceBundle class:

package com.example.faces.i18n;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public class Text extends ResourceBundle {

    protected static final String BUNDLE_NAME = "com.example.faces.i18n.text";
    protected static final String BUNDLE_EXTENSION = "properties";
    protected static final Control UTF8_CONTROL = new UTF8Control();

    public Text() {
        setParent(ResourceBundle.getBundle(BUNDLE_NAME,
            FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL));
    }

    @Override
    protected Object handleGetObject(String key) {
        return parent.getObject(key);
    }

    @Override
    public Enumeration getKeys() {
        return parent.getKeys();
    }

    protected static class UTF8Control extends Control {
        public ResourceBundle newBundle
            (String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
                throws IllegalAccessException, InstantiationException, IOException
        {
            // The below code is copied from default Control#newBundle() implementation.
            // Only the PropertyResourceBundle line is changed to read the file as UTF-8.
            String bundleName = toBundleName(baseName, locale);
            String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION);
            ResourceBundle bundle = null;
            InputStream stream = null;
            if (reload) {
                URL url = loader.getResource(resourceName);
                if (url != null) {
                    URLConnection connection = url.openConnection();
                    if (connection != null) {
                        connection.setUseCaches(false);
                        stream = connection.getInputStream();
                    }
                }
            } else {
                stream = loader.getResourceAsStream(resourceName);
            }
            if (stream != null) {
                try {
                    bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
                } finally {
                    stream.close();
                }
            }
            return bundle;
        }
    }

}

Using it in JSF is extraordinary simple: just define the fully qualified classname instead of the fully qualified bundle name as resource-bundle base-name in faces-config.xml:

    <application>
        <locale-config>
            <default-locale>en</default-locale>
            <supported-locale>nl</supported-locale>
            <supported-locale>es</supported-locale>
        </locale-config>
        <resource-bundle>
            <base-name>com.example.faces.i18n.Text</base-name>
            <var>text</var>
        </resource-bundle>
    </application>

Note the var element. This enables you to reference the bundle as #{text} without the need for f:loadBundle tag in every view.

This way you can keep your properties files UTF-8 all the way. In the above code example, their location is definied by the BUNDLE_NAME constant in the Text class. It expects them to be inside the com.example.faces.i18n package with the filenames text.properties (for generic content, this file is mandatory anyway), text_en.properties (for English), text_nl.properties (for Dutch) and text_es.properties (for Spanish).

Changing the locale in JSF/Facelets

As an extra bonus, here’s some code which shows at its simplest way how you could change the locale (actually, the language) from in the view side. It’s targeted on JSF 2.x / Facelets, but can be done as good on JSF 1.x and/or JSP with minor changes.

The view:

<!DOCTYPE html>
<html lang="#{localeBean.language}"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html">
<f:view locale="#{localeBean.locale}">
    <h:head>
        <title>JSF/Facelets i18n example</title>
    </h:head>
    <h:body>
        <h:form>
            <h:selectOneMenu value="#{localeBean.language}" onchange="submit()">
                <f:selectItem itemValue="en" itemLabel="English" />
                <f:selectItem itemValue="nl" itemLabel="Nederlands" />
                <f:selectItem itemValue="es" itemLabel="Español" />
            </h:selectOneMenu>
        </h:form>
        <p><h:outputText value="#{text['some.text']}" /></p>
    </h:body>
</f:view>
</html>

The bean:

package com.example.faces;

import java.util.Locale;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

@ManagedBean
@SessionScoped
public class LocaleBean {

    private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void setLanguage(String language) {
        locale = new Locale(language);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

}

That’s it!

More background information about the world of characters and bytes as it is seen by computers and humans can be found in this article: Unicode – How to get the characters right?.

Bauke Scholtz

JBoss AS 6 release date published

11 September 2010

Although JBoss AS 6 CR1 and GA have been on JBoss’ JIRA roadmap for some time, no due date was set. Until recently…

These are the dates mentioned:

JBoss AS 6 CR1 15 Nov. 2010 jira
JBoss AS 6 GA/Final 17 Dec. 2010 jira

From CR1 on, JBoss AS 6 would be an officially certified Java EE 6 implementation. If JBoss were to succeed in sticking to these release dates, it would be almost exactly 1 year after the Java EE 6 spec has been released that JBoss is able to offer an implementation.

For the Java landscape, this release is fairly important. The entire concept of having a spec depends on there being multiple implementations, but for the better part of this year only Glassfish has had a Java EE 6 implementation.

Besides that, JBoss AS 6 will also simply mean that more developers have access to the wealth of improvements that Java EE 6 brings to the table. After all, JBoss AS is one of the most used Java EE Application Servers. Although technically possible, most people won’t swap application servers just to be able to use the new spec and will more likely wait for ‘their’ AS to be updated.

Arjan Tijms

Efficient way to determine if a String is a Number

9 September 2010

Introduction

After cloning the M4N projects from Mercurial, one of the first classes I checked was the M4N Common Utils class. I saw the following method:

public static boolean isNumber(String string) {
    try {
        Long.parseLong(string);
    } catch (Exception e) {
        return false;
    }
    return true;
}

It’s the most easy way to determine if the String represents a valid number. But it’s not the most cheap/efficient way for the case that the String doesn’t represent a valid number at all, because an Exception has to be created. Creating an Exception is relatively expensive, among others the whole stacktrace has to be collected/built during the creation of an Exception. Even when it doesn’t throw an exception, it does another unnecessary job: creating the long value based on the digits found.

Alternatives

We could copy the source of the Long#parseLong() and modify it so that it returns false rather than throwing an Exception and that it doesn’t create a long value. It makes use of Character#digit() to obtain the String’s character as a digit. We can replace this by Character#isDigit().

public static boolean isNumber(String string) {
    if (string == null || string.isEmpty()) {
        return false;
    }
    int i = 0;
    if (string.charAt(0) == '-') {
        if (string.length() > 1) {
            i++;
        } else {
            return false;
        }
    }
    for (; i < string.length(); i++) {
        if (!Character.isDigit(string.charAt(i))) {
            return false;
        }
    }
    return true;
}

Since we're looking for a certain pattern in a String, we could also grab regex for this. True, regular expressions are not the holy grail, but it may happen that its speed is very affordable. We want to allow an optional minus sign in the front -? and for the remnant only digits \d+, so the regex pattern end up look like this:

private static final Pattern numberPattern = Pattern.compile("-?\\d+");    

public static boolean isNumber(String string) {
    return string != null && numberPattern.matcher(string).matches();
}

Because compiling the pattern is also an expensive task at its own, we want to do it only once and declare it as a static final field.

(Micro) Benchmarking

Now we want to benchmark those three different approaches. This can basically be done by obtaining the System#nanoTime() as start time, then executing the piece of code -preferably in a fixed amount of iterations- and then obtaining the System#nanoTime() once again as end time and finally calculate the difference between the two times. However, there are some gotchas in this approach. You would be more benchmarking the JVM/Hotspot/JIT which is been used, not the code. The JIT for example may bring in some optimizations which may after all result in misleading benchmark results. Here are two articles which tells a bit more about the gotchas:

The most important considerations are that we'd like to put the code we want to benchmark in its own method which has a return value (which we in turn shouldn't ignore!) and that we also want to execute the particular method a bunch of times beforehand to trigger the JIT optimizations (to "warmup" the JVM).

public static void main(String... args) {
    // Prepare.
    String[] strings = {
        null, "foo", "123", "+123", "-123", "0", "--123", "12345678901234567890"
    };
    int iterations = 1000000;
    boolean result = false;

    // Let for each of the strings show the isNumber() results.
    for (String string : strings) {
        System.out.printf("String: %s isNumberWithParseLong: %s WithIsDigit:"
            + " %s WithRegex: %s%n", string, isNumberWithParseLong(string),
                isNumberWithIsDigit(string), isNumberWithRegex(string));
    }

    // JVM warmup.
    System.out.print("Warming up JVM .. ");
    for (int i = 0; i < iterations / 10; i++) {
        for (String string : strings) {
            result ^= isNumberWithParseLong(string);
            result ^= isNumberWithIsDigit(string);
            result ^= isNumberWithRegex(string);
        }
    }
    System.out.println("Finished! Now the benchmarks ..");

    // Benchmark isNumber() with Long#parseLong().
    long st1 = System.nanoTime();
    for (int i = 0; i < iterations; i++) {
        for (String string : strings) {
            result ^= isNumberWithParseLong(string);
        }
    }
    long et1 = System.nanoTime();
    System.out.printf("isNumberWithParseLong: %d ms%n", (et1 - st1) / 1000000);

    // Benchmark isNumber() with Character#isDigit().
    long st2 = System.nanoTime();
    for (int i = 0; i < iterations; i++) {
        for (String string : strings) {
            result ^= isNumberWithIsDigit(string);
        }
    }
    long et2 = System.nanoTime();
    System.out.printf("isNumberWithIsDigit: %d ms%n", (et2 - st2) / 1000000);

    // Benchmark isNumber() with regex.
    long st3 = System.nanoTime();
    for (int i = 0; i < iterations; i++) {
        for (String string : strings) {
            result ^= isNumberWithRegex(string);
        }
    }
    long et3 = System.nanoTime();
    System.out.printf("isNumberWithRegex: %d ms%n", (et3 - st3) / 1000000);

    // Print the result. This way we let the JIT know that we're interested in the
    // result so that it doesn't optimize the one or other away, for the case that.
    System.out.println(result);
}

At the current machine, a Dell Latitude E5500 with Core2Duo P8400, the results are like this:

String: null isNumberWithParseLong: false WithIsDigit: false WithRegex: false
String: foo isNumberWithParseLong: false WithIsDigit: false WithRegex: false
String: 123 isNumberWithParseLong: true WithIsDigit: true WithRegex: true
String: +123 isNumberWithParseLong: false WithIsDigit: false WithRegex: false
String: -123 isNumberWithParseLong: true WithIsDigit: true WithRegex: true
String: 0 isNumberWithParseLong: true WithIsDigit: true WithRegex: true
String: --123 isNumberWithParseLong: false WithIsDigit: false WithRegex: false
String: 12345678901234567890 isNumberWithParseLong: false WithIsDigit: true WithRegex: true
Warming up JVM .. Finished! Now the benchmarks ..
isNumberWithParseLong: 9392 ms
isNumberWithIsDigit: 369 ms
isNumberWithRegex: 2763 ms
false

You see, using Character#isDigit() is in this particular benchmark up to 25 times faster than Long#parseLong(). True, this benchmark also covers the corner cases. In a lot of cases we expect valid numbers. If you remove the invalid numbers from the String[], you'll see that the difference isn't 25 times anymore, but only about 2.5 times.

Long Overflow

Maybe you've also noticed that there's a 12345678901234567890 string which is invalid according to Long#parseLong() (because it overflows), but is valid according to others. In practice, numbers won't be long like that, but if this has to be taken into consideration in the new isNumber() method as well to ensure its robustness, then it's worth the effort to call Long#parseLong() anyway when the string's length is equal to or greater than the number of digits in Long.MAX_VALUE. We'll change our winning isNumber() method like that:

private static final int NUMBER_MAX_LENGTH = String.valueOf(Long.MAX_VALUE).length();

public static boolean isNumber(String string) {
    if (string == null || string.isEmpty()) {
        return false;
    }
    if (string.length() >= NUMBER_MAX_LENGTH) {
        try {
            Long.parseLong(string);
        } catch (Exception e) {
            return false;
        }
    } else {
        int i = 0;
        if (string.charAt(0) == '-') {
            if (string.length() > 1) {
                i++;
            } else {
                return false;
            }
        }
        for (; i < string.length(); i++) {
            if (!Character.isDigit(string.charAt(i))) {
                return false;
            }
        }
    }
    return true;
}

It became a piece of code, but it's at least faster in the majority of use cases. It's however not very beneficial in a webapplication with 200ms response time and only one or two isNumber() calls.

Bauke Scholtz

Where to put named queries in JPA?

6 September 2010

JPA provides multiple ways to obtain entities. There is a very simple programmatic API that allows us to get an entity by ID, there’s a more elaborate one called the Criteria API and then there’s a query language called JPQL (Java Persistence Query Language).

JPQL is an object oriented query language that is based on the simplicity of SQL, but works directly on objects and their properties. The problem with such a language that’s used inside another language (Java) is where to store the query definition. Traditionally there have been 2 solutions:

  1. Store the definitions in annotations on some entity.
  2. Construct strings holding the definitions inline in your Java code.

The first solution is called a Named Query in JPA, it looks like this:

@NamedQueries(value={
   @NamedQuery(
      name = "Website.getWebsiteByUserId",
      query="select website from Website website where website.userId = :userId")
   @NamedQuery(...)
})
@Entity
public class Website { ... }

The advantages of this method are twofold: JPA checks your query is valid at startup time (no runtime surprises) and the query definition is parsed only once and re-used afterwards. As an extra bonus, it also strongly encourages to used named parameters. The disadvantage however is that its location is just plain awkward. The entity is typically not the location where we wish to store this kind of logic. It gets even more awkward when the query is about multiple entities, yet you have to choose a single one to store the query definition on. Instead, a DAO, Service or whatever code is used to interact with the entity manager is a much more logical place to store a query definition. Unfortunately, @NamedQuery only works on entities. Neither Enterprise beans nor any other kind of managed bean in Java EE supports them.

This thus brings us to the second solution, which looks like this:

public foo() {
    // some code
    Website website = entityManager.createQuery(
      "select website from Website website where website.userId = :userId", Website.class)
      .setParameter("userId", userId)
      .getSingleResult();

This is arguably a much better location, though still not ideal. If the query is long, we have to concatenate strings which makes the query hard to read and hard to maintain. It has the major disadvantage that the query is only checked at runtime and has to be re-parsed over and over again. There are some limited opportunities for reusing a Query object obtained by createQuery(), but since this object is only valid as long as the persistence context in which it was created is still active, those opportunities are really rather limited. Additionally, this style of query definition can make it tempting for developers to build their queries dynamically, giving rise to some nasty potential injection holes.

So having the choice between those two, which one do we choose? Actually, it appears there is a third solution, which is for some reason quite often overlooked by many people:

  1. Store the query text in XML (mapping) files.

In addition to annotations, JPA (and pretty much every API in Java EE that uses annotations) allows you to define the same thing or occasionally a little more in XML. Of course we don’t want one huge XML file with all our queries, but as it turns out JPA simply allows us to use as many files as we need and organize them in whatever way we want. We could for example put all queries related to some entity in one file anyway, or put all financial queries in one file and all core queries in another file, etc. The mechanism is actually quite similar to using multiple faces-config.xml files in JSF. The XML based solution looks as follows.

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0"
>
    <persistence-unit name="somePU">
        <jta-data-source>java:/someDS</jta-data-source>
 
        <!-- Named JPQL queries per entity, but any other organization is possible  -->
        <mapping-file>META-INF/jpql/Website.xml</mapping-file>
        <mapping-file>META-INF/jpql/User.xml</mapping-file>
    </persistence-unit>
</persistence>

Website.xml:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="1.0" 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 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd "
>
    <named-query name="Website.getByUserId">
        <query>
            SELECT 
                website
            FROM 
                Website website
            WHERE
                website.userId = :userId
        </query>
    </named-query>
 
    <named-query name="Website.foobar">
        <query>
            ...
        </query>
    </named-query>
 
</entity-mappings>

Finally, using such query definitions in code is exactly the same as if they would have been defined using annotations, i.e. by calling entityManager.createNamedQuery().

Each XML file can contain as few or as many queries as you like. It might make sense to put a really complicated and huge query in one file, but to group several smaller related queries in another file. Do note that query names are part of a global namespace and are not automatically put in any namespace based on the file they are defined in. In the example above queries are pre-fixed with “Website.”, which happens to be the name of the entity but you can choose anything you want here. In the example META-INF/jpql was used as the directory to store queries, but any location on the class path including storing queries in jars will do.

As mentioned, for some reason this XML method seem to be often overlooked by many people. I’ve personally met multiple persons who build themselves a management system for storing JPQL queries in files, loading them, substituting parameters, etc while such a mechanism is in fact readily available in JPA (and has been since JPA 1.0!). Of course, the home grown systems don’t have the startup-time validation of queries nor do they do any pre-parsing and pre-compilation of queries.

Arjan Tijms

Facelets and legacy JSP

28 April 2010

It’s well known that Facelets is the far superior technology when it comes to authoring pages using JSF. By default, Facelets has no provisions to include content from JSP pages, or Servlets for that matter. Normally this really isn’t needed. Facelets provides a better and clearer templating mechanism than what JSP has ever offered.

Facelets & JSP in one app

However, when migrating a large application you might have to run a while in mixed-mode, that is running with both Facelets and JSP pages in a single application. It ain’t pretty, but it is explicitly supported. Ever wondered why you are forced to use prefix mapping for this? Well, the Facelets view handler delegates to the default view handler for createView, which transforms a view ID suffix like .jsf or .xhtml to a default one (e.g. .jsp), but leaves the suffix alone when using a prefix mapping like /faces/*. The Facelets viewhandler later decides to handle a request itself or delegate again to the default view handler, based on the suffix. When using suffix mapping, the first delegation had just caused this suffix to be replaced with the default suffix and the Facelets view handler thus can’t make any distinction between a Facelets request and a JSP request anymore.

The above is thus why you have to use prefix mapping for Facelets pages if you want to use both Facelets and JSP in a single application.

JSP includes

Having Facelets and JSP pages in 1 application might be only half of the story. It’s not unlikely that the existing JSP pages make use of included resources that are also JSP based, or maybe Servlet based. Rewriting these to full-fledged Facelets artifacts is technically the best option, but if you have to run in mixed-mode for a while, this means you have to maintain two versions of these includes. Obviously maintaining two separate versions is not ideal too.

One alternative, that I like to present here, is building a bridge component that executes the JSP or Servlet and writes its output to the standard JSF response writer. Thanks to Facelets and JSF in general, such a component is actually not that hard to build:

The component’s source code:



public class JSPIncludeComponent extends UIComponentBase {

public String getFamily() {
   return "components.jsp.include";
}

public void encodeBegin(FacesContext context) throws IOException {
   try {
      ExternalContext externalContext = context.getExternalContext();
      HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
      HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();

      // Create dispatcher for the resource given by the componen's page attribute.
      RequestDispatcher requestDispatcher = request.getRequestDispatcher((String) getAttributes().get("page"));

      // Catch the resource's output.
      CharResponseWrapper responseWrapper = new CharResponseWrapper(response);
      requestDispatcher.include(request, responseWrapper);

      // Write the output from the resource to the JSF response writer.
      context.getResponseWriter().write(responseWrapper.toString());
   }
   catch (ServletException e) {
      throw new IOException();
   }
}
}

The component here gets its content from the resource path denoted by the attribute “page”. To JSF, there is no difference between content that is generated locally in the component and content that the component obtained from somewhere else.

The component makes use of a HttpServletResponseWrapper, which is a fairly common artifact in many legacy Servlet/JSP applications. For completeness, here is the source of the particular implementation I used:



public class CharResponseWrapper extends HttpServletResponseWrapper {

   private CharArrayWriter output;

   @Override
   public String toString() {
      return output.toString();
   }

   public CharResponseWrapper(HttpServletResponse response) {
      super(response);
      output = new CharArrayWriter();
   }

   public CharArrayWriter getCharWriter() {
      return output;
   }

   @Override
   public PrintWriter getWriter() {
       return new PrintWriter(output);
  }

   @Override
   public ServletOutputStream getOutputStream() {
      return new CharOutputStream(output);
   }

   public InputStream getInputStream() {
      return new ByteArrayInputStream( toString().getBytes() );
   }
}

class CharOutputStream extends ServletOutputStream {

   private Writer output;

   public CharOutputStream( Writer writer ) {
      output = writer;
   }

   @Override
   public void write(int b) throws IOException {
      output.write(b);
   }
}

In JSF 1.2 there’s a minor inconvenience where you have to register the component you just created in an .XML file. JSF 2.0 provides a convenient annotation for this, but in JSF 1.2 it has to happen via XML:


<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
    version="1.2"
>
	<component>
		<component-type>com.example.component.JSPIncludeComponent</component-type>
		<component-class>com.example.component.JSPIncludeComponent</component-class>
	</component>

</faces-config>

This can either be put in your regular faces-config.xml, or in a separate faces-config.xml in a META-INF directory on your class-path. The latter option is typically when packaging in a jar, but also works for any regular Java source dir of your web module.

To make the component usable on a Facelets page, we only have to assign it a name space and a tag name. This has to happen in a file with a suffix .taglib.xml that’s also in a META-INF directory on your class-path. Even in JSF 2.0, there are unfortunately no annotations for this. For this example I called the file foo-include.xml:


<!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>
	<namespace>http://foo.com/jsf</namespace> 

	<tag>
	  <tag-name>include</tag-name>
	  <component>
	    <component-type>com.example.component.JSPIncludeComponent</component-type>
	  </component>
	</tag>

</facelet-taglib>

Note that this example uses the older DTD for the standalone Facelets implementation for JSF 1.2. JSF 2.0 uses a more modern xsd, for which an example can be seen here. Also note that we don’t have to define any attributes nor did we had to define any getters and setters for those attributes on the UI component implementation. This convenience does come at a cost though, as your IDE now can’t provide you with any content assist for the component’s attributes.

Finally an example of how it all comes together on an actual Facelets page:


<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:foo="http://foo.com/jsf"
   version="2.1"
>
	<ui:composition>
		<html xmlns="http://www.w3.org/1999/xhtml">

			<head>
				<title>JSP include example</title>
				<meta http-equiv="pragma" content="no-cache"/>
				<meta http-equiv="cache-control" content="no-cache"/>
				<meta http-equiv="expires" content="0"/>
			</head>  

			<body>
				JSP: <br/>
				<foo:include page="/test.jsp"/><br/><br/>

				SERVLET: <br/>
				<foo:include page="/TestServlet"/><br/><br/>
			</body>
		</html>

	</ui:composition> 

</jsp:root>

I wouldn’t recommend using this as a lasting solution, but it might ease a migration from legacy JSP with smelly scriptlets and all on them to a more sane and modern Facelets application.

Arjan Tijms

Java EE 6 – release imminent

7 October 2009

Yesterday the umbrella JSR for Java EE 6 finally released a proposed final draft. This means the release of Java EE 6, a fairly large release with many tweaks and additions, is relatively imminent.

I’ve been tracking its progress for some time now and collected references to a number of articles about the major parts of Java EE 6 here: Java EE 6 progress page.

Indeed, the two most influential open source implementations (Jboss AS and Glassfish) are about to release new versions supporting Java EE 6. Naturally, Glassfish is more up to date with their support, but this time Jboss AS is hot on their heels.

Alexis of Sun wrote yesterday that “We’re fast approaching a final release of v3 with full Java EE 6 support indeed.”

Meanwhile, Jason Green of Jboss announced about a month ago that “we can put out a 5.2 beta which includes some cool EE6 capabilities. The target release date is 10/15″, which would be around next week.

So, Glassfish is about to come with full support, while Jboss AS comes with some Java EE 6 support, but whatever your favorite implementation is, it seems that enterprise Java developers are in for some interesting times.

IntelliJ – The IDE I wanted to love

27 June 2009

In the Java market we have a plethora of ide’s to choose from. The one I am most familiar with and also see used most often is Eclipse. Everyone knows Eclipse of course. Eclipse is not without its faults. So its natural to look around every so often. Eclipse is my baseline. At this point we arrive at IntelliJ. IntelliJ is another well known ide. I have heard IntelliJ described as the only ide for java developers, the ide that wil increase productivity 10-100 times. Its a commercial product which means you can have a reasonable expectation of stability, customer support and all the nifty tooling you would expect in Eclipse or any other ide. Naturally you expect it to be better than Eclipse or you would’t pay for it. I proceeded to download, install and put IntelliJ to use.

A few words on environment. I run Debian Lenny on a Dell Precision T-3400.

IntelliJ is an easy install. Download, unpack, run (,????, profit!). Its only 100MB compressed which is less than 150MB for Eclipse classic (and a lot less than 650MB for MyEclipse). You may need to check JDK_HOME variables but I’m guessing most people wil have this set up already. Otherwise what are you doing with a Java specific IDE. You may be confronted with a dialog or two. To begin with you should be safe with the defaults. Odds are you only need a subset of the defaults to begin with anyway.

My first impression after the install is that IntelliJ is very pretty. Especially after I changed the theme. This all went really well. Everything was fast and seemed well thought out. Of course IntelliJ has its own key mapping, menu ordering and things of that nature. If you like you can enable Eclipse key mappings but if you want to get to know a program rather than get to work quickly I recommend going with what’s totally unfamiliar. Although I am of the opinion that ctrl-s means save in any language.

The Subversion plugin works like a charm. I am even convinced it’s faster than Subversive…at least in our local environment where Subversion has, at times, been a pain to work with. If for no other reason, this plugin makes me want to use IntelliJ. If my work confined itself to talking to the repository I would be done. Forever.

So here we have a fresh working copy of our project, complete with Eclipse project files. IntelliJ understands Eclipse project files or at least so it claims. An import or two later and I have an official IntelliJ project. As far as I’m concerned I just need to point this puppy to Tomcat and we’re good to go.

Now IntelliJ has a lot of spiffy UI thingies. You got screens for configuring everything. You’ve got modules and facets. You’ve got raindrops on roses and warm woolen mittens. Confidently I configured the project to deploy to tomcat. Of course it wouldn’t work at once, that would be too much to ask. I was convinced any problems I was sure to encounter would be easy to solve.

My first problem comes in the form of compiler errors. “But wait,” you say, “did you not do a fresh checkout? Are your colleagues so daft that they enter broken code?” That would be yes and not usually. IntelliJ seems less permisive than eclipse in allowing certain constructs. Mind you Eclipse has no compile errors on the same code…so it can’t really be a compiler error since they use the same one. Ok, so its a precompile syntax validation check error or whatever. It’s not really a big deal.

Unfortunately I have no clue what IntelliJ is really doing. Somewhere there exists a tomcat. Somewhere there exists at least one copy of this tomcat. Somewhere you may or may not be deploying your project. Ok, I can actually find where IntelliJ hides its tomcat copy. Why can’t it just use my tomcat? I don’t know. Oh you can, sort of, but then you all of a sudden have to start and stop tomcat yourself. Not that I really care that IntelliJ uses a copy of tomcat, except that this copy still uses the originals directories. Sort of. I think. I’m not really sure.

A word on IntelliJ support. If you happen to write them they answer quickly. Really quickly. Actually the reply is there almost before you press compose mail. I was seriously impressed. Unfortunately they couldn’t help me and I dind’t want to rely heavily on support which is mostly meant for paying customers anyway. I also don’t like using support lines in general. It feels like a flaw in the product. Which it is.

You may be asking why I didn’t simply look up the answers in the documentation. IntelliJ documentation is one of the worst I have ever seen. It’s not worse than factually wrong information but it’s not better than a blank piece of paper. Basically if you have something labeled “Perform action” the documentation wil read “Performs the action Action”. The documentation will never actually explain what is happening or go into the details of anything.

So now I have a project which may or may not be deploying somewhere. After some looking around I do figure out I have lots of classpath problems. Also, my ant builds aren’t being run. Ok, add library here, ant build before deploy…Some progress made but not enough. My project still won’t work.

To make a long story short for about a week I’ve been playing with IntelliJ. I’ve installed, reinstalled, checked out, imported, etc, etc. I can’t get our project to work. This is a project which does work under Eclipse. So I blame IntelliJ. Where Eclipse always seems to have the thing you are looking for where you are looking for it, IntelliJ will make you search for it. Where Eclipse forces you to know what you’re doing and setup this and do that, IntelliJ has done it for you (mostly) and otherwise you can pretty much forget it.

To me IntelliJ is like a beautiful woman with a really anoying personality and a deaf ear. I really wanted to like it. Ask my colleagues, I am ready and willing to say that I hate something. I do it regularly and with passion. I do it to Eclipse all the time. Yet, despite all this, I really can’t hate IntelliJ. I would still really like to work with it. I’m convinced it could be really good. I can’t hate it and yet I can’t love it. For now it wil remain the IDE I wanted to love.

Jboss AS 5 GA released!

5 December 2008

Today is a historic day for Java, as one of the leading implementations of Java EE 5, Jboss AS 5 has *finally* been released. Originally planned for early 2007 orso and promised to be released almost every quarter.

But today, no more speculation and no guessing. It’s here, and this time it’s for real! Read all about this fabulous release here: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=146773

Download it from here: http://www.jboss.org/jbossas/downloads/

With Jboss officially implementing the Java EE 5 spec now, a new baseline of Java has been set. From now on, technologies like JSF 1.2, EJB3 and JPA can really be considered as basic, standard available techs.

Congrats to the Jboss team, and hoping it won’t take them as long to release Java EE 6 ;)

References:

Jboss AS 5 GA release date

24 November 2008

People have been wondering for some time about the release date of Jboss AS 5. As many of you know, Jboss 5 has been in development for quite some time and its release has been highly anticipated. Arguably, Jboss is one of the most important, if not -the- most important Java EE implementation. The fact that an official release of version 5 of this spec has been so long overdue, has been painful. Of course, Jboss 4.2.x supports most of the Java EE 5 stuff, but it’s just not the Real Thing.

The importance of Jboss AS is due to a number of reasons. Of course there are other Java EE 5 implementations out there, but the number of offerings seem to be declining. On the commercial side of the fence there’s basically IBM’s Websphere and Oracle’s OC4J, and on the open source side there’s Glassfish, Geronimo and Jboss AS 5. For many people, a closed source, commercial Java EE implementation seems to be little attractive. This leaves us basically with only 3 options for the moment. Geronimo may be nice, but nobody seems to be using this. Glassfish should maybe be the default choice (afterall, the Sun Java SE implementation is typically the default choice for many too), but has two main problems:

  1. It can’t be configured.
  2. It doesn’t offer any services.

This basically leaves Jboss AS 5 as the only choice, it it weren’t for the fact that it was always still in beta or in rc. In a way, this left a kind of void in the Java EE world (unless of course configuration and services don’t matter to you, then I suppose Glassfish would be perfectly fine).

Previously, Jboss AS 5 had been announced for february 2008 (see Where is JBossAS GA 5), but this seemed to be too optimistic. A major milestone was reached when Jboss AS 5 RC2 was officially EE 5 certified. A careful guess for the GA release date was then made for early November 2008 (see JBoss AS is now EE5 certified!).

Today however, a definite date has been given by Project Lead Dimitris Andreadis:

December 2008!

(See Jboss 5 release date?)

For those interested, these are some additional interesting resources:

How we won an iPhone dev competition without any prior knowledge

1 September 2008

About 2 weeks ago one of my team members, Robin Eggenkamp, mentioned there would be some iPhone dev ‘conference’ this month (iPhone Dev Camp, Amsterdam), originally at the building exactly opposite of the building where our own office is. Since I’m always interested in anything related to development I agreed to tag along. I expected it to be the kind of event where some talks are organized with a small hands on lab where some expert developer teaches newbies how to get up and running.

Now I’m certainly not a newbie when it comes to development. I lead a team of Java developers working on a rather large 200.000+ loc Java EE enterprise application and in a past life I worked as a win32/MFC C++ developer. Somewhere in between I also managed to finish a CS master. But… the iPhone was new to me. Although I’ve owned Apple computers ever since System 6 was still new & shiny, I’d never touched Xcode, Objective-C or Cocoa before. The closest I ever came was firing up Project Builder on my G3 iMac’s OS X 10.2, but only to test some C++ routine.

Because of the hands-on thing, I did plan to at least read an Objective-C tutorial the night before going to the event, but unfortunately couldn’t find the time to do so. When we arrived at the scene at exactly 10:00 in the morning, the place was already rather filled up. We found a cozy spot at a place in the back and while Robin started to connect his MacBook, I looked around and noticed it was not exactly what I thought it would be. Instead of an organized series of talks, this was a bunch of people sitting behind their computers, hacking away at stuff. The atmosphere seemed top notch though and I had a quick chat with some of the other people. At around 11 there was a short introduction talk and it became clear that the intend was to code something up for the iPhone and demo it at 17:00. The best apps would win a prize, with the first prize being a speaker set and a copy of Adobe CS3 or so.

By total coincidence, only moments after having his MacBook connected to the network, Robin finally received an email that he had been accepted for the iPhone developer program, something for which he had applied a whole month before. That meant we could start with some real development now! Robin had a little bit of experience with Xcode, but had done barely more than deploy some hello world examples to the simulator and tinkering a bit with the code. The fun thing about this was that normally whenever I need to use a new technique for my regular enterprise development, I first get myself a book of at least 600 pages, read the first 200 pages of that, try out some basic concepts, read another 200 pages, try another aspect of the tech, etc before I even attempt to apply it. Now we had to build something in a language we both didn’t know, on a platform we didn’t know, with tools we didn’t know and all of that in the course of a day :P

We started thinking about what kind of application we would try to create for the iPhone and I suddenly got the idea of letting the iPhone connect to a Mac and using data from its acceleratometer to move the Mac’s mouse pointer. I started with formulating some simple milestones to reach that goal:

  • Create local Mac app that moves mouse programmatically.
  • Create local iPhone app that just prints accelerator values to the screen.
  • Setup a connection from the iPhone to the Mac that just sends “hello”. Let the Mac prints this.
  • Integrate the individual steps to become the app we actually want. I assumed we would need some time to calibrate the raw acceleratometer and to find a suitable mapping from the meter’s range to the pixels on the Mac’s screen.

Meanwhile Robin was attempting to deploy his hello world example app to his iPhone using his just obtained certificate. It should have been a trivial thing, but after each deployment attempt a message box was displayed saying something like “0xE8000001, your mobile device has encountered an unexpected error (0x…) during the install phase: verifying application”. We tried many things, but nothing seemed to work. While we were feverishly googling for a solution, precious time on the clock ticked away. It must have been somewhere around 13:00 when Robin finally found out which settings in the project needed to be adjusted in what way. The example hello world app deployed correctly to the iPhone and it worked! Looking at the clock we realized we only had about 4 hours to go and we hadn’t written a single line of code ourselves yet…

Milestone 1 – The local Mac app – moving the mouse

The initial plan was to build the Mac app in Cocoa, but we decided that using Java would be the fastest way for us, basically since we simply know the language and environment. This milestone was easily completed. Using the java.awt.Robot class moving the Mac’s mouse pointer was a breeze.

Milestone 2 – The local iPhone app – printing accelerator values

For this milestone we couldn’t shy away from Objective-C anymore and actually had to take the plunge. We first looked up an example for getting data from the acceleratometer and luckily Apple had provided one. The next thing was to build a simple app, barely more than a hello world, that prints these values to the screen. This proved to be a little harder. Objective-C sometimes looks like Java and sometimes doesn’t. What are those square brackets everywhere? It looked like a kind of method call, but I couldn’t really figure out the meaning of the square brackets themselves. And how where we supposed to define properties so we could take advantage of the injection features of interface builder? Using @Property seemed obvious to us, but the compiler kept generating tons of warnings and errors. And how do we organize our code? We had created an AppDelegate, which we connected in interface builder to a mainView that inherited from the Window class. We added two labels that we injected to this view class, deployed our app to the iPhone, and… nothing happened. After feeling a little silly, we actually tried to quickly read some documentation. We learned that the square brackets have no extra special meaning, it’s just the Objective-C syntax for doing a method call. @Property needed to be accompanied with a declaration in the header and another annotation in the implementation file, @synthesize, that’s there to actually generate the getter and setter. Also, when creating a new project Xcode had already created an AppDelegate for us, something we overlooked.

With this new insight we ‘almost’ got our first real code completely working, but a few small things were still not going as planned. We therefor decided to throw it all away and change our strategy; start with an existing iPhone example application and just throw away what we don’t need and add what we do need. Going that route would save us from dealing with some of the nitty-gritty.

It was 14:00 by then and lunch had started. We enjoyed our nice and free lunch and had a chat again with the other guys. It seemed to be the case that we where hopelessly behind, since we still didn’t really had anything. After lunch things started to improve though. Having some idea of the Objective-C syntax now and using some of my almost forgotten C knowledge, we were quickly able to adapt an existing app to just print the 3 accelerator values (x, y, z) to 3 separate labels. Check!

Milestone 3 – Connecting iPhone and Mac

Since we had wasted a tremendous amount of time on the deployment and second milestone, we only had little time remaining. My original plan was to have one thread on the Mac listening to incoming communication, fetching commands and dispatching these to a (blocking) queue which will be read by another thread that controls the mouse movement. For the communication we wanted to dig through the iPhone API a little to see what it had to offer. With only 2 hours remaining, we decided to use the most basic communication method available; a simple BSD socket. At the Mac side we used a simple ServerSocket in Java and at the iPhone side we used the low level C socket()/connect() functions, for which we found a basic snippet of code that needed only a few adjustments. Although absolutely not the best technical solution, we decided to create and close a connection for each message sent.

Sending a basic test string from the iPhone to the Mac worked perfectly, so a little later we were able to send the accelerator values to the Mac. Check!

Milestone 4 – Integration

We had all the separate components up and running and now only needed to integrate them together. The acceleratometer’s values appeared to be in the range of -3 to 3 for all axis, while Robin’s Mac had a 1280*800 resolution. When totally in rest, there was a certain noise margin in the values that we got from the acceleratometer, so we expected that a little calibration was required. To test a little though we started with just multiplying the values we got by 60 and added that to the current mouse position. Surprisingly this already gave fairly good results. The multiplication and the rounding down to whole pixels canceled out the noise perfectly. In a few minutes we ended up with a really simple mapping that was just something like max(0,min(forceX * 15,1280)) for the movement on the X-axis. Sending about 15 messages per second appeared to be enough for smooth motion.

By now we suddenly had some time remaining, so we used that to implement the ability to also do a mouse click. Our initial approach to that was to sent a separate message for a mouse click, but it appeared to be more robust to just add the mouse button state as a fourth parameter to the existing message. At the very last moment there was a little panic when all messages being sent appeared to be empty. Apparently, our string formatting syntax for a boolean wasn’t supported by Objective-C (we used something like “%d,%d,%d,%b”) or maybe there was a difference between a primitive boolean and an Object boolean. We decided not to pursue the issue and simply use the string “false” and “true” (something I normally always stay far from, but with 30 seconds on the clock remaining there wasn’t much choice). Since we had been fumbling with the code for most of the day, we figured that our chances of winning anything where rather slim. Nevertheless we were happy that we had came up with something that worked, and actually worked rather nice.

The demo

It was now time for all of us to demo our application. Among others there was a tips of the days app, an app that retrieved quotes from the Internet, a very cool looking game where you had to touch the screen to cause a kind of bubble on which a moving object bounced to another side complete with sound effects and all and a very impressive looking application that measured your air time when skiing in addition to your speed, path and direction. Unfortunately this last app appeared to be only concept art.

When it was our time for the demo, I told something about the technical shortcuts we had taken, while Robin demonstrated how to use the iPhone to paint a running man in a painting application on the Mac.

Showing the demo
Picture by tizzle. See flickr.

Much to our surprise, our application was well received and we got the first price; a nice speaker set for the iPhone or iPod. We’ll install it in the office :)

Arjan Tijms

Links:

best counter