Mittwoch, 9. Oktober 2013

Checked Exceptions vs Interfaces

So genannte "Checked Exceptions" sind Ausnahmen in Java, die auf jeden Fall vom Programmierer behandelt werden müssen. Tut er das nicht, wirft der Compiler einen Fehler und verweigert die Übersetzung. Am Konzept der Checked Exceptions gibt es reichlich Kritikpunkte. Java selbst versucht in dem entsprechenden Tutorial das Konzept zu verteidigen. Besonders pikant ist aber, dass das Konzept der Checked Exceptions in Widerspruch steht zu einem anderen Konzept von Java und zwar den "Interfaces". Bei einem Interface handelt es sich um eine abstrakte Spezifikation eines Verhaltens, das unabhängig von der Art der Implementation ist. Das Interface weiß also nichts darüber, wie es implementiert sein könnte. Somit kann das Interface auch nicht wissen, ob bei einer Implementation eine Ausnahme auftreten kann und wenn ja welche. Das wiederum bedeutet, dass ein Interface gar keine Ausnahmebehandlung vorsehen kann, da dem Interface gar nicht klar sein kann, welche Fehler bei der jeweiligen Implementation auftreten könnten.

Java definiert seit der Version 1.5 das Interface "Appendable". Dieses Interface spezifiziert den Vorgang des Anhängens einer Zeichenkette an ein Objekt mittels der Methode append. Merkwürdigerweise sind alle drei Varianten von append so definiert, dass sie eine IOException werfen können. Das wirft die Frage auf, woher das Interface weiß, dass bei seiner Implementation eine IOException auftreten kann, obwohl der Sinn eines Interfaces darin besteht, dies gar nicht wissen zu dürfen? Die Antwort liegt in der hellseherischen Fähigkeit dieses Interface. Bei der Definition des Interfaces ging man davon aus, dass es mal eine Implementation geben könne, die beim Vorgang des Anhängens eine IO-Operation ausführen müsste. Und genau das würde das Entstehen einer IOException ermöglichen. Wenn man also vom Konzept der Checked Exceptions nicht abrücken will, muss man das Interface so gestalten, dass alle theoretisch denkbaren Checked Exceptions vorhergesehen werden um sie im Interface definieren zu können. Ein derartiges Anliegen ist natürlich völliger Unsinn.

Ergebnis dieses konzeptionellen Widerspruchs ist, dass man das Interface Appendable mit eigenen Checked Exceptions, die die Designer von Java leider nicht vorhergesehen haben, gar nicht implementieren kann. Das wiederum bedeutet, dass man in einer Implementation von Appendable alle Checked Exceptions in Unchecked Exceptions umwandeln muss. Und das wirf dann die Frage auf: wozu das eigentlich? Insbesondere wenn man sich vor Augen führt, dass Appendable kein Einzelfall ist. Das Problem tritt in gleicher Weise beim Iterator auf. Und obwohl der Iterator schon seit Version 1.2 mit an Bord ist, war man damals immerhin so schlau, sich die Blöße mit der IOException gar nicht erst zu geben. Das Iterator-Interface definiert keine implementationsspezifischen Ausnahmen, obwohl natürlich sonnenklar ist, dass auch beim Iterieren IOExceptions auftreten können.

Am Ende stellt sich dann die Frage: auf was will man lieber verzichten: Interfaces oder Checked Exceptions? Ich für meinen Teil bin der Meinung, wer Checked Exceptions benutzt ist selber Schuld.

Dienstag, 8. Oktober 2013

Java inherits Common Lisp´s name spaces

Java puts classes and variables in different name spaces. This is a bit like Common Lisp where functions have also their own name space. Common Lisp has been criticized for this and has been called ugly. Oracle´s Java 1.7 does it the same and compiles the following example without any complain:
class names
{
  public static void main (String[] args)
  {
    names names = new names();
  }
}

Freitag, 16. August 2013

Startpage als Standard-Suchmaschine in älterem Firefox

Unser aller Held Edward Snowden hat uns nahe gelegt, deutlich mehr Augenmerk auf Datenschutz und Datensicherheit zu legen. Für mich fängt das mit der Google-Suche an. Glücklicherweise gibt es einen Anbieter namens ixquick, der die Google-Suche anonymisiert und unter dem Namen Startpage anbietet. Um die Suchmaschine im Browser zu nutzen gibt es für Firefox eine Search-Engine-Definition.

Beruflich bin ich aber gezwungen eine ältere Firefox-Version zu nutzen. Die hat das Problem, dass die Suche über die URL-Eingabe unabhängig von der Suche über das Sucheingabefeld konfiguriert wird. Die Lösung für das Problem findet sich in der Knowledgebase von Startpage. Man muss lediglich auf der about:config-Seite die Option keyword.URL parametrisieren.

Trägt man dort den folgenden Wert ein, klappt die Suche auch über die URL-Zeile:

https://startpage.com/do/search?language=german&cat=web&query=

Samstag, 20. Juli 2013

Android's Package Download

