Best practices: SQL-Repositories

Nachdem ich mich nun schon zum x-ten Mal durch Logfiles wühle, mal eine kleine Anregung: Werden die SQL-Statements einer Anwendung zentral in einer Datei gehalten (SQL-Repository/Statement-Repository), lohnt es sich, zu jedem Statement einen SQL-Kommentar aufzunehmen: Was macht das Statement und aus welchem Kontext wird es aufgerufen? Diese Kommentare werden typischerweise im Log gezeigt und vereinfachen die Analyse enorm. Gleichzeitig sinkt die Fehlerwahrscheinlichkeit bei Korrekturen durch allgemeines Verständnis. Was für das Anwendungsprogramm gilt, muss auch für Statements gelten: DOKU OR DIE!

Bei Statements empfiehlt sich die Kommentierung mit “/*” und “*/”, da der gebräuchlichere Einzellenkommentar mit “- -” ein blockweises Auskommentieren in XML-Dateien verhindert.

Java Webstart (JWS) Remote debugging

Nach blöder Rumprobiererei habe ich endlich eine Remote Debugging connection hinbekommen. Hintergrund: Entwicklungsrechner mit Windows, Probleme unter Linux. Der Umstand, dass es sich um ein Webstart-App handelt, macht es noch ein bißchen kniffliger. Nach der Konsultation von einigen Foren und Blogs hab ich es jetzt geschafft: Auf dem Linuxrechner läuft die JVM im Debug-Modus und mit dem unter Windows installierten Eclipse kann ich (fast) debuggen, als wäre es eine aus Eclipse gestartete Anwendung. Voraussetzung ist natürlich, dass man den Sourcecode zur Verfügung hat. Reverse-Engineering mittels JODE funktioniert nur teilweise sauber. Ein weiterer -leider einschneidender- Nachteil ist der, dass die Variablenwerte nicht auslesbar sind. Es ist also sinnvoll, den Code mit entsprechend vielen Log-Statements zu instrumentieren, die über die Java-Konsole ausgelesen werden können.

Mein Vorgehen:

1. Die VM muss mit bestimmten Flags gestartet werden. Dazu bietet sich die Umgebungsvariable JAVAWS_VM_ARGS an. Funktioniert hat es mit folgenden Parametern:

-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888

Diese Konfiguration führt dazu, dass die VM auf Port 8888 hört. Firewalls sind ggf. auszuschalten bzw. zu konfigurieren. In einigen Foren habe ich gelesen, man müsse noch einen Servernamen angeben, wenn es sich nicht um localhost handelt. Das stimmt nicht.

2. Dann habe ich mir die bei einem vorherigen Start heruntergeladene JNLP-Datei geschnappt und lokal gestartet: javaws xxx.jnlp. Die Konsolenausgaben geben ein gewisses Feedback, ob alles geklappt hat. Unter Windows ging das bei mir übrigens nicht. Da meckert er, er könne die Main-Class nicht finden. Warum? Keine Ahnung… U.U. muss die JNLP-Datei noch ein bißchen überarbeitet werden.

3. Zum Test auf dem Linux-Rechner den Debugger starten: jdb -attach localhost:8888. Hier ist es wichtig, den Servernamen mitanzugeben, sogar wenn es sich um localhost handelt. Gelingt ein Connect ist alles in Butter. Gelingt er nicht: Viel Spass beim Wühlen im Netz.

4. Im Eclipse auf dem Windows-Rechner: Findet sich im, über “Debug…” geöffneten Menü im linken Teil ein Eintrag: “Remote Java Application”. Davon eine neue anlegen. Im Dialog den Port (8888) angeben und den Linux-Rechner eintragen (bei mir tat es nur die IP-Adresse). Projekt auswählen, Connection Type “Standard (Socket Attach)”. Alle anderen Einstellungen sind okay.

5. Bei gestarteter Linux-VM diese Konfiguration starten und fertig ist die Kiste. Es läßt sich debuggen wie gewohnt.

Der Unterschied zwischen nichts und nichts

Oracle bietet die schöne Funktion trim(), die Leerzeichen wegschneidet. Aber zum Teufel! irgendwie hat meine Abfrageklausel trim(table.field) <> '' NIE ein Ergebnis gebracht. Egal, ob field (ein char(10)-Feld) leer war oder nicht.
Die Lösung: trim() verwandelt leere Strings (z.B. ' ') in null und nicht wie beispielsweise in Java in den Leerstring "". Auch '' sieht Oracle als null. Und so ist null nie verschieden von null.

Mir war vorher noch nie aufgefallen, wie schwer es sein kann, DB-Admins von der Sinnhaftigkeit der Unterscheidung zwischen null und Leerstring zu überzeugen. Naja, Datenbanken sind halt selten objektorientiert.

Ant Styles




        
        
            
                
            
        

Heute bin ich in einem unserer Ant-Build-Skripte über etwas sehr Nettes gestolpert. In einer Config-Datei steht bei uns @jars@. Das läßt sich mit zur Build-Zeit ganz bequem dynamisch ersetzen. Z.B. durch eine Liste von Jars in einem speziellen Verzeichnis, wie im unteren Beispiel.

