Better exception handling in Java 7 : Multicatch and final rethrow

I'm happy to announce that an other improvement from the Project Coin has be marked for inclusion in Java 7 : Improved Exception Handling for Java, from Neal Gafter. This has been announced by Joe Darcy on his blog.

This improvement add two litlte improvements to exception handling :

  • Multicatch : You'll now be able to catch multi exceptions type in one catch block
  • Final Rethow : Allows you to catch an exception type and it's subtype and rethrow it without having to add a throws clause to the method signature.

Often, we have that kind of code :

} catch (FirstException ex) {
     logger.error(ex);
     throw ex;
} catch (SecondException ex) {
     logger.error(ex);
     throw ex;
}

But that code is heavy for nothing really interesting. A solution is to find a common supertype of these two exceptions type and catch just that type and rethrow it. But that can catch more exceptions than you want.

So now, with that new feature, you can do :

} catch (FirstException | SecondException ex) {
     logger.error(ex);
    throw ex;
}

A lot more cleaner, isn't it ?

And the second improvement is a little more complicated. Imagine that you want to catch all exceptions, make several operations and then rethrow it. The code isn't hard to make, but the big problem is that you must add a throws clause to your method signature to manage the new exception launched by your code and this is not the objective. Now, you can do that without adding an exception throws clause :

try {
     // some code
} catch (final Throwable ex) {
     // some more code
    throw ex;
}

