Freitag, 3. Juli 2015

Grails und SQL Logging

Problem: Die abgesetzten SQL Statements sollen in das Log, aber nicht in die Konsole.

Hintergrund: Die Ausgabe des SQL wird durch die Standardkonfiguration der Datenquelle in die Konsole geleitet.

Lösung: Die Log4j Konfigurationen nutzen, um die gleiche Ausgabe in einer separaten Logdatei ausgeben zu lassen.

Hier eine Beispielhafte Konfiguration in Grails 2.5.0.

Mittwoch, 1. Juli 2015

Zugriff über eigenen Datenbank-Client auf die H2 Datenbank bei der Entwicklung mit Grails

Problem

Mit einem eigenen Datenbank-Client können keine Datenbankabfragen gegen die voreingestellte Entwicklungsdatenbank von Grails abgesetzt werden.

Hintergrund

Der voreingestellte In-Memory Mode der H2 Datenbank macht den Zugriff auf die Daten der Applikation von einem anderen JVM Prozesses aus unmöglich.

Lösung

Der Automatic Mixed-Mode ermöglicht es die Datenbank gleichzeitig lokal und im Server Modus zu betreiben. Die H2 Datenbank verwaltet die Verbindungen dann so, dass dem ersten Prozess Zugriff im Embedded Mode ermöglicht wird und alle weiteren Prozesse bekommen Zugriff im Server Mode.


Die Dateien der Datenbank liegen bei der obigen Konfiguration in dem Verzeichnis data innerhalb des Projektverzeichnisses.

Der Datenbank-Client verwendet die gleiche Datenbankverbindungskonfiguration wie die Grails Applikation. Zu beachten ist lediglich, dass der Pfad zu den Datenbankdateien in dem Client eventuell angepasst werden muss.

Montag, 29. Juni 2015

Grails Spring Security ACL kann Cache Bean nicht initiieren

Problem: Grails 2.5.0 kann aufgrund der folgenden Ausgabe nicht gestartet werden.


Hintergund: Hibernate verwendet einen Cache und hat diesen bereits gestartet. Das ACL Plugin verwendet ebenfalls einen Cache unter dem gleichen Namen.

Lösung

Schritt 1: Ergänzen der Abhängigkeiten, um des Cache Plugin.


Schritt 2: Konfiguration des Cache, zur gemeinsamen Nutzung.


Montag, 22. Juni 2015

VirtualBox - Unable to load R3 module

Problem
Beim Start einer VM von VirtualBox auf einem Rechner mit Windows 7, wird folgende Fehlermeldung ausgegeben.

Erläuterung
Wichtige Windows Systemdateien wurden durch die Installation von Fremdsoftware verändert.

Lösung 1
In der Konsole von Windows folgenden Befehl ausführen, um die Systemdateien wieder herzustellen.

Lösung 2
Die veraltete Version VirtualBox 4.2.16 installieren.

Dienstag, 16. Juni 2015

JVM 1.8 Update 45 inkompatibel mit Grails

Problem: Beim Start einer Grails-Applikation wird die folgende Fehlermeldung in der Konsole ausgegeben.


Erläuterung: Es gibt Inkompatibilitäten zwischen JDK 1.8 Update 45 und Grails.

Lösung: Installation einer älteren Java Version, wie zum Beispiel JDK 1.8 Update 25 oder JDK 1.7 Update 79.

Sonntag, 14. Juni 2015

Kontinuierliches Refactoring


Vor wenigen Tagen hatte ich das Vergnügen eine Präsentation über Refactorings halten zu dürfen. In der mir zur Verfügung gestellten Stunde war eine Live Coding Session von etwa 10 Minuten enthalten.

Mein Ziel war es, die Herzen der Teilnehmer für das Prinzip der ständigen Überarbeitung des Quelltextes zu erwärmen, ohne dabei die Funktion der Software zu verändern.

Mein Vorhaben, selbst gezeichnete Piktogramme in meine Präsentation einzubauen, ist bereits im Vorfeld an dem Feedback für die Folien gescheitert. Entweder muss ich noch an meinen zeichnerischen Fähigkeiten arbeiten oder das sie passen einfach nicht so gut zu einer Power Point Präsentation.

Donnerstag, 21. Mai 2015

Präsentation mit Piktogrammen

Durch meinen Beruf habe ich mit der Entwicklung von Software zu tun. Dieses Handwerk zu beherrschen und die Fertigkeiten weiter auszubauen, ist für mich eine alltägliche Aufgabe. Andere Fertigkeiten werden seltener abgefragt. Zum Beispiel vor einer Gruppe zu präsentieren. Dadurch fehlt mir die Möglichkeit diese Fertigkeit weiter zu entwickeln. Ich freue ich mich daher über Gelegenheiten meine Kenntnisse auch auf diesem Gebiet erweitern zu können.

