Wired-Space

A space made up of wires and wires.

Object-Relational-Mappers, such as Hibernate, can be a great help to the database using Java developer. “Just” design your object domain model carefully, add some annotations to the code and you can retrieve, manipulate and store your objects just like that. And with minimal boilerplate code all objects are kept nice and tidy in your database. Inheritance and aggregation/composition included. Nifty!!

However, there are some pitfalls. And there is one I fell into today for about two hours. The pit was named “transactions”.

Transactions are a major help to keep your data model in a consistent state. Cut short, a transaction is a sequence of operations that is either processed successfully or it fails and then the data model remains unchanged. No half constructed objects or dead references if handled correctly.

When trying to test my code today, I made a startling discovery. Although my operations where neatly nested inside a Hibernate transaction and when an exception was thrown the rollback() call executed as intended, the objects were already written to the database!

Checking the code over and over again I could not find the mistake. Then, looking at the transaction object’s methods I found the wasRolledBack() method, that returned true if the rollback was done properly. And I did get “true” as return value despite the fact that the transaction had changed the database. Even turning the Hibernate logging level to DEBUG only showed happy messages like:

org.hibernate.transaction.JDBCTransaction rolled back JDBC Connection

So what went wrong?

When you use Hibernate to handle your OR mapping, you configure the database connection in an configuration XML file. Besides the usual stuff like the JDBC driver class, database URL, username and such, there is one additional property:

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

This property defines what SQL “dialect” your chosen database “speaks”. Or so I thought.

As a matter of fact, it does do more. It can also define what database engine is used for the automagically created tables. And in my particular case the MySQLDialect decided to create MyISAM tables. The MyISAM database engine however does _not_ support transactions! So why oh why did I not get an exception when trying to roll back on a non-supported transaction? Even worse. Why did the wasRolledBack() method report true?

I’m not exactly sure if this is a bug in Hibernate, MySQL or if there is simply no way to properly determine if a transaction is supported or not. But I do know that this is a very annoying behaviour of the Hibernate/MySQL combination because you get no hint at all that something went wrong unless you had a look at the database yourself.

The solution is pretty simple, too. All you have to do it to set the dialect property to the correct value such as:

<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

This will make Hibernate use the InnoDB database engine when creating the tables. InnoDB does support transactions and the moment I changed the dialect, everything went smoothly as intended.

Just recently I purchased a mobile phone thats properly capable of browsing the internet, more precisely an Android phone. So far, I am in two minds about it. Using it as mobile access device to all those things like email, calendar and even blogs (writing this post on it) is quite comfortable, even given its small size. And there is also an abundance of free applications available and easily accessable. Because of the way less restrictions and costs compared to Apple’s mobile devices, I’m much more complied to give development on this a try. However… There are some things that do worry me. First of all, the horrible Bluetooth support. No Obex file transport? Thats something even my old Nokia could do. Do I really have to connect an USB cable or set up some WLAN services just to push some photos to my Desktop PC? The other main feature tht it lacks is mulitouch support. Apple sure did show how small scale devices benefit from that kind of user interaction. My hope is that we see improvment on those topics in Android 2.0 … and I hope that most current devices can be updated.

In my last blog post I mentioned that creating MP4, or rather Quicktime style files using GStreamer contains a minor problem. The MOOV atom is usually written to the end of the files, but software such as the Flash player needs that atom to be present at the file’s start if it wants to start playing before the whole file is available. This is, for example, the case when you get the video via a slow HTTP connection.

While looking for a solution, I came across Mike Melanson’s qt-faststart tool that does exactly that, moving the MOOV atom to the front of the video file. His tool was written in C and is also found in the FFMPEG source tree by now. I originally had a look at GStreamer because with its many language bindings I was able to do video transcoding in Java without having to call external command line tools. So using qt-faststart in its C written form was of little use to me. To my surprise the process of moving and adjusting the MOOV atom is not that complex and I was able to port Mike’s tool to Java pretty quickly.