Using the final keyword it allows you to throw an exception of the exact dynamic type that will be throwed. So if an IOException occurs, an IOException will be throwed. Of course, you have to declare the exceptions not caught. You throws clauses will exactly the same if you use the code (in //some code) without catching anything but now you can do something if that happens.

I think multi-catch is a great feature, but for me the final rethrow is not often useful for programmers and perhaps a little weird using the final keyword.

JTheque licensed under Apache License 2.0

I decided to change the licence of all the JTheque Projects (The Core, the Utils and all the applications) to Apache Licence 2.0. The current license was GNU GPL V3.

I wanted to remove the copyleft clause of the GPL License to make the use of JTheque more simple and more open. For me the copyleft is not really important, I need only the copyright clause.

So, all the next versions of one of the JTheque Projects will now be made available under the Terms of the Apache License 2.0.

Tip : How to switch from KUbuntu to Ubuntu

After installed the new version of KUbuntu Lucid Lynx, I have changed the display manager from KDE (KUbuntu) to Gnome (Ubuntu).

This is easier than we could think.

The first thing to do is to install the Ubuntu desktop :

sudo apt-get install ubuntu-desktop

That will install the Ubuntu Display Manager. You'll be asked for the Display Manager to use, choose gdm (Gnome Display Manager).

After that, you'll have the Gnome Display Manager, but you've also all the applications of the KUbuntu Desktop distribution.

To remove them, you can use this command :

sudo apt-get remove akonadi-server akregator amarok amarok-common amarok-utils apport-kde apturl-kde ark cdrdao dolphin dragonplayer exiv2 foomatic-db-gutenprint freespacenotifier gdebi-kde gnupg-agent gtk2-engines-qtcurve gwenview hpijs-ppds ibus-qt4 icoutils ijsgutenprint install-package jockey-kde k3b k3b-data kaddressbook kamera kate kbluetooth kcalc kcm-gtk kcm-touchpad kde-window-manager kde-zeroconf kdebase-bin kdebase-data kdebase-plasma kdebase-runtime kdebase-runtime-data kdebase-workspace kdebase-workspace-bin kdebase-workspace-data kdebase-workspace-kgreet-plugins kdegraphics-strigi-plugins kdelibs-bin kdelibs5 kdelibs5-data kdemultimedia-kio-plugins kdepasswd kdepim-groupware kdepim-kresources kdepim-runtime kdepim-strigi-plugins kdepim-wizards kdepimlibs-data kdepimlibs5 kdesudo kdm kfind khelpcenter4 klipper kmag kmail kmix kmousetool knm-runtime knotes konqueror konqueror-nsplugins konqueror-plugin-searchbar konsole kontact kopete kopete-message-indicator korganizer kpackagekit kppp krdc krfb krosspython ksnapshot ksysguard ksysguardd ksystemlog ktimetracker ktorrent ktorrent-data kubuntu-debug-installer kubuntu-default-settings kubuntu-desktop kubuntu-docs kubuntu-firefox-installer kubuntu-konqueror-shortcuts kubuntu-notification-helper kvkbd kwalletmanager language-selector-qt libakonadiprivate1 libao2 libattica0 libaudio2 libboost-program-options1.40.0 libclucene0ldbl libdbusmenu-qt2 libepub0 libexiv2-6 libflac++6 libibus-qt1 libindicate-qt0 libiodbc2 libk3b6 libkcddb4 libkdcraw8 libkdecorations4 libkdepim4 libkephal4 libkexiv2-8 libkfontinst4 libkipi7 libkleo4 libkonq5 libkonq5-templates libkonqsidebarplugin4 libkopete4 libkpgp4 libkscreensaver5 libksgrd4 libksieve4 libksignalplotter4 libkwineffects1 libkworkspace4 liblastfm0 libmimelib4 libmng1 libmodplug0c2 libmpcdec3 libmsn0.3 libmysqlclient16 libokularcore1 libotr2 libpackagekit-glib2-12 libpackagekit-qt-12 libphonon4 libplasma-applet-system-monitor4 libplasma-geolocation-interface4 libplasma3 libplasmaclock4 libplasmagenericshell4 libpolkit-qt-1-0 libpoppler-qt4-3 libprocesscore4 libprocessui4 libqca2 libqca2-plugin-ossl libqimageblitz4 libqt4-assistant libqt4-dbus libqt4-designer libqt4-help libqt4-network libqt4-opengl libqt4-qt3support libqt4-script libqt4-scripttools libqt4-sql libqt4-sql-mysql libqt4-sql-sqlite libqt4-svg libqt4-test libqt4-webkit libqt4-xml libqt4-xmlpatterns libqtcore4 libqtgui4 libqtscript4-core libqtscript4-gui libqtscript4-network libqtscript4-sql libqtscript4-uitools libqtscript4-xml libsolidcontrol4 libsolidcontrolifaces4 libsoprano4 libssh-4 libstreamanalyzer0 libstreams0 libtag-extras1 libtaskmanager4 libvncserver0 libweather-ion4 libxcb-shape0 libxcb-shm0 libxcb-xv0 libxine1 libxine1-bin libxine1-console libxine1-misc-plugins libxine1-x libzip1 mysql-client-core-5.1 mysql-common mysql-server-core-5.1 network-manager-kde okular okular-extra-backends openoffice.org-kde openoffice.org-style-oxygen oxygen-cursor-theme oxygen-icon-theme oxygen-icon-theme-complete packagekit packagekit-backend-apt phonon phonon-backend-xine pinentry-gtk2 pinentry-qt4 plasma-dataengines-addons plasma-dataengines-workspace plasma-desktop plasma-scriptengine-javascript plasma-scriptengine-python plasma-widget-facebook plasma-widget-folderview plasma-widget-kimpanel plasma-widget-kimpanel-backend-ibus plasma-widget-kubuntu-feedback plasma-widget-message-indicator plasma-widget-quickaccess plasma-widgets-addons plasma-widgets-workspace plymouth-theme-kubuntu-logo polkit-kde-1 printer-applet python-kde4 python-packagekit python-qt4 python-qt4-dbus python-sip quassel quassel-data shared-desktop-ontologies software-properties-kde soprano-daemon system-config-printer-kde systemsettings ttf-dejavu ttf-dejavu-extra update-manager-kde usb-creator-kde userconfig virtuoso-nepomuk

If you're under Karmic Koala (9.10), you must use this command :

sudo apt-get remove akonadi-server akregator amarok amarok-common amarok-utils apport-kde apturl-kde ark cdrdao dolphin dragonplayer exiv2 foomatic-db-gutenprint gdebi-kde gnupg-agent gtk2-engines-qtcurve gwenview hpijs-ppds ibus-qt4 ijsgutenprint imagemagick install-package jockey-kde k3b k3b-data kaddressbook kamera kate kcm-gtk kde-icons-oxygen kde-style-qtcurve kde-window-manager kde-zeroconf kdebase-bin kdebase-data kdebase-plasma kdebase-runtime kdebase-runtime-bin-kde4 kdebase-runtime-data kdebase-runtime-data-common kdebase-workspace-bin kdebase-workspace-data kdebase-workspace-kgreet-plugins kdebase-workspace-libs4+5 kdebluetooth kdegraphics-strigi-plugins kdelibs-bin kdelibs5 kdelibs5-data kdemultimedia-kio-plugins kdepasswd kdepim-groupware kdepim-kresources kdepim-runtime kdepim-runtime-data kdepim-runtime-libs4 kdepim-strigi-plugins kdepim-wizards kdepimlibs-data kdepimlibs5 kdesudo kdm kfind khelpcenter4 kipi-plugins klipper kmag kmail kmix kmousetool knotes konq-plugins konq-plugins-l10n konqueror konqueror-nsplugins konqueror-plugin-searchbar konqueror-plugins konsole kontact kopete korganizer kpackagekit kppp krdc krfb ksnapshot ksysguard ksysguardd ksystemlog ktimetracker ktorrent ktorrent-data kubuntu-artwork-usplash kubuntu-default-settings kubuntu-desktop kubuntu-docs kubuntu-firefox-installer kubuntu-konqueror-shortcuts kvkbd kwalletmanager kwin-style-qtcurve language-selector-qt libakonadiprivate1 libao2 libaudio2 libboost-program-options1.38.0 libclucene0ldbl libepub0 libexiv2-5 libfftw3-3 libflac++6 libindicate-qt0 libjpeg-progs libk3b6 libkabcommon4 libkcddb4 libkdcraw7 libkdecorations4 libkdepim4 libkexiv2-7 libkipi6 libkleo4 libknotificationitem1 libkonq5 libkonq5-templates libkonqsidebarplugin4 libkontactinterfaces4 libkopete4 libkorundum4-ruby1.8 libkpgp4 libksane0 libksieve4 libkwineffects1 liblancelot0 liblastfm0 liblzma0 libmimelib4 libmodplug0c2 libmpcdec3 libmsn0.1 libokularcore1 libotr2 libpackagekit-glib11 libpackagekit-qt11 libplasma3 libpolkit-dbus2 libpolkit-grant2 libpolkit-qt0 libpolkit2 libpoppler-qt4-3 libqca2 libqca2-plugin-ossl libqimageblitz4 libqscintilla2-5 libqt4-assistant libqt4-dbus libqt4-designer libqt4-help libqt4-network libqt4-opengl libqt4-phonon libqt4-qt3support libqt4-ruby1.8 libqt4-script libqt4-scripttools libqt4-sql libqt4-sql-mysql libqt4-sql-sqlite libqt4-svg libqt4-test libqt4-webkit libqt4-xml libqt4-xmlpatterns libqtcore4 libqtgui4 libqtscript4-core libqtscript4-gui libqtscript4-network libqtscript4-sql libqtscript4-uitools libqtscript4-xml libruby1.8 libscim8c2a libsmokekde4-2 libsmokeqt4-2 libsoprano4 libstreamanalyzer0 libstreams0 libstrigiqtdbusclient0 libtag-extras1 libtidy-0.99-0 libvncserver0 libxcb-shape0 libxcb-shm0 libxcb-xv0 libxine1 libxine1-bin libxine1-console libxine1-misc-plugins libxine1-x libzip1 mysql-server-core-5.1 okular okular-extra-backends openoffice.org-kde openoffice.org-style-oxygen oxygen-cursor-theme packagekit packagekit-backend-apt phonon-backend-xine pinentry-gtk2 pinentry-qt4 plasma-dataengines-addons plasma-dataengines-workspace plasma-scriptengine-python plasma-widget-facebook plasma-widget-folderview plasma-widget-googlecalendar plasma-widget-indicatordisplay plasma-widget-kimpanel plasma-widget-kubuntu-qa-feedback plasma-widget-lancelot plasma-widget-networkmanagement plasma-widget-quickaccess plasma-widgets-addons plasma-widgets-workspace policykit printer-applet python-kde4 python-packagekit python-qt4 python-qt4-dbus python-sip4 quassel quassel-data ruby ruby1.8 software-properties-kde soprano-daemon speedcrunch system-config-printer-kde systemsettings ttf-arphic-uming ttf-dejavu ttf-dejavu-extra update-manager-kde update-notifier-kde usb-creator-kde userconfig

I hope that will be useful to someone :)

