JBoss AS 6 GA released!

29 December 2010

Today is another historic day for Java, as one of the leading implementations of Java EE, namely JBoss AS, has released its Java EE 6 implementation JBoss AS 6.

Where JBoss AS 5 had a very shaky release cycle, the JBoss AS 6 cycle went very smooth. An originally planned JBoss AS 5.2 was abandoned early and the team went straight for JBoss AS 6. A series of milestones and a candidate release were planned, which were all released on time with only minor deviations.

Almost exactly a year after the Java EE 6 specification itself and the reference implementation Glassfish V3 was released, JBoss is now the first to release an independent third party implementation. Of course, independent and third-party has to be taken with a grain salt. The reference implementation for CDI, an important new API in Java EE 6, is Weld which is implemented by JBoss and used by Glassfish. On the other hand, JBoss doesn’t develop its own JSF implementation but bundles the reference one from Oracle.

Anyway, with JBoss AS officially implementing the Java EE 6 spec now, a new baseline for Java EE has been set. From now on, technologies like JSF 2.0, EJB3.1, JPA 2.0 and CDI can really be considered as basic, standard available techs.

Download it from here: http://www.jboss.org/jbossas/downloads/
Release notes: http://community.jboss.org/wiki/AS600FinalReleaseNotes

Congrats to the JBoss team, and good happy developing for everyone who is updating to Java EE 6!
Arjan Tijms

JBoss AS 6 CR1 released

22 November 2010

With only one week delay (see JBoss AS 6 release date published) JBoss has today released the first release candidate/candidate release of the exciting new JBoss AS 6.

As mentioned before, this will give JBoss developers access to the wealth of improvements brought by Java EE 6. See my Java EE 6 progress page for details about those changes.

Release notes : http://community.jboss.org/wiki/AS600CR1ReleaseNotes
Download: http://sourceforge.net/projects/jboss/files/JBoss/JBoss-6.0.0.CR1/

Interesting additions are the shared library mode (JBAS-8304) and JBoss Cache now being replaced by Infinispan (JBAS-7837). Hopefully this will also end the long standing memory leaks in CDI (JBAS-6545).

Arjan Tijms

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 0x89, 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 = u00c9u00e9n van de wijken van Curau00e7ao heet Saliu00f1a.

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().getExternalContext().getRequestLocale(), 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) {
        this.locale = new Locale(language);
    }

}

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

Van een Ubuntu Lenovo T61 naar een Macbook Pro laptop

17 May 2010

Ben overgegaan van Ubuntu naar OS X en van Lenovo naar Apple, want mijn laptop lenovo T61 is na een trip met het vliegtuig toch echt kapot gegaan.

Stop dus nooit je laptop in gewone bagage; dat overleefde mijn laptop in ieder geval niet. Lenovo (IBM) staat of stond wel bekend om zijn kwaliteit.

Wat moest de nieuwe laptop hebben:

  • Relatief licht zijn, onder de 2.5 kg
  • Batterij moest echt lang mee gaan, meer dan 4 uur
  • Buiten in de zon kunnen werken, LED verlichting
  • Scherm van 1650×1050 pixels hebben.
  • Makkelijk thuis en op m’n werk kunnen opladen
  • Snel kunnen opstarten
  • Makkelijk kunnen sync-en met mobiele telefoon
  • camera, voor skype meeting
  • Makkelijk backups maken

De nieuwe macbook pro voldeed aan alle eisen.

Beginnen op de mac heb ik gebruikt om over te schakelen.

Meest irritante van het overschakelen is eigenlijk de “End” functie toets (cmd + pijltje) om naar eind van regel te gaan. Die werkt niet goed op mijn externe keyboard. Voor de rest gaat alles vrij goed. Wat ik een super fijne feature vind, is de link in mail app waarin je direct naar jouw geantwoorde mail gaat op een inkomende mail.

Ik kan de overstap erg aanraden.

Review: world’s first Supermicro 2026TT chassis

10 March 2010

Just after our house style has been redesigned in blue, we technicians go green. Our intention was to modernize our server park with exclusive 2.5″ chassis, and where long waiting for a 2U, 2.5″ chassis that would accommodate a lot of SSDs. We are already preparing a new database server (fitted with 24 x 2.5″ INTEL X25-E SSDs) based on the Supermicro SC826 chasis, but our XEN cluster would love something similar too!