Recently I have asked on several forums (XDA Developer, Stackexchange) how the Android package download works. I got no useful answer. First the bone heads at Android Enthusiasts did not understand my questions and after they got it, they closed the questions, because the topic has nothing to do with Android (roflpimp). At XDA Developer I was not able to ask the question in the right section, because I had not written enough junk to be qualified for the right sections.

You see I had to figure it out on myself. I configured an ALIX board as an wireless access point connected my old Cyanogen 7 Defy and started an update. I captured the traffic with Tshark and analyzed it with Wireshark.

The Android 2 client does two requests for a package update. The first request gets answered by an redirect and the second starts the download. This is the first request.

And this is the second.

First the client contacts the host android.clients.google.com and requests something from /market/download/ and after that the client contacts some random host in a probably random sub domain below android.clients.google.com and requests something from /market/GetBinary/. The traffic is not encrypted. This makes to possible to block the package download without breaking other Google services.

This is an example configuration for Squid.

acl apps url_regex "/etc/squid3/apps.url"
http_access deny apps
deny_info TCP_RESET apps

The file with the regular expression contains only one entry.

android\.clients\.google\.com/market/(download|GetBinary)/

Successful blocks are marked as TCP_DENIED in the log file.

1374352802.189      0 192.168.3.27 TCP_DENIED/403 0 GET http://android.clients.google.com/market/download/Download? - NONE/- text/html

Donnerstag, 11. Juli 2013

Renaming inheritance relations with Rhino in Oracle´s SQL Data Modeler

The default naming rule for inheritance relations is a simple enumeration.

  • Hierarchy_1
  • Hierarchy_2
  • and so on...

Recently I had the problem to clean up an existing model. This can be done by hand but it is a very annoying job. Oracle´s SQL Data Modeler includes Mozillas Rhino engine to perform automatic tasks on the model. It is much more convenient to unify the relation names by a script. The following script does the job.

var entities = model.getEntitySet().toArray();
for (var e = 0; e < entities.length; e++) {
    var entity = entities[e];
    if (entity.isInheriting()) {
        var relation = entity.getInheritanceRelation();
        var source = relation.getSourceEntity().getName();
        var target = relation.getTargetEntity().getName();
        relation.setName(source + "_" + target + "_ih");
        relation.setDirty(true);
    }
}

The new names are created by the name of the source entity and the name of the target entity separated by an underline and suffixed by "ih".

The documentation of the classes and methods available from JavaScript is quite limited. But the file datamodeler/xmlmetadata/doc/index.html in the Data Modeler package list all of them and it is possible to use the debugger repl to test their functionality.

Mittwoch, 10. Juli 2013

Abuse inheritance for embedding with SQL Developer

Creating relational models in SQL is often a very annoying job, because of the limited expressiveness of the relational model. Thanks to PostgreSQL it is possible to create inheritance relationships between different entities. But the object oriented world spurns more and more inheritance. Inheritance was invented to reuse code but after Barbara Liskov formulated her substitution principle most object oriented disciples bless embedding instead of inheritance. Evangelists like Google´s Go banish inheritance at all and allow only embedding.

Never the less Oracle´s SQL Developer does not know anything about embedding and provides only single inheritance. The following example shows how to use this for embedding. I would like to created objects in my database which timestamps. A "creatable" should have a create time stamp, a "deletable" should have an additional delete time stamp and a "modifyable" should add a third time stamp. This is the logical model:

The engineering strategy "one table per child" results in a relational model with only one table.

The attributes of all ancestors are merged into the table. Whenever I need the three time stamps I can specify the inheritance without the need to add them manually to the entity.

But one thing is still annoying. The columns are prefixed with the abstract table names, which leads to unnecessary redundancy in the name of the columns. I did not find a way to suppress this naming style but I found a way to fix the names by writing a custom transformation script. SQL Developer embeds Mozilla´s Rhino engine, which provides a way to manipulate the engineered model. The following script removes the table prefixes from the three columns.

function set_name (object, name)
{
    object.setName(name);
    object.setDirty(true);
}

tables = model.getTableSet().toArray();
for (var t = 0; t<tables.length;t++) {
    table = tables[t];
    tname = table.getName();
    columns = table.getElements();
    for (var c = 0; c < columns.length; c++) {
        column = columns[c];
        cname = column.getName();
        if (m = cname.match(/.+_((CREATE|DELETE|MODIFY)_TS)$/))
            set_name(column, m[1]);
    }
}

Freitag, 5. Juli 2013

instanceof in Java

Javas instanceof Operator ist nicht nur wahr für die Klasse der ein Objekt angehört sondern auch für sämtliche Elternklassen. Das folgende Beispiel
class instance
{
  static class A {}
  static class B extends A {}

  static<T> void println(T arg) { System.out.println(arg); }

  public static void main (String[] args)
  {
    A a = new A();
    B b = new B();
    A c = b;

    println (a instanceof A);
    println (a instanceof B);
    println (b instanceof A);
    println (b instanceof B);
    println (c instanceof A);
    println (c instanceof B);
  }
}
generiert die folgende Ausgabe:
$ javac -cp . -Xlint:unchecked instance.java && java instance
true
false
true
true
true
true
Lediglich Objekte der Elternklasse sind keine Instanz einer Kindklasse.