Wednesday, March 25, 2009

Net Censorship in Australia

Current the planned Australian Internet filter  and the Australian Communications and Media Authority (ACMA) are causing quite a bit of controversy. The ACMA's Internet blacklist was leaked and there were some disturbing entries on the list. Among the entries were a Queensland dentist's website, a tour operator, and after disclosing the contents, wikileaks has been added to the list.

Transparency

There are two problems with the current blacklist as it stands. Firstly, a site that links to a blacklisted or illicit site is also blacklisted. The prime example of this is wikileaks.org which was blacklisted after disclosing the ACMA's blacklist. Media outlets have also been threatened with an $11,000 a day fine for linking to banned sites. This is insanity:

  • What if you link to a site then at a later date it posts offending material?
  • What if a site is placed onto the blacklist after you've linked to it?
  • What if a user posts a black listed link onto a forum you control?
  • The link itself doesn't contain any illicit material.

It seems like a violation of free speech to prevent someone from discussing illicit material, how is linking to it any different? Of course the linking issue it the key issue being played out in music sharing cases such as the current trial for "The Pirate Bay".

Secondly, the list is secret and thus there is no accountability. The article on ComputerWorld claims that the decision to add a site to the list can be made by a single bureaucrat. Without the list being disclosed how can there be any accountability for government. They may argue that disclosing the list will provide a central point for people to look for the offending illicit material (child pornography, etc). However:

  • People know how to get to illicit material anyway. Pedophile networks can be extremely sophisticated and secure.
  • If the governments filter is put in place all those sites will be blocked anyway.

Leave it to the Experts

There is already a lot of evidence that the Internet filtering plan will not work out (including ACMA's own reports). Instead of entering into an unaccountable Internet censorship setup, I feel that we should direct the funding into our state and federal police bodies. They are already doing a great job but could use the extra support. In NSW the police have just recently been given a boost to their online powers but only with a warrant - already much more accountable than a secret list.

Further Reading

Tuesday, March 17, 2009

Interesting Links

Sunday, March 8, 2009

Java Exceptions

Checked exceptions... they cause me pain. At first glance they seem to provide a way for design by contract to include exceptions. However they only increase complexity and have limited usefulness for design by contract.

SNR

Firstly, they increase the "signal-to-noise ratio" for the code. The SNR for code determines how clear your code is (someone else coined that term - but try Google for it!). Anders Hejlsberg also talks about imperative vs declarative programming which is a similar concept. Anyway consider the following code snippets:

Update UI from non UI-thread in Java:

try
{
// Run the update code on the Swing thread
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
try
{
// Update UI value from the file system data
FileUtility f = new FileUtility();
uiComponent.setValue(f.readSomething());
}
catch (IOException e)
{
throw new IllegalStateException("Error performing file operation.", e);
}
}
}
}
catch (InterruptedException ex)
{
throw new IllegalStateException("Interrupted updating UI", ex);
}
catch (InvocationTargetException ex)
{
throw new IllegalStateException("Invocation target exception updating UI", ex");
}

Update UI from non UI-thread in C#:

private void UpdateValue()
{
// Ensure the update happens on the UI thread
if (InvokeRequired)
{
Invoke(new MethodInvoker(UpdateValue));
}
else
{
// Update UI value from the file system data
FileUtility f = new FileUtility();
uiComponent.Value = f.ReadSomething();
}
}

The UI threading code in the C# example still adds some extra noise so I like to use Postsharp to reduce it down to this:

[UIMethod]
private void UpdateValue()
{
// Update UI value from the file system data
FileUtility f = new FileUtility();
uiComponent.Value = f.ReadSomething();
}

Which seems a lot clearer to me. When you start to do more and more UI work in Swing checked exceptions start to become really annoying and useless.


Jail Break


To implement even the most basic of implementations, such as Java's List interface, checked exceptions as a tool for design by contract fall down. Consider a list that is backed by a database or a filesystem or any other implementation that throws a checked exception. The only possible implementation is to catch the checked exception and rethrow it as an unchecked exception:

public void clear()
{
try
{
backingImplementation.clear();
}
catch (CheckedBackingImplException ex)
{
throw new IllegalStateException("Error clearing underlying list.", ex);
}
}

And now you have to ask what is the point of all that code? The checked exceptions just add noise, the exception has been caught but not handled and design by contract (in terms of checked exceptions) has broken down.


Service, s'il vous plaƮt?


When the cost of checked exceptions starts to kick in (wrapping in unchecked exceptions, millions of checked exceptions) you can see code like this in response:

try
{
// Perform some action
}
catch (Exception e)
{
log.warn("Unexpected exception processing action", e);
}

The problem with this code is well documented in the .net world. Basically if you can't handle the exception then step aside.


Summary


In non-trivial situations all of the above problems compound making debugging and maintaining code harder. They add noise to the code and the usefulness as a design by contract mechanism is questionable.


Really, in Java the divide between checked exceptions and runtime exceptions should have been a red flag: some exceptions are are unexpected.  Exceptions are for exceptional circumstances and you don't always want to deal with exceptional circumstances at all levels in your code.

Tuesday, March 3, 2009

Java Suppress Finalizer

A colleague pointed my to Dr Heinz M. Kabutz's article on Java finalizers. The article compares the performance of objects that have a trivial (empty) finalizer vs those that have a very simple finalizer. The basic outcome is that the running time for the non-trivial case is orders of magnitude larger than the trivial case.

I was quite shocked when I saw this since the simple finalizer given in the example is similar to what is proposed in .net IDisposable pattern. I was thinking "Holy Smoke, Batman! How can it really be that bad??". The answer is in Jack Shirazi's article: basically the finalizer causes the object to live through the nursery collection and thus puts much more pressure on the mature space collector.

.net?

I decided to implement the test in C# quickly and see how it performed. Here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
public class ConditionalFinalizer
{
private static readonly bool DEBUG = false;

// Should be volatile as it is accessed from multiple threads.
// Thanks to Anton Muhin for pointing that out.
private volatile bool resourceClosed;
private readonly int id;

public ConditionalFinalizer(int id)
{
this.id = id;
resourceClosed = false;
}

~ConditionalFinalizer()
{
if (DEBUG)
{
if (!resourceClosed)
{
Console.Error.WriteLine("You forgot to close the resource with id " + id);
}
resourceClosed = true;
}
}

public void close()
{
resourceClosed = true;
GC.SuppressFinalize(this);
}
}

class Program
{
static void Main(string[] args)
{
// Allow the JIT to warm up
for (int i = 0; i < 10 * 1000 * 1000; i++)
{
ConditionalFinalizer cf = new ConditionalFinalizer(i);
if (i % (1000 * 1000) != 0)
{
cf.close();
}
}


DateTime start = DateTime.Now;

for (int i = 0; i < 10 * 1000 * 1000; i++)
{
ConditionalFinalizer cf = new ConditionalFinalizer(i);
if (i % (1000 * 1000) != 0)
{
cf.close();
}
}

TimeSpan time = DateTime.Now - start;
Console.WriteLine("time = " + time.TotalMilliseconds);

Console.ReadKey();
}
}
}
The most important change is the added call to "GC.SuppressFinalize". This test case is the specific reason for this call - basically it removes the object from the finalization queue thus allowing it to be collected in the nursery collection. I also added an initial loop to allow the JIT to compile the classes in use. Here are the results:

DotnetPerformance


Calling "GC.SuppressFinalize" dramatically improves the performance for .net and my initial results line up with Dr Kabutz's. Java really does a neat optimisation for the trivial finalizer case! Unfortunately it also gets smashed in the non-trivial case...


Java


Dr Kabutz's code for showing the classes pending finalization goes 90% of the way towards providing something similar to "GC.SuppressFinalize", I decided to add that last little bit:

import java.lang.ref.Reference;
import java.lang.reflect.Field;

public class FinalizeHelper {

static FinalizeHelper finalizeHelper = new FinalizeHelper();

private final Class<?> finalizerClazz;
private final Object lock;
private final Field unfinalizedField;
private final Field nextField;
private final Field prevField;
private final Field referentField;

public FinalizeHelper() {
try {
finalizerClazz = Class.forName("java.lang.ref.Finalizer");

// we need to lock on this field to avoid racing conditions
Field lockField = finalizerClazz.getDeclaredField("lock");
lockField.setAccessible(true);
lock = lockField.get(null);

// the start into the linked list of finalizers
unfinalizedField = finalizerClazz.getDeclaredField("unfinalized");
unfinalizedField.setAccessible(true);

// the next element in the linked list
nextField = finalizerClazz.getDeclaredField("next");
nextField.setAccessible(true);

// the prev element in the linked list
prevField = finalizerClazz.getDeclaredField("prev");
prevField.setAccessible(true);

// the object that the finalizer is defined on
referentField = Reference.class.getDeclaredField("referent");
referentField.setAccessible(true);

} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException("Could not create FinalizeHelper", e);
}
}

private void suppress(Object instance) {
try {
synchronized (lock) {
// Get the start of the un-finalized list
Object current = unfinalizedField.get(null);
Object previous = null;

while (current != null) {
Object value = referentField.get(current);

// Check if this entry refers to the instance we are interested in
if (value == instance) {
// Unlink the current entry from the queue
Object next = nextField.get(current);
if (previous == null) {
unfinalizedField.set(null, next);
prevField.set(next, null);
} else {
nextField.set(previous, next);
prevField.set(next, previous);
}
break;
}

// Move to the next entry
previous = current;
current = nextField.get(current);
}
}
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}

public static void suppressFinalize(Object instance) {
finalizeHelper.suppress(instance);
}
}

Here is the updated test files:

public class ConditionalFinalizer {
private static final boolean DEBUG = false;

// Should be volatile as it is accessed from multiple threads.
// Thanks to Anton Muhin for pointing that out.
private volatile boolean resourceClosed;
private final int id;

public ConditionalFinalizer(int id) {
this.id = id;
resourceClosed = false;
}

protected void finalize() throws Throwable {
if (DEBUG) {
if (!resourceClosed) {
System.err.println("You forgot to close the resource with id " + id);
}
resourceClosed = true;
super.finalize();
}
}

public void close() {
resourceClosed = true;
FinalizeHelper.suppressFinalize(this);
}
}

and:

public class ConditionalFinalizerTest1 {
public static void main(String[] args) throws InterruptedException {
long time = System.currentTimeMillis();
for (int i = 0; i < 10 * 1000 * 1000; i++) {
ConditionalFinalizer cf = new ConditionalFinalizer(i);
if (i % (1000 * 1000) != 0) {
cf.close();
}
}
time = System.currentTimeMillis() - time;
System.out.println("time = " + time);
}
}

And here are the updated results:


DotnetPerformance2


Suppressing the finalizer for those objects significantly increases the performance of the test. The difference in performance between .net and Java is probably because I'm using reflection to scan the finalizer list in the Java case.


Summary


There is a definite benefit to suppressing finalizers for object that get manually disposed, its just a pity that there is no native "GC.SuppressFinalize" method for Java. The IDiposable pattern is very useful for situations where you want to be able to:



  • Manually dispose of an item when you know it is no longer needed.
  • Be able to run clean up code to safely bring down connections, close files, etc.
  • Be able to rely on the finalizer to catch situation where it is not known when an object should be cleaned up or to catch mistakes that mean the clean code is not explicitly called.