Mir ist bewusst, es gibt einige Dinge die ich bei einer Präsentation falsch machen kann. Manches weiß und beachte ich bereits, Anderes muss ich mir durch ständiges Feedback bewusst machen und die richtigen Maßnahmen daraus ableiten. Da finde ich es sehr hilfreich, wenn man mir zeigt worauf es ankommt.

Vor kurzem hatte ich das Glück an einer zweitägigen Schulung für souveränes Präsentieren teilzunehmen. Ich habe Erkenntnisse über Struktur und Aufbau einer Präsentation, Einsatz der Medien, Einbindung des Publikums, Sprache und Körpersprache, sowie den Umgang mit Störern gewonnen.

An dem letzten Tag der Schulung haben wir Teilnehmer innerhalb von zwei Stunden eine Präsentation zu einem Thema unserer Wahl erstellen und sie dann vor den anderen Teilnehmern halten dürfen. Da in der gesamten Schulung keine digitalen Medien verwendet wurden, haben wir sie mit Flip Charts und Pinnwänden erstellt. Wir haben uns dabei an dem orientiert, was wir in den Übungen am Vortag gelernt hatten. Durch die Vorgabe der Medien habe ich mich entschieden meine Präsentation mit möglichst vielen Piktogrammen zu füllen, um den "visuellen Kanal" des Publikums zu bedienen. Das Ergebnis ist in den folgenden Fotos zu sehen:








Fazit

Diese Flip Charts sind keine Meisterwerke, aber das kam bei mir nach der kurzen Zeit heraus. Auch wenn es noch Einiges zu verbessern gibt, habe ich mich weiterentwickeln können. Ich bin darüber erstaunt, wie schnell man mit einigen Piktogrammen aussagekräftige Bilder erstellen kann. Sie sind ein gutes Hilfsmittel, um Inhalte dem Publikum zu vermitteln. Ich finde den handwerklichen "Touch" der Zeichnungen persönlich und aussagekräftig. Ich werde in Zukunft versuchen Piktogramme in meinen Präsentationen einzubauen. Vielleicht auch in PowerPoint Folien.

Mittwoch, 6. Mai 2015

Arbeiten in Teams - Angefangene Aufgaben

Bei der Softwareentwicklung in einem Team zu arbeiten ist manchmal etwas anstrengend, aber die meiste Zeit ist es hilfreich. Wenn man ein gutes Team hat, bietet es einen entscheidenden Vorteil: Die Aufgabe an der man gerade arbeitet, kann von einem Teammitglied weitergeführt werden.

Ich persönlich empfinde die Möglichkeit eine Aufgabe von einem Kollegen weiterentwickeln zu lassen, als sehr angenehm. Nicht selten sind die Arbeiten zeitkritisch und müssen innerhalb weniger Tage abgeschlossen werden. Im Alltag ist mir jedoch immer wieder aufgefallen, dass man dazu neigt sich nicht nur auf eine Teilaufgaben zu konzentrieren. Oft kommt Eines zum Anderen und man hat plötzlich einige offene Baustellen in der Software, die man versucht bis zum Fertigstellungstermin zu schließen. In vielen Fällen klappt es auch, wenn nichts dazwischen kommt. Und genau darum geht es mir. Meiner Erfahrung nach, kommt immer wieder mal etwas dazwischen. Die Arbeit kann dann nicht planmäßig beendet werden. Die Gründe dafür können so vielfältig sein, dass keine Liste der Welt vollständig wäre.

Damit der Kollege die Arbeit jedoch möglichst nahtlos weiterführen kann, muss er den aktuellen Stand der Entwicklung kennen. Welche Teilaufgaben sind bereits erledigt, wo muss weitergearbeitet werden? Sind zu viele Baustellen vorhanden oder die funktionalen Anpassungen an der Software nicht gut nachzuvollziehen, fällt es schwer den aktuellen Stand schnell zu erfassen. Die Arbeiten stehen dann zunächst still, bis der Kollege auf den gleichen Wissensstand ist wie ich war, als ich die Arbeit liegen gelassen habe.

Wenn man die Kollegen direkt neben sich sitzen hat, dann kommt es hin und wieder zu einem Austausch. Sei es, weil man Fragen zu Implementierungsdetails hat oder man regelmäßige Code Reviews durchführt oder man gar Pair-Programming macht. Dadurch haben die Kollegen wenigstens eine Vorstellung von dem aktuellen Stand. Wenn man jedoch in einem verteilten Team arbeitet, verschärft sich die Situation deutlich. Aufgrund der Distanz arbeitet man eher selten so eng zusammen, dass die Kollegen über den aktuellen Stand informiert sind. Sie haben meistens erst dann Berührung mit der Materie, wenn ihnen die Aufgabe zugewiesen wird.