Improve performances of WordPress with W3 Total Cache

Performances of a website is often a hot topic. That's not always easy to create quick websites with low response time and without high server usage.

WordPress is not very slow but when you've a lot of readers (this is not really my case :) ) at the same time, the response time can be critical.

But there is some ways to improve very easily the performances of a WordPress website using some plugins. There is a lot of plugins to do that in WordPress, but the one I'm going to introduce is the one which I found the best.

I will talk about W3 Total Cache from Frederick Townes.

Read more…

First build of JTheque with Sonar 2.0

This week-end I updated the version of Sonar to the new version 2.0 and migrated it from Tomcat 5.5 to Tomcat 6.0. I waited until now for the plugins I use to be compatible. Now, all my plugins are compatible :

  • Motion Chart : An elegant chart demonstrating the evolutions of metrics build after build
  • Quality Index : Compute a quality index for each project based on 4 axes : Coding, Complexity, Coverage and Style
  • Radiator : Display a view like the main view of all projects (all the rectangles with a lot of colors) for all the components of a project
  • Rules Meter : Indicate for each project how many rules were activated during analysis
  • SCM Activity : Compute some metrics about the SCM Activity of the project
  • TagList : Analyze some tag (@TODO, @FIXME, ...) in your code and display them in the project
  • Technical Debt : Compute a technical debt estimation for all the problems of your project
  • Timeline : Display a chart of the evolution of the metrics build after build
  • Build Stability : Display the stability of the builds on the continuous integration system