The wait is over: we were shipped the world’s very first Supermicro 2026TT-HIBXRF 2U Server. While the blades more or less existed before, the speciality on this configuration is that all 6 Sata channels are connected to the backplane. This enables us to use all Sata ports for LVM setups, using SSDs for performance and power saving sake.

front1

front1

front2

front2

swap bays and switching panel details

swap bays and switching panel details

rear1

rear1

rear connection details

rear connection details

Which goodies did we place in the blades:

  • CPU: 2 x Xeon X5570 (Nehalem, 4 cores, 8 threads, 2.93 GHz, 95 W)
  • RAM: 6 x Kingston KVR1333D3D4R9S/4G
  • HDD: 1 x Seagate ST9500530NS 500GB SATA
  • SSD: 4 x INTEL X25-M Postville SSDSA2MH160G2C1 (@FW 02HD)

On the HDD we installed debian lenny with XEN kernel Xen 3.2-1-amd64; DOM0 and DOMu are running 2.6.26-2-xen-amd64 kernels, the virtual machines will run on LVM volumes created using 4 SSDs. Since the INTEL SSDs are based on MLC cells we are taking a risk with potentially intensive writing; however, testing on our workstations showed that the life expectancy of this setup will be a couple of years. Manufacturers are planning longer living MLC SSDs at the end of this year, so replacements will be on hand pretty soon.

bios

bios

What about power usage of such a server? I measured it quickly with no optimizations in the Linux kernel and with the Hyper-Threading option switched off in the BIOS:

  • STANDBY: 30 Watt
  • 1 BLADE: 210 Watt
  • 2 BLADES: 347 Watt
  • 3 BLADES: 499 Watt
  • 4 BLADES: 647 Watt

This comes down to ~ 150 Watt per blade (idle), and ~50 Watt for 4 x HDD, 16 x SSD, and some case fans – pretty cool, isn’t it? What this setup will do on high load will be determined later; for now, the cooling conditions in our test room where far from optimal: with an ambient temperature of 27 degrees Celsius, the temperature within the chassis rose to 53 degrees. We have to wait for stress testing when the server is at its final destination, with much better cooling conditions.

What about XEN, LVM and SSD performance? We are not done yet, but measurements in DOM0 showed pretty nice figures. Since a hardware RAID solution using these twin blades is more or less off limits, software RAID is the best alternative. From our experience, we know that the xfs file system performs best for benchmarking (with schedulers set to deadline). After some sweet-spot measurements using lvm2, using 4 SSDs (RAID 0), we figured out that the following settings are best:

pvcreate --metadatasize 511K /dev/sdb /dev/sdc /dev/sdd /dev/sde
vgcreate xenvg-ssd /dev/sdb /dev/sdc /dev/sdd /dev/sde 
lvcreate -i4 -I256 -L40G -n benchmark -n xenvg-ssd

Figures derived from this setup are not benched using IOZone, IOMeter or similar, but we used our own tools that will do the trick. For more information on this, please see: http://jdevelopment.nl/hardware/one-dvd-per-second/:

bm-flash:

Filling 4G before testing  ...   4096 MB done in 12 seconds (341 MB/sec).

Read Tests:

Block |   1 thread    |  10 threads   |  40 threads
 Size |  IOPS    BW   |  IOPS    BW   |  IOPS    BW
      |               |               |
 512B |  8695    4.2M | 58401   28.5M |153774   75.0M
   1K |  7712    7.5M | 54920   53.6M |148026  144.5M
   2K |  6455   12.6M | 46069   89.9M |134606  262.9M
   4K |  4909   19.1M | 35301  137.8M |103674  404.9M
   8K |  4516   35.2M | 32108  250.8M | 72833  569.0M
  16K |  3954   61.7M | 27518  429.9M | 43003  671.9M
  32K |  3262  101.9M | 19297  603.0M | 22875  714.8M
  64K |  2376  148.5M | 11136  696.0M | 11750  734.3M
 128K |  1665  208.1M |  5880  735.1M |  5933  741.7M
 256K |  1001  250.4M |  2979  744.7M |  2973  743.4M
 512K |   841  420.7M |  1415  707.5M |  1422  711.2M
   1M |   533  533.5M |   619  619.0M |   621  621.0M
   2M |   280  560.0M |   307  615.5M |   309  619.3M
   4M |   143  574.3M |   153  614.7M |   151  606.3M

Write Tests:

Block |   1 thread    |  10 threads   |  40 threads
 Size |  IOPS    BW   |  IOPS    BW   |  IOPS    BW
      |               |               |
 512B | 11062    5.4M | 21375   10.4M | 26693   13.0M
   1K |  6834    6.6M | 15384   15.0M | 22303   21.7M
   2K |  6244   12.1M | 13582   26.5M | 23145   45.2M
   4K |  7473   29.1M | 18849   73.6M | 25007   97.6M
   8K |  7106   55.5M | 24629  192.4M | 31830  248.6M
  16K |  7254  113.3M | 18285  285.7M | 23884  373.1M
  32K |  4842  151.3M |  8619  269.3M | 11580  361.8M
  64K |  2525  157.8M |  4604  287.7M |  5943  371.4M
 128K |  1319  164.8M |  2377  297.2M |  3048  381.0M
 256K |   561  140.4M |  1244  311.0M |  1531  382.7M
 512K |   368  184.0M |   745  372.8M |   778  389.3M
   1M |   335  335.2M |   381  381.8M |   401  401.5M
   2M |   174  348.1M |   192  385.7M |   210  421.0M
   4M |    91  364.7M |   103  414.0M |   107  428.3M

xdd:

Random READ tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  13639      6 | 120414     61 | 186044     95 |
     1024 |  14256     14 | 109734    112 | 181448    185 |
     2048 |  12669     25 |  95246    195 | 171345    350 |
     4096 |  10302     42 |  75704    310 | 132238    541 |
     8192 |   8591     70 |  55870    457 |  78980    647 |
    16384 |   7244    118 |  35797    586 |  43133    706 |
    32768 |   5786    189 |  21985    720 |  22711    744 |

Sequential READ tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  35796     18 | 119992     61 | 178309     91 |
     1024 |  34838     35 | 113584    116 | 170864    174 |
     2048 |  28590     58 |  97803    200 | 173524    355 |
     4096 |  19967     81 |  72748    297 | 134078    549 |
     8192 |  14151    115 |  57131    468 |  79959    655 |
    16384 |   9276    151 |  38128    624 |  43480    712 |
    32768 |   4460    146 |  22309    731 |  22812    747 |

Random WRITE tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  23271     11 |  33162     16 |  40870     20 |
     1024 |  16571     16 |  26695     27 |  37758     38 |
     2048 |  16747     34 |  25156     51 |  34664     70 |
     4096 |  14019     57 |  24817    101 |  29577    121 |
     8192 |  12817    104 |  25704    210 |  30310    248 |
    16384 |  11149    182 |  15612    255 |  23467    384 |
    32768 |   6613    216 |   8525    279 |  12281    402 |

Sequential WRITE tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  29471     15 |  36580     18 |  41892     21 |
     1024 |  26631     27 |  35478     36 |  36696     37 |
     2048 |  23431     47 |  32128     65 |  39953     81 |
     4096 |  22747     93 |  33924    138 |  40566    166 |
     8192 |  19811    162 |  23773    194 |  38880    318 |
    16384 |  12436    203 |  16751    274 |  24396    399 |
    32768 |   7470    244 |   8978    294 |  13039    427 |

Random READ/WRITE [90/10] tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  14961      7 |  57521     29 |  85189     43 |
     1024 |  12284     12 |  43737     44 |  73368     75 |
     2048 |   9762     19 |  33229     68 |  66863    136 |
     4096 |   7366     30 |  27530    112 |  58668    240 |
     8192 |   6298     51 |  25379    207 |  48998    401 |
    16384 |   5283     86 |  20828    341 |  29309    480 |
    32768 |   4019    131 |  15410    504 |  19318    633 |

Sequential READ/WRITE [90/10] tests:

          |      1 Thread |    10 Threads |    40 Threads |
Blocksize |   IOPS   MB/s |   IOPS   MB/s |   IOPS   MB/s |
          |               |               |               |
      512 |  14278      7 |  72588     37 |  88427     45 |
     1024 |  10767     11 |  49585     50 |  73693     75 |
     2048 |   9110     18 |  34068     69 |  72447    148 |
     4096 |   7592     31 |  27516    112 |  66647    272 |
     8192 |   6271     51 |  26221    214 |  53545    438 |
    16384 |   5512     90 |  22818    373 |  33087    542 |
    32768 |   4138    135 |  16400    537 |  20735    679 |

sequential:

# dd if=/dev/zero of=/bench/xdd/S1 bs=8K count=2M
2097152+0 records in
2097152+0 records out
17179869184 bytes (17 GB) copied, 34.8562 s, 493 MB/s
# dd of=/dev/zero if=/bench/xdd/S1 bs=8K
2097152+0 records in
2097152+0 records out
17179869184 bytes (17 GB) copied, 27.2719 s, 630 MB/s
#  time cp /bench/xdd/S1 /bench/xdd/S0
real	1m8.972s
user	0m0.468s
sys	0m13.049s

More to come….

M4N iPhone app on iPad

10 February 2010

Recently, Apple announced the launch of the iPad. I downloaded the new SDK directly, to try our iPhone application. Unfortunately, it crashed immediately, without a clear error. I decided to wait for the next version, as I was not the only one with this kind of problem. Tonight, Apple released beta 2 of the SDK, so this morning I tried to run the app again. And now it works, thanks Apple!

m4n_on_ipad

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.

a hitchhikers guide to har2009.org galaxy

18 August 2009

Een kort verslag van “a hitchhikers guide through hackers galaxy:
har2009.org“…Ergens op de Nederlandse heide ver weg van de bewoonde
wereld in het bos is een land wat Har heet. Een korte sfeer impressie.

1) Je moet gewoon een “uitgeprint” ticket meenemen anders kom je het
land niet in. (Kom je daar aan met je ticket op je iphone. Dat is
zooo 2009 we leven hier in wood-galaxy man.) Maar iedereen is wel
gewoon super aardig en met kopie paspoort + telnummer en het nummer op
je ticket kom je ook binnen.

2) Ze hebben daar i.p.v. gewone chipknips en pinpasjes alleen
plastieke muntjes waar je je bier mee kan kopen en eten halen. Er is
in har-Galaxy wel een wisselkantoor. Dus je kan wel met je pinpas
plastieke muntjes kopen.

3) Mobiel bellen. Tja, .. ,gewoon via een belachelijk hoog tarief het
lokale netwerk roamen zoals je in het buitenland doet, zat er in
Galaxy land niet in. Wel gratis mobiel bellen als je dan wel even alle
beveiligings hurdels overwint. Dat lukte mij als allochtoon niet. Dan
maar gewoon een van de 10 onbeveiligde wifi netwerken kiezen en mijn
iphone werd gelijk gedeeld met de rest van har2009. Het zijn hele
aardige wezens hoor alles zullen we eerlijk delen.

4) Netwerken doen de harrers ook uitgebreid, dat doe je door met je
laptop naast elkaar in de lounge te gaan zitten en je irc chat client
(een soort msn maar dan text based) of je nog mensen tegenkomt.

5) Communiceren doe je via je t-shirt. Wat is cool? Een t-shirt dat
bewijst dat je software code kan begrijpen die zo ingewikkeld is dat
alleen jij zo intelligent bent dat je dat kan ontcijferen. Gewoon een
interessante spreuk mag ook.

6) Een quiz, ook leuk doe je zo: je krijgt een antwoord en dan moet
je de vraag zelf verzinnen.

7) Ook de presentaties zijn interessant. Je gaat daar niet naar toe,
ook al is het op 500 meter afstand. Je blijft in je tent, zet het op
de beamer met boxen aan en luistert zo mee. Ok, langs gaan is ook ok,
toegegeven soms doen aardse mensen ook goede dingen.

8) En wat is er dan zo leuk? Wat is er leuk aan lego, het in elkaar
zetten van je bouwsel en dan als het af is er naar kijken en bedenken
zo die werkt. En dan om je heen kijken wat er nog meer te doen is. Zo
ook het op een camping voor elkaar krijgen dat je volledig online kan
programmeren en door dat met elkaar te doen info uitwisselen en
bedenken wat er allemaal nog te hacken/lees programeren valt. Samen
opbouwen ervan en meehelpen is the fun.

Har2009.nl was voor mij een korte reis terug in de tijd waar internet
werd gebouwd door geeks, techneuten en software engineers die allemaal
de wereld verbeteren en waar toevallige fondsten uitgroeien tot wereld
successen maar waar ook mensen de nodige issues aan de kaak stellen,
waar de bouwstenen van onze virtuele internet wereld van gebouwd
worden. Har2009 was een geweldige ervaring.

Bijgesloten wat foto’s uit de gewone wereld op zijn commercieels om te
bewijzen dat ik er echt ben geweest en dat bovenstaande echt waar is.
Het zijn geen sprookjes.

css.php best counter