Für mich habe ich daher immer folgende Punkte als minimalen Leitfaden im Hinterkopf:
  • Organisatorisch
    • Schneide die einzelnen Aufgaben in möglichst kleine Teilaufgaben.
    • Dokumentiere Erkenntnisse im Ticketsystem, Wiki, VCS usw..
      • UML Diagramme zu eigenen Zwecken.
      • Fachlich interessante SQL Statements.
      • Fotos vom Whiteboard oder Flipchart.
  • Software
    • Führe spätestens nach jeder Teilaufgabe einen Commit im VCS aus.
    • Baue die Software vor dem Commit mit allen Tests erfolgreich durch.
    • Verlasse den Arbeitsplatz nicht mit Quelltext, der nicht in das VCS eingespielt ist.

Wenn ich mich mit anderen Software Entwicklern über diese Punkte unterhalte, dann bilden sich häufig zwei Fraktionen. Die Einen machen es immer so und empfinden diese Punkte als selbstverständlich oder sogar unzureichend, die Anderen machen es auf gar keinen Fall so und empfinden es als zu aufwendig. Den Ersteren muss ich sagen, dass die guten Vorsätze im Entwickleralltag gerne mal vergessen werden. Und die Letzteren machen sich, meiner Meinung nach, das Leben unnötig schwer. Und mir damit auch!

Dienstag, 31. März 2015

Eclipse GGTS kann Grails Projekt nicht kompilieren


Problem

Beim Kompilieren des Grails Projekts gibt die GGTS IDE folgende Fehlermeldung aus.

Error Fatal error during compilation org.apache.tools.ant.BuildException: java.lang.OutOfMemoryError: Java heap space (Use --stacktrace to see the full trace)

Lösung

Einstellen der Default JVM Args auf einen sinnvollen Wert.


Donnerstag, 26. Februar 2015

Meine Beobachtungen in Meetings

Mir ist in der Vergangenheit immer wieder aufgefallen, wie schwer es manchen Menschen fällt Verhaltensweisen an den Tag zu legen, die eine vernünftige Zusammenarbeit ermöglichen. Während eines Meetings zum Beispiel.

In einem Meeting werden Informationen gesammelt und Einsichten generiert. Am Ende sollten Erkenntnisse gewonnen und vielleicht Maßnahmen abgeleitet worden sein. Für gewöhnlich ist es mit einem klaren Zeitfenster versehen.

Damit ein Meeting funktioniert und einen Mehrwert generiert, sollten von den Teilnehmern zwei Dinge beachtet werden: Vorbereitung und Disziplin.

Vorbereitung

Die Teilnehmer sollten auf das Meeting vorbereitet sein. Sie sollten sich über die zu erörternden Themen und die Ziele des Meetings informieren, damit sie sich auf die Punkte konzentrieren können, die ihnen einen Mehrwert bieten. Wenn Teilnehmer nicht über die zu erörternden Punkte informiert sind, müssen sie während des Meetings durch die Anderen auf den notwendigen Wissenstand gebracht werden. Sie neigen dann auch gerne dazu in den Gesprächen immer wieder abzudriften und müssen immer wieder durch die Anderen "eingefangen" werden. Das kostet Zeit und reduziert den Nutzen des Meetings.

Disziplin

Während des Meetings sollten sich die Teilnehmer das Ziel der Zusammenkunft bewusst machen. Falls die eigenen Beiträge den vordefinierten Fokus verlassen, ist eine Selbstregulierung notwendig. Auch wenn einem Details oder verwandte Themen persönlich unter den Nägeln brennen, hat eine Diskussion über Randthemen eine Defokussierung der Teilnehmer zur Folge. Die Anderen werden dazu gezwungen den Äußerungen zu folgen, um den Kern der Aussagen zu verstehen. Es kommt dabei immer wieder zu Diskussionen über irrelevante Details. Was die Teilnehmer wiederum verleitet ihren Standpunkt bei unwichtigsten Punkten deutlich zu machen. Danach müssen die Teilnehmer den Fokus wiederfinden. Dieser  Prozess der Defokusierung und anschließender Refokussierung ist, meiner Erfahrung nach, zeitintensiv und reduziert das energetische Level des Meetings deutlich.

Kompensation

Man kann schnell in die Situation kommen, dass man sich nicht ausreichend auf ein Meeting vorbereitet hat. Sollte es doch passieren, muss das nicht unbedingt zu einem Einbruch der Produktivität eines führen. Entscheidend dabei ist, wie man mit der Situation umgeht. Mit ausreichender Disziplin kann man das Defizit durch stark fokussierte und konstruktive Mitarbeit kompensieren. So behindert man wenigstens nicht den konstruktiven Prozess.

Fazit

Die Kombination aus schlechter Vorbereitung und schlechter Disziplin einzelner Teilnehmer, hat einen enorm schlechten Einfluss auf das Ergebnis. Wer sich als konstruktives Mitglied des Teams sieht und nichts konstruktives beizutragen hat, sollte wenigstens diszipliniert sein. 