Now I made the first build of JTheque with Sonar 2.0.

At first view, there is not a lot of changes with this new version, but the main view has been a little improved and the new analysis are good. Now you've metrics about your design and about the dependencies to cut to make your design better. They added a good dependency matrix to each project.

This version works well like the older. The only things to pay attention for the update is the long time the database upgrade takes.

I've also updated Hudson to the last version and also migrated it to my Tomcat 6.0.

Ubuntu Lucid Lynx Tip : Put the window buttons to the right

In Ubuntu 10.04 (Lucid Lynx), the window buttons (minimize, maximize and close) are by default at the left of the window title like in Mac.

This is really disappoiting when you upgrade from an older version of Ubuntu to this one.

But it's really simple to solve that problem.

Open a terminal and type this command :

gconf-editor

And then go to : apps > metacity > general. You'll see here a key named button_layout with the default value of "close,minimize,maximize:". To put the buttons like in the other versions, you just have to edit this value to

:minimize,maximize,close

And then all your windows  will have the normal button order at the right of the window title bar.

If you want to include the window menu, you can change the value to :

menu:minimize,maximize,close

And you will the menu at the left before the title.

Ubuntu Lucid Lynx (10.04) is here !

Update 1 : Sadly, the released has been delayed due to a bug in the GRUB bootloader. With this Bug, Grub display only Ubuntu when you're in a multi-boot system. To make the new release faster, they decided to respin only the Ubuntu 32/64 bit desktop CDs and the Ubuntu Netbook Edition. Normally these versions will be available later today, but perhaps tomorrow. The others versions will follow later.