And once again was annoyed by Java’s lack of unsigned byte data primitives. :( Really, processing low-level data structures in Java is not nice.

As Mike was kind enough to put his program into the public domain, I think it is just fair to do the same with the Java port. You can get the source code here.  [ Java Quicktime Faststart tool ]

The Java port is pretty straight taken from the C code, so all credit about this handy little tool should go to Mike. I hope somebody can make good use of the Java port somehow.

A few days ago, I began to have a closer look at the GStreamer library, because it seemed to be an interesting alternative to some less-than-optimal solutions for video and audio processing we use at work.

The basic concept behind GStreamer is a framework that allows the developer to assemble a media processing graph by linking elements together, that are either a data source, sink or filter. This approach allows for a wide range of application from a simple MP3 player up to a non-linear video editing application (using the GNonLin Element) .

The data flow is controlled by using capabilities applied to the connections between the pipeline elements. Each element can accept certain capabilities on its input connections and provides capabilities on its output connections. When the pipeline is activated, it negotiates if the specified capabilities can be provided by the used elements.

What really surprised me was the amount of language bindings available for GStreamer. While the library itself is written in C and uses the GLib GObject framework, there are bindings for PHP, Python, Perl, Java and others.

After giving the application development manual a quick read, it was surprisingly easy to set up a pipeline that converts a source video file into a Flash playable MP4 file.

I just had to figure out a few minor things that where not really obvious from the documentation. Or I just didn’t find them :)

The first problem was to retrieve the original video’s characteristics, such as its image dimensions. This was necessary because if I just inserted an image scaling element, the target video was rescaled without taking pixel- or display aspect ratio into any consideration. So to retrieve that information, I had to set up the pipeline and then set it to “PAUSE” state without having target video dimensions set. This forces the pipeline to negotiate all of its capabilities, or to “preroll” as it is called in the GStreamer terminology. Once done you can retrieve the negotiated capabilities from the video decoding element. Those include the width, height and the pixel aspect ratio. Now you determine the correct scaling parameters before setting the pipeline to its “NULL” state, which causes it to discard all negotiated capabilities. Finally, after applying the new scaling parameters, you set the pipeline to its “PLAYING” state to get the conversion done.

The other problem I had was less a problem of GStreamer itself, but of the Java bindings. Those bindings use the Java Native Access (JNA) to call the GStreamer library. As such the pipeline, once having its state set to a new value, runs in a separate thread. This has two implications on how to use it in the Java source code.

For one, the thread does not terminate by itself if it encounters an error or the pipeline reaches the end of its input stream.

And second, the method call that sets the pipeline to a new state is non blocking. So you might run into the end of your main method before the pipeline has finished or maybe even changed its state yet.

The solution to the first problem is to attach a couple of listeners to the pipeline’s message bus and act upon the end of stream or error messages. Otherwise the program might never terminate because the GStreamer thread does not end at all.

The second problem can be tackled by calling the getState() method of the pipeline object. This call blocks until either the pipeline returns its current (new) state or a given timeout expires.

Once I had figured this out, the program works pretty well for most videos. Those that fail are usually quite “exotic”. Yes, when you run the program in a Linux environment, WMV files are to be considered exotic :P

There is one problem I still have to solve.

H.264 encoded videos that are supposed to be played in the Adobe Flash player via HTTP download must be stored in a MP4 container format. The problem with doing a one pass write of that file is that the block containing the meta data, such as duration and seek points, is written at the end of the file. However, if this is the case, the Flash player does not start playing the video until the whole file was downloaded. The proper treatment of this problem is manipulating the MP4 file so that the metadata block is moved to the file’s front and adjust all of its stored offsets. This is called “faststart” in some programs. One MP4 multiplexing plugin of the GStreamer library supported this by writing the video into a temporary file and then move it to the final location after adjusting the metadata block. But it seems the plugin is a bit buggy. For some files the audio track just stopped after a minute or so. The other MP4 plugin does not have that problem, but it does not support faststart at all.

This might be fixed in a future version, or so I hope.

The GStreamer people divide some plugins into three packages that represent their state of quality or legal issues.

The “good” package contains all plugins that meet the developers quality criteria and don’t pose any legal issues.

The “bad” package contains plugins that seem to meet the quality standard but may have questionable legal issues.

The “ugly” package contains all the other plugins that don’t meet quality or legal standards.

Talking about legal issues, there is something that might be of interest to people who worry about the legal issues of using patented technology, such as MP3. Fluendo offers commercially licensed GStreamer plugins so that you can at least for some codecs purchase a license and use it in your product.

Overall I am really impressed with the GStreamer framework. That the plugins’ quality seem to vary is not that surprising, considering that they are provided by several different parties. The framework itself is pretty much all you need for, I’d say, most video or audio related applications. If it can deal with all the media files you throw at it, is only depending on the plugins you have installed, similar to having video codecs registered with DirectX oder Quicktime on other plattforms.

I’m pretty sure I will have some more fun with it :)

A few days ago at work we stumbled upon a bug in our system where a piece of software writes two files to a shared storage and then triggers our CMS to import those files by calling an HTTP RPC.

As one of the CMS developers reworked this import routine, he found that the import sometimes failed for no apparent reason. But whenever he put debug messages into his code, the bug seemed to go away. I’ve reads somewhere  that this could be called a “Heisenberg bug”. Bugs that change their behaviour depending on if you are watching them or not ;)

