Java

Never throw a NullPointerException. Ever.

NullPointerExceptions (NPEs) happen in Java. They indicate that the VM tried to de-reference a null - value. And that's OK. But it is not OK to write code like this:

if(someVariable == null) {
    throw new NullPointerException("The value of \"someVariable" must not be null");
}

It is not OK to write code like this for 3 reasons:

  1. As I said before, the NPE indicates that some part of the program tried to de-reference a null value. This did not happen here.
  2. The exception class you use should indicate what happened. Otherwise we would have only 2 Exception classes in Java: Exception and RuntimeException.
  3. NPEs indicate a programming error and are quite useful to find bugs. You compromise this when you throw them for "normal" errors.

As for the second point: I can think of two reasons why the null value is not allowed here. The first would be that null is an illegal value for an argument of your method. Use "IllegalArgumentException" in this case. The other reason is that a null value would cause an illegal program state. In this case you can use "IllegalStateException". If both scenarios do not feel right for you, create your own exception class.

(Just another rant. Everything IMHO. This post is somewhat related to Exception Abuse. And yes, there is a reason why I wrote this.)

JSXP 0.3 Released

We have just released Version 0.3 of the JSXP web framework for java. The main improvement is the new validation architecture, and some minor bug fixes.

JSXP Community Pages

We have just created a new JSXP community website: jsxpcommunity.org. So far it hosts several JSXP-related forums and the project mailing lists. There might be more content in the future.

JSXP 0.2 Released

We have just released version 0.2 of JSXP - the simple web framework for Java. This release contains great improvements in the view flows implementations, and some minor bug fixes.

JSXP 0.1

Oliver Szymanski and I released JSXP 0.1 today. JSXP is a web application framework for Java. It's main features are: Compile-time safety when accessing elements of the pages, simple XHTML design, component orientation, human readable URLs, automatic server side state, and more.

Openbakery Translation Engine 0.2 released

I have just released the second version of the openbakery translation engine, which contains major feature enhancements:

  • Added support for multiple properties files: Now all properties files for the given locale are searched for translations (important for larger projects).
  • Better support for hierarchical locales: TranslationChecker now creates a list of indirectly defined translations.
  • Multiple calls to initialize are now allowed: All translations from all referenced properties files are searched when translating a string.
  • Enhanced output of TranslationChecker: It now tells you where it found a translation (the class or the properties file).

You can find a detailed example at the project page of openbakery translation.

Openbakery Translation Engine 0.1 released

Yesterday and today I created a translation engine for java which has several advantages over the default i18n using resource bundles:

  • The text in the default locale is the key for the translation
  • There is no properties file for the default locale, only for translations
  • There is a tool which analyzes a source tree and finds all translations which are missing in a certain properties file
  • This tool also finds entries in the properties file which are not used anymore and can be removed

Usage is really simple, you just call a static "translate" - method:

translate("This string should be translated"); //Simple translation
translate("This string has parameters: {0} and {1}", "Foo", "Bar"); //Translations can be parameterized
translate(File.class, "Open"); //Translations can have a context, which is the name of a Java class

You can find a complete example, download links, the bug tracker, and other information on the project page at openbakery.org. There is also a freshmeat project page for the project which should be available soon.

Herbstcampus 2008

|

The last three days I was at the Herbstcampus 2008, a new Conference in Nürnberg (Germany), and it was really great. I am right next to James Gosling on the Speaker Foto ;)

I did only one talk, except that I didn't talk ;) - I was the programmer in the .NET session of the technology tournament. The tournament was about creating a newsletter application with a certain technology (.NET, Java EE, Java+Spring+Hibernat, Ruby on Rails an Ercatons). All the coding had to be done live in 70 Minutes, the only set up we ware allowed to prepare was the development environment. Oliver Szymanski and I did the .NET session and it was great - I think I'll present our solution here on this blog because we used COM+ Serviced Components as Webservices, and we didn't find a comprehensive tutorial on how to do this on the net (especially when it comes to errors and what the error messages mean).

The other talks were pretty cool too, especially the ones from James Gosling and Dirk Prims (an Evangelist from Microsoft Germany) who gave a pretty interesting talk about security and tricks how crackers can exploit certain programming errors. The whole conference was pretty cool, but there were some things which were a little bit annoying: Errors in the Schedule, Chaos at the meals (which were not very good). Anyway, it was the first time for the organizers, and I guess they'll learn for the next time.

You can read more about the campus (and Java and .NET programming in general) in the blog source-knights.com.

Java Myth: Optimization using Exceptions instead of control structures

Just about once a year I meet sombody who says that one can optimize certain things (like for-loops or equals-methods) in Java using Exceptions instead of the normal control structures. I always try to tell them that they are wrong, using arguments like "Exception handling is painfully slow" or "you just have prevented the JIT to perform an important optimization", but most of the times I fail to convince them. By the way, I still think the most important argument against such "optimizations" is Use Exceptions only when an error has occured.

I have written some small benchmarks which demonstrate some interesting points. All timing measurements were done using YourKit Java Profiler 6.0.16, the program was running in Java 1.5.0_07 on a MacBook Pro (OS X 10.4.10). If you find any mistakes I made please email me (mail-at-davidtanzer-dot-net) - unfortunately I had to disable anonymous comments because of comment spam.

I did all the for loop tests with ARRAY_LENGTH=10 000 000 (JIT) and ARRAY_LENGTH=1 000 000 (JIT and Interpreter Only: -Xint), the Exception benchmarks were only done with the "Small" array length.

The argument for the optimization I want to debunk here goes like this:

For loops which iterate over an array waste lots of time