Update 2 : Finally the download is available :)

The new version of Ubuntu at just been released today : Ubuntu Lucid Lynx 10.04

This version is a LTS (Long Term Support) version. So you've three years of technical support for the Desktop version and five years for the Server.

So here are the main news of Lucid Lynx :

Read more…

How to write correct benchmarks

Several months ago, I wrote an article to compare the performances of short indexes for loops. I wrote that code to achieve my goal :

package com.wicht.old;

public class TestShortInt {
    public static void main(String[] args){
        long startTime = System.nanoTime();

        int resultInt = 0;

        for (int i = 0; i < 100000; i++){
            for (int j = 0; j < 32760; j++){
                resultInt += i * j;
            }
        }

        System.out.println("Temp pour int : " + (System.nanoTime() - startTime) / 1000000 + " ms");

        startTime = System.nanoTime();

        int resultShort = 0;

        for (int k = 0; k < 100000; k++){
            for (short f = 0; f < 32760; f++){
                resultShort += k * f;
            }
        }

        System.out.println("Temp pour short : " + (System.nanoTime() - startTime) / 1000000 + " ms");

        System.out.println(resultInt);
        System.out.println(resultShort);
    }
}

And i found as a result that short was two times slower than int and I was convinced of these results until a week ago.

At this time, a reader (Jean) criticized the results of my tests and gave me links to several articles about micro-benchmarking. I've read these articles and understand why my results were incorrect.

In fact, my test doesn't pay attention to several things that can change results of tests :

  • JVM warmup : Due to several parameters, the code is first often slow and becomes faster and faster when the execution time grows until it goes to steady-state.
  • Class loading : The first time you launch a benchmark, all the used classes must be loaded, increasing the execution time.
  • Just In Time Compiler : When the JVM identify a hot part of the code
  • Garbage Collector : A garbage collection can happen during the benchmark and with that the time can increase a lot.

Due to all these factors, the first runs (perhaps 10 seconds of run) are slower than the other and than can make your benchmarks completely false.

So, how can we do to have good benchmarks results ?

It's really difficult, but we can have help using a benchmark framework introduced by Brent Boyer, a software developer from Elliptic Group. This framework take care of all the previously introduced factors and made good benchmarks.

The use of this framework is really simple, you just have to create a new instance of the Benchmark class passing to it a Callable or a Runnable and the test is directly launched. Here is the example with the test of short and int in loop indexes :