<propertyregex property="jars.path.appxml"
               input="${jars.path.property}"
               regexp="([^\\.]*)(dist\\\\apps\\\\myapp\\.ear\\\\)([^\\.]*)(\\.jar)"
               replace="&<module&> &<java&>\3\4&</java&> &</module&>"
               casesensitive="false" />

<!-- Copy application.xml and use the correct jars -->
<copy file="${apps.dir}/myapp.ear/META-INF/application.xml"
      toFile="${dist.dir}/myapp.ear/META-INF/application.xml">
  <filterset>
    <filter token="jars"
            value="${jars.path.appxml}" />
  </filterset>
</copy>

Mehr dazu hier: http://ant.apache.org/manual/CoreTypes/filterset.html

Find the Bug

Gestern habe ich ein bißchen rumgehackt und bin mal wieder in den selben Fehler gerannt. Hier mal als Knobelaufgabe für alle Nerds:

Ausschnitt aus einer Java-Methode:

int bereich = 11;
int probSum = 3;
Random r1 = new Random(42);
Random r2 = new Random(23);
for (int i = 0; i < 17 ; i++) {
probSum = (Math.abs(r1.nextInt()) + Math.abs(r2.nextInt())) % bereich;
System.out.println(probSum);
}

Ausgabe z.B:

2

12

-4

Quizfrage: Wie kann es sein, dass probSum nach dieser Zuweisung eine negative Zahl ist?????

Java für Mütter I

Einleitung

Also: Was ist Java? Java ist eine Insel in Indonesien, die für ihren wohlschmeckenden Kaffee bekannt ist. Gleichzeitig ist Java auch eine Programmiersprache. Und obgleich einige Ähnlichkeiten zwischen dem Insel- und dem Programmierleben bestehen, gibt es doch einige kleinere Unterschiede, die ich im Folgenden an die Mutter bringen will.
Die Sprache Java ist eine sogenannte “Objektorientierte Programmiersprache”. Das sagt einem zu Beginn genauso viel wie “Merapi” (ein Vulkan auf der Insel).
Was es wirklich heißt, wird sich im Laufe meines Tutorials herausstellen. Es richtet sich, wie bereits mehrfach erwähnt, an Mütter. Das soll heißen, an Leute, die von Programmieren eigentlich keine Ahnung haben. Ich will hier also nur die Grundlagen vermitteln und keinen Einstieg in professionelle Software-Entwicklung verschaffen. Ich schaffe mir doch keine unnötige Konkurrenz, oder?

Teil 1: Grundschul-Informatik
Jeder kennt Computer. Da laufen Programme drauf. Entweder man hat solche schon mal installiert, oder man ist deutlich zu unfähig, um dieses Tutorial durchzuarbeiten. Vielleich sollte man dann lieber die Zeit im Kindergarten verbringen. Aber was ist ein Programm genau? Ein Programm ist ein Text, in dem man dem Computer Anweisungen gibt, irgendetwas zu machen. Das sind Rechenbefehle oder Speicher- und Ladebefehle, oder auch irgendwelche grafischen Ausgaben, wie Fenster oder Meldungen. Eine Programmiersprache legt fest, WIE man die Befehle formuliert. Wenn man einen korrekt formulierten Programmier-Text hat, kann ein anderes Programm diesen “Code” lesen und den Computer dazu bringen, die gewünschten Sachen zu machen. Es gibt also quasi einen Übersetzer von dem, was man schreibt, in das, was der Computer versteht. Dieser Übersetzer heißt je nach Sprachtyp “Interpreter” oder “Compiler” und erlaubt, eine (relativ) einfach Kommunikation mit dem Computer. Man kann auch selbst mit dem Computer sprechen. Aber dessen Sprache ist sehr unschön. Er versteht nämlich nur Nullen und Einsen und die sprechen wenige Leute fließend. Fehler verzeiht er auch überhaupt nicht gerne.
Java ist also nicht nur eine Programmiersprache, sondern gleichzeitig auch ein Programm: ein Übersetzerprogramm (“javac”) und ein Ausführungsprogramm (“java”). Um also irgendetwas programmieren zu können, müssen wir erstmal was installieren. Die Installation ist genau wie bei anderen Programmen auch: Runterladen. Öffnen. Ganz oft auf OK drücken. Step by Step:
1. Hier JDK 6 herunterladen: Lizenzbedingungen akzeptieren und “windows offline installation, multi language” anklicken. Da es sich um 50 Megabyte handelt reicht hier kein normales Modem.

2. Heruntergeladene Datei öffnen. Accept->Next->Warten->Next->Finish->Read me schließen.

Jetzt haben wir das Grundwerkzeug. Um einfacher Code zu schreiben, ist es auch gut, sich ein kleines Programmierschreib-Programm zu verwenden. Ein solches ist SciTE. Das installieren wir auch mal. Wenn wir das geschafft haben, können wir gleich mit dem ersten Programm starten.