After some debugging we found that in some cases the XML file, that held metadata for the import, was empty. A quick glance over the source code showed that the following steps were processed.

  1. Copy the file that should be imported to the shared storage.
  2. Write the XML file to the same location.
  3. Call the CMS’ RPC via HTTP query.

It seemed that step 3 was executed before step 2 was fully completed. So how did this happen?

The software that generates the XML file and calls the CMS is written in Java. Doing those things in Java is very easy because you get DOM creation, manipulation, XML file export and HTTP POST queries pretty much for free from the runtime environment.

We build our own pitfall into this comfortable environment by using a BufferedWriter for writing XML output to the file. Ok, this is not a pitfall by itself. But it becomes one if you don’t take the buffer into account when thinking about the code’s runtime behaviour.

The following snippet shows the last three lines of code of step two, mentioned above:
StreamResult result = new StreamResult(out);
DOMSource source = new DOMSource(xmlDoc);
transformer.transform(source, result);

“out” is our BufferedWriter here and it was defined as a local variable.

In a non-managed runtime environment, e.g. software written in C++, “out” would have gone out of scope after the code above and as such be destroyed in one way or another. Most likely its destructor would have been called and thus having its buffers flushed.

However, in Java this is not as straightforward as that. Although “out” has gone out of scope and is not referenced anymore by any other object, it won’t be destroyed until the garbage collection’s next run.

So while “out” was still active, the XML was written to its buffer, but not yet written to the disk, when the HTTP call to the CMS was made. In turn, the CMS tried to read the still empty XML file and threw an error.

When the CMS developer added debugging output to his import code, that output delayed reading the XML file long enough so that “out” wrote its buffer to the file and everything went fine.

Two additional lines of code fixed the whole problem:

out.flush();
out.close();

Those force “out” to write its contents to the file immediately. Of course you can argue that if you are doing this, you could also just drop BufferedWriter and use non buffered output.

True enough, but this is a good example on how you should deal carefully with delayed actions such as buffered writings in a managed environment. Especially if you have some kind of distributed system.

In this particular case, just using buffered output and not manually flushing its buffers caused a racing condition.

So, if you use buffers, don’t forget to .flush() ! :)

The German “SoftwareArchitekTOUR” podcast is hosted by the publisher of the German computer magazines c’t and iX.

It just started with its first, or in this case “zeroth”, episode, introducing its speakers and giving an outlook on what topics the podcast will focus on.

The episodes will be listed on this RSS feed. “SoftwareArchitekTOUR” RSS

It seems we’ll get more of those in future.

There really is a podcast about _everything_, isn’t it?

Just now I found a podcast that has software engineering as topic. So far I only listened to one episode that dealt with design patterns and it seemed quite interesting. The podcast did not explain design patterns from ground up, but was more of a discussion about patterns, what they are and some misunderstandings about them.

Seems like a nice podcast to listen on my commute to work.

Oh, and here’s the link: Software Engineering Radio.

Recently I came across something in a software project that, translated into Java, looked like this:

Map<Object,String> map = new HashMap<Object,String>();
map.put(null, "This actually works!");
System.out.println(map.get(null));

While this looks, at least to me, very strange to begin with, reading the Java API docs on Map and some of its implementations revealed that the above code holds a few traps.

  1. Map does not make any statements about how key or value being null is handled.
  2. HashMap allows for both being null, which I wouldn’t have guessed, because what’s the hash code of null ?? HashMap has a special case handling for null keys, as a quick look at its source code showed.
  3. Other implementations like TreeMap throw “NullPointerExceptions” when key and/or value are null.

So, the above declaration of map should actually read:

HashMap<Object,String> map = new HashMap<Object,String>();

Because we assume a certain behavior of our map that the Map interface definition does not explicitly mentions.

Using interfaces is for member definitions is generally a good idea, because you can switch implementations as you see fit. The above example, however, shows that one should pay close attention to what exactly the interface defines and what is left to implementation. In this special case, using a HashMap is a requirement, so “map” should be declared as such, too.

Take a normal digital photo camera that can take 640×480 30fps video, an awesome 3D open source program (Blender) and an enthusiastic but untalented 3D wannabe artists and you get this:

I know there are quite some glitches and errors, but it was fun to create. Hopefuly, the next one will be better!

The video footage was taken at an old iron mill at “Landschaftspark Nord”, Duisburg, Germany.

I got this nice little chart linked today. It _really_ matches my experience :)

English translation:

x-Axis = Time, blue line=number of written code lines, green line= length of the “Todo” list, pink line= Grade of understanding.

Software development over time.

Simple but absolutely on spot :)