public class ShortIndexesLoop {
    public static void main(String[] args) {
        Callable callableInt = new Callable(){
            public Long call() throws Exception {
                long result = 0;

                for (int f = 0; f < 32760; f++){
                      result += 444;
                  }

                return result;
            }
        };

        Callable callableShort = new Callable(){
            public Long call() throws Exception {
                long result = 0;

                for (short f = 0; f < 32760; f++){
                      result += 444;
                  }

                return result;
            }
        };

        try {
            Benchmark intBenchmark = new Benchmark(callableInt);

            System.out.println("Result with int ");
            System.out.println(intBenchmark.toString());

            Benchmark shortBenchmark = new Benchmark(callableShort);

            System.out.println("Result short ");
            System.out.println(shortBenchmark.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

To get the results, you can use Benchmark.toString() or Benchmark.toStringFull() for more statistics. You can also directly access some stats like standard deviation using Benchmark.getSd() or directly with Benchmark.getStats() to get all the stats.

Here is the result with the preceding code :

Result int
first = 807.056 us, mean = 46.032 us (CI deltas: -261.393 ns, +408.932 ns), sd = 230.929 us (CI deltas: -68.201 us, +105.262 us)
Result short
first = 721.912 us, mean = 48.234 us (CI deltas: -198.625 ns, +254.774 ns), sd = 160.196 us (CI deltas: -32.764 us, +37.882 us)

As you can see, the short version is only 104.78% slower than the int. That show that the first results were completely false.

Here is the full results of the int version :

action statistics: first = 807.056 us, mean = 46.032 us (CI deltas: -261.393 ns, +408.932 ns), sd = 230.929 us (CI deltas: -68.201 us, +105.262 us) WARNING: EXECUTION TIMES HAVE EXTREME OUTLIERS, SD VALUES MAY BE INACCURATE
    ----------
    --the action statistics were calculated from block statistics
    --each block measured 32768 task executions
    --the user says that task internally performs m = 1 actions
    --then the number of actions per block measurement is a = 32768
    --block statistics: mean = 1.508 s (CI deltas: -8.565 ms, +13.400 ms), sd = 41.803 ms (CI deltas: -12.346 ms, +19.054 ms)
    --the forumla used to convert block statistics to action statistics (mean scales as 1/a, sd scales as 1/sqrt(a)) assumes that the action execution times are iid
    ----------
    --each confidence interval (CI) is reported as either +- deltas from the point estimate, or as a closed interval ([x, y])
    --each confidence interval has confidence level = 0.95
    ----------
    --EXECUTION TIMES APPEAR TO HAVE OUTLIERS
    --this was determined using the boxplot algorithm with median = 1.498 s, interquantileRange = 34.127 ms
    --3 are EXTREME (on the high side): #57 = 1.621 s, #58 = 1.647 s, #59 = 1.688 s
    --2 are mild (on the high side): #55 = 1.570 s, #56 = 1.582 s
    ----------
    --block sd values MAY NOT REFLECT TASK'S INTRINSIC VARIATION
    --guesstimate: environmental noise explains at least 55.89418621876822% of the measured sd
    ----------
    --action sd values ALMOST CERTAINLY GROSSLY INFLATED by outliers
    --they cause at least 98.95646276911543% of the measured VARIANCE according to a equi-valued outlier model
    --model quantities: a = 32768.0, muB = 1.5083895562166663, sigmaB = 0.04180264914581472, muA = 4.603239612477619E-5, sigmaA = 2.3092919283255957E-4, tMin = 0.0, muGMin = 2.3016198062388096E-5, sigmaG = 5.754049515597024E-6, cMax1 = 1252, cMax2 = 322, cMax = 322, cOutMin = 322, varOutMin = 0.0017292260645147487, muG(cOutMin) = 2.3034259031465023E-5, U(cOutMin) = 0.002363416110812895

Like you can perhaps see when you use this framework, it gives you some warnings when by example you have extreme outliers that can make the standard deviation completely false.

You can download this framework on the web page of the Elliptic Group. I found it really powerful and easy to use and I'll use it everytime I have to do a benchmark.

To conclude, I must also say that even if you use that kind of framework, you can make very bad benchmarks if you don't test the right part of the code. Here are two really interesting articles from Brent Boyer :

Maven 3.0 Beta 1 is here !

The Maven team has just announced the release of Maven 3.0-beta-1.

There is still several things to do for the final releases, but Maven 3 is now ready to go from Alpha to Beta.

If you're interested on migrating to this new version, you should have a look at this page from the Maven site : Maven 3 Compatibility Notes. This page lists all the known differences between Maven 2 and Maven 3 for compatibility purpose.

Some news of Maven 3 :

  • Complete Kernel Rewriting
  • New languages for POM : YAML and Groovy
  • POM Composition
  • Extensibility : Easier to create plugins extending an other plugin
  • Create the build at start and not step by step
  • Mercury for repositories and dependencies access
  • Maven Shell : Shell environment to execute Maven commands

You can download it here.