Dienstag, 24. Februar 2015

Test-driven SQL

Die Migration

Eine Änderung des Datenmodells ist durchzuführen und es sind Daten aus der bestehenden Struktur in eine Neue zu überführen. Es gibt verschiedene Möglichkeiten eine Datenbank zu migrieren. Werkzeuge wie LiquiBase sollen die Arbeit erleichtern und helfen sogar dabei einen Bogen um SQL zu machen. Mir persönlich begegnet eine Migration mittels SQL Statements trotzdem immer wieder. Auch wenn eines der erwähnten Werkzeuge im Einsatz ist. 

Bei einer Migration mittels SQL gehe ich für gewöhnlich in folgenden Schritten vor:

1.) Erstellen der SELECT Anweisungen zur Identifizierung der Datensätze die zu migrieren sind.
2.) Erstellen der DDL SQL (falls notwendig).
3.) Erstellen der UPDATE oder INSERT Anweisungen zum Migrieren der selektierten Daten.

Bei diesem Vorgehen werden zur Selektion der Datenmengen typischer Weise Joins und Where-Klauseln verwendet, die den Ist-Zustand der Datenbank interpretieren (1). Nach erstellen der neuen Struktur (2), wird die eigentliche Migration durchgeführt (3). Wenn kein Fehler bei der Ausführung der Statements auftritt, ist die Migration erfolgreich durchgeführt. 

Ist das wirklich so? Ein erfolgreicher Durchlauf sagt doch nicht, dass die Daten aus fachlicher Sicht den richtigen Zustand angenommen haben. Man könnte nun den Migrationskripten vertrauen, schließlich wurden sie mit größter Sorgfalt erstellt. 

TDD

Doch wenn dieses Vorgehen richtig ist, warum vetrauen TDDler bei der Entwicklung von Software nicht einfach dem produktiven Code? Warum das Schreiben von Testfällen? Ist die Migration von Daten weniger kritisch, als das Schreiben einer Applikation?

Gehen wir einmal davon aus, beides muss den gleichen Kriterien der Fehlerfreiheit genügen. Führe ich als TDDler diesen Gedanken zu Ende, drängt sich mir ein testgetriebenes Vorgehen bei der Erstellung von Migrationsscripts auf. Wie würde ein solches Vorgehen wohl aussehen?

TDD und SQL

Nach TDD definiert man die Erwartung an die zu implementierende Funktion in einem Testfall. Dieser Testfall wird geschrieben, noch bevor die eigentliche Funktion realisiert wird. Bei einer Datenbankmigration müsste man zunächst das erwartete Ergebnis einer Migration in einem Test-SQL-Statement definieren. 

Ein Testfall unterscheidet sich für gewöhnlich von der Logik der zu testenden Fachlichkeit. Sie ist möglichst einfach oder gar nicht vorhanden. Schließlich möchte man die zu testende Fachlichkeit nicht ein weiteres Mal in dem Test programmieren. Das SELECT Statement des Tests darf demnach keine Statements aus der Migration wiederverwenden.

Ein Testfall verwendet zudem möglichst simple Daten, um den erwarteten Zustand zu definieren, den das System nach Ausführung der getesteten Funktion angenommen haben soll. Das spricht für ein SELECT Statement mit möglichst wenigen JOINS und wenigen Kriterien in der WHERE Klausel. 

Bei einem Unit Test erhält der Entwickler ein eindeutiges Feedback, ob der Test erfolgreich war oder fehlgeschlagen ist. Eine komplexe Ausgabe, muss von dem Entwickler interpretiert werden und ermöglicht somit eine Fehlinterpretation. Das Test-SQL Statement sollte ein ebenso eindeutiges Feedback liefern.

Man kann nun eine Test SQL so schreiben, dass es gleich in einem Rutsch die gesamte Migration auf Erfolg überprüft. Oder, man geht in möglichst kleinen Schritten vor und zerlegt die Migration. Diese kann dann von den Testfällen iterativ vorangetrieben werden.

Fazit

Aus den obigen Gedanken ergibt sich für mich folgendes Vorgehen...

1.) Erstellen der DDL SQL (falls notwendig)

In möglichst kleinen Schritten und Zyklen...

2.) Erstellen / erweitern der Test SQL.
3.) Erstellen / erweitern der UPDATE oder INSERT Anweisungen.
4.) Zurück zu Schritt 2.

Das Vorgehen kann also auch beim Erstellen einer Datenbankmigration funktionieren. Voraussetzung hierfür ist allerdings, dass es geeignete Datensätze in der Datenbank gibt. Ohne eine sinnvolle Ausgabe der Test SQL, ist kein test-getriebener Ansatz möglich.