...because the array length is checke twice - int the for - condition and during each array element access. We could simply eliminate the check in the loop condition and wait for the ArrayIndexOutOfBoundsException which must be faster for large arrays:

	private int f(int i) {
		return i;
	}

	private void testForLoop() {
		int[] array = new int[ARRAY_LENGTH];
		
		for(int i=0; i<array.length; i++) {
			array[i] = f(i);
		}
	}

	private void testForLoopException() {
		int[] array = new int[ARRAY_LENGTH];
		
		try {
			for(int i=0;; i++) {
				array[i] = f(i);
			}
		} catch(ArrayIndexOutOfBoundsException e) {
			//Obviously the loop is finished. Or a real error has occured, we can't know that.
		}
	}
Test 10 000 000 1 000 000 1 000 000 (Interpreter only
testForLoop 113 ms not measurable 21 ms
testForLoopException 128 ms 21 ms 23 ms

I have made a second benchmark which invokes the 2 methods 100 times to see if the JIT optimizes the loops better when they become a hot spot:

Test 10 000 000 1 000 000 1 000 000 (Interpreter only
testManyForLoops 6835 ms 706 ms 2161 ms
testManyForLoopsException 7614 ms 761 ms 2206 ms

We see here that the Exception version is always slower.

...but exception handling is fast, creating the Exceptions is slow

...so if we could speed up Exception creation we could really optimize things this time. Well, this is also not true. While exception handling in Java causes no runtime overhead as long as everything works, It takes quite some time to find and invoke the exception handler:

	private void createAndThrowExceptions() {
		for(int i=0; i<ARRAY_LENGTH; i++) {
			try {
				throwException();
			} catch(ArrayIndexOutOfBoundsException e) {
				//Empty
			}
		}
	}

	private void throwException() {
		throw new ArrayIndexOutOfBoundsException(Integer.toString(0));
	}

	private void createExceptions() {
		for(int i=0; i<ARRAY_LENGTH; i++) {
			//The message of an AIOOBE is the index which was out of bounds
			Exception e = new ArrayIndexOutOfBoundsException(Integer.toString(0));
		}
	}
Test 10 000 000 1 000 000 1 000 000 (Interpreter only
createExceptions x 5599 ms 6577 ms
createAndThrowExceptions x 14497 ms 15906 ms

So again, throwing and catching takes up most of the time.

...but still we waste time during creation

...because the slowest thing when creating exceptions is filling in the stack trace.

	private class MyException extends Exception {
		private static final long serialVersionUID = 1L;
		@Override
		public synchronized Throwable fillInStackTrace() {
			return this;
		}
		public MyException() {
			super();
		}
		public MyException(String arg0, Throwable arg1) {
			super(arg0, arg1);
		}
		public MyException(String arg0) {
			super(arg0);
		}
		public MyException(Throwable arg0) {
			super(arg0);
		}
	}

	private void createExceptionsWithoutStacktrace() {
		for(int i=0; i<ARRAY_LENGTH; i++) {
			//The message of an AIOOBE is the index which was out of bounds
			Exception e = new MyException(Integer.toString(0));
		}
	}
Test 10 000 000 1 000 000 1 000 000 (Interpreter only
createExceptions x 5599 ms 6577 ms
createExceptionsWithoutStacktrace x 4539 ms 5549 ms

So here we have not saved much time and have completely lost the stack trace. Not a good thing, IMHO.

Conclustion

Don't use exceptions for optimization. Don't try to be smarter than the JIT.

ExceptionLargeSet
ExceptionSmallSet
ExceptionLargeSet - Interpreter Only

Exception Abuse (or: When should I use Exceptions and when is it better to use something else)

| |

Ok, here comes another rant. I always thought this topic should be really obvious for anyone who does object oriented programming, but I've seen it done wrong so often in the last year that I thought I'll write about it now. First let me post an example of how not to do it:

//somewhere in a method which checks some values...
try {
    isObjectValid(object);
} catch(Exception e) {
    //Do some stuff you have to do if the object was not valid, and then
    //continue in the program.
}

//and here the isObjectValid method:
void isObjectValid(SomeType object) throws Exception {
    if(!(...check the object...)) {
        throw new Exception("Object is not valid: [reason]");
    }
}

First, let me tell you that I have really seen methods like this in Production systems. Different productions systems from different vendors. Now, there are 2 things wrong with the isObjectValid method:

  • The "is" prefix should only be used for methods which return a boolean. But that's not a big issue, it just doesn't fell right
  • More important, the method uses an exception in a case where no error has occured

Now, when should one use Exceptions? And when is it better to check a return value of a method for "null" or "false"? The answer is:

Exceptions are for handling program errors. And nothing else

There are two main reasons why I wrote the answer like this:

(1) Exception handling is not efficient. It does not have to be. When something went wrong and all that's left for to do the VM is report the error it has plenty of time. Remember, every time an Exception is thrown, the following occurs:

  • The object is created on the heap. That does not take too much time, but it has to be done.
  • The constructors of Exception and Throwable are invoked, and this cases fillInStackTrace() to be invoked
  • The VM has to find the corresponding catch block, and invoke the code in it
  • After that there is an unreferenced object which potentially reduces the time until the next garbage collection (ok, not a big issue, but anyway).

(2) Most developers expect exceptions to occur when something has gone so wrong that the method which has thrown the excecption can not finish it's task. And rightly so. Because this is what exceptions are for.

You might also interested in this article by Rene which is about the abuse of "null". He writes about a similar problem: Methods that simply return "null" instead of throwing an exception when something has fundamentally gone wrong. Also bad. Very bad.

Syndicate content