Tag Archives: Programmierung

Java Enterprise Loop

Following a discussion in the Netz39 IRC channel I created a short Java Enterprise Loop for those in need.

package com.penguineering.seriousnonsense;

/*
 * Short usage instructions:
 *
 * 		final Runnable loopee = ... // Acquire some runnable instance
 * 		EnterpriseLoop.forRunnable(loopee).run();
 *
 * or put it in a thread:
 * 
 * 		new Thread(EnterpriseLoop.forRunnable(loopee)).start();
 *
 *
 * Whatever kills your design best.
 */

public class EnterpriseLoop implements Runnable {
	public static EnterpriseLoop forRunnable(final Runnable _loopee) throws NullPointerException {
		return new EnterpriseLoop(_loopee);
	}
	
	private final Runnable loopee;
	
	private EnterpriseLoop(final Runnable _loopee) throws NullPointerException {
		if (_loopee == null)
			throw new NullPointerException("Runnable _loopee must not be null!");
		
		this.loopee = _loopee;
	}
	
	public Runnable getLoopee() {
		return loopee;
	}
	
	@Override
	public void run() {
		while (true)
			try {
				loopee.run();
			} catch {Throwable t) {
				// ignore
			}
	}
}

To adhere to development standards usually found in situations leading to the need of an enterprise loop, I neither documented the code (except for a short usage instruction to save you from thinking about those lines you are going to copy) nor tested it.

I leave this to the public domain to successfully serve as a bad example.

JavaMail and TLS: Turn on the security switch!

While talking to Ge0rg about latest issues in Java TLS we stumbled upon the question whether the JavaMail API would have similar problems.

Naturally one would expect that Java’s SSL implementation is secure. However, this is not the case: Special care needs to be taken regarding Man-In-The-Middle attacks: While a certificate may turn out to be valid, you cannot be sure that it has the right origin!

The problem is known for a while and library maintainers are taking steps to avoid it. However, for compatibility reasons those features may need to be turned on.

For JavaMail version 1.5.2 the SSLNOTES.TXT says specifically:

— Server Identity

Check RFC 2595 specifies addition checks that must be performed on the server’s certificate to ensure that the server you connected to is the server you intended to connect to. This reduces the risk of “man in the middle” attacks. For compatibility with earlier releases of JavaMail, these additional checks are disabled by default. We strongly recommend that you enable these checks when using SSL. To enable these checks, set the “mail..ssl.checkserveridentity” property to “true”.

Here is the thing that most examples forget: You need to switch that feature on!

final Authenticator auth = ... // somewhere in your application
final Properties p = new Properties();

// add your JavaMail configuration here

// this is implied by the protocol "imaps"
p.put("mail.imap.starttls.enable", "true");

// not only check the certificate, but also make sure that we are
// connected to the right server.
p.put("mail.imap.ssl.checkserveridentity", "true");

try {
	Session session = Session.getDefaultInstance(p, auth);
	Store store = session.getStore();
	store.connect();

	// do something with the store
} catch (MessagingException e) {
	// do something meaningful(!) with the exception
}

// close the store when you are done

To use SSL at all, you need to turn it on, either by specifying “imaps” in the property mail.store.protocol or by setting mail.imap.starttls.enable to “true”. Replace imap respectively for other protocol suites (e.g. smtp).

Update 2014-08-05: Inserted the Link to Georg’s blog post about latest issues in Java TLS.

AT91Boot_DLL-API-Aaaaargh-Anfall

Atmel ist so nett für seine auf ARM basierenden Microcontroller eine Software mitzuliefern, mit der man den Controller sozusagen in Betrieb nehmen und den angeschlossen RAM und Flash testen und bespielen kann, nennt sich SAM-BA. Enthalten ist eine Bibliothek namens AT91Boot_DLL.dll, deren API ganz brauchbar dokumentiert ist. Sucht man noch ein wenig quer, stößt man auch auf AT91-ISP, wo es zwei Beispielprojekte gibt, wie man die Bibliothek in eigenen Projekten nutzen kann. Der Vorteil an der Bibliothek ist, dass man sich um die Verbindung zur ARM-CPU via USB oder serieller Schnittstelle keine Gedanken machen muss, man ruft einfach die Funktion AT91Boot_Scan() auf und lässt die DLL suchen. Das Code-Beispiel aus der Dokumentation sieht so aus:

CHAR *strConnectedDevices[5];
for (UINT i=0; i<5; i++)
    strConnectedDevices[i] = (CHAR *)malloc(100);
AT91Boot_Scan((char *)strConnectedDevices);

Beim Betrachten der Funktionsparameter hatte ich bereits letzte Woche den Verdacht, dass das mal krachen könnte, wenn man hier der Bibliothek gar nicht sagen kann, wie lang die Liste jetzt wirklich ist, die man da reinfüttert. Im Beispielprojekt umfasst die übrigens 10 Elemente und das änderte ich Freitag nachmittag noch auf 5. Funktionierte Freitag auch, so weit so schön.

Montag, also heute, stieg die Anwendung dann reproduzierbar mit einer Access Violation in der msvcrt.dll aus beim Aufruf dieser Funktion. Klassisch: »Es geht nicht mehr, ich hab aber nichts geändert.«

Etliche Flüche, Tests, Recherchen und dergleichen später stellte sich raus, dass ich doch was geändert hatte: ich hatte heute noch ein, zwei USB-Geräte mehr an meinen Rechner angeschlossen. Die Bibliothek sucht zuerst nach über USB angeschlossenen ARM-Prozessoren und scheint alle aktiven USB-Geräte durchzugehen, 5 Elemente in der Liste haben dann nicht mehr ausgereicht, flugs im Präprozessor-Makro den Wert erhöht und schon läuft das wieder ohne Absturz.

Den Rumpelstilzchentanz, den ich hier aufgeführt habe, weil die ihre API nicht sauber designen können und einen so zur Suche nach so dämlich subtilen Fehlern zwingen, möge sich bitte jeder selbst vorstellen! *motz*

Microsoft Visual C++ 6 und CMake

Warum man eine steinalte Entwicklungsumgebung mit einem modernen Build-System zusammen benutzen will, lässt sich nicht nur mit »Weil es geht!« begründen, es gibt sogar handfeste Argumente dafür, doch der Reihe nach.

Aus Gründen hab ich hier einige MFC-Projekte vorliegen, die in Visual Studio 6 entwickelt wurden, für das hier auch eine gültige Enterprise-Lizenz existiert. Bekommen habe ich Quellcode eines älteren Projekts ohne die Projektdateien. Neu zu entwickeln ist ein vergleichbares Programm und da Entwicklungsumgebung und KnowHow verfügbar sind, wird das neue Projekt eben auch in Visual Studio 6 entwickelt, die Programme laufen ja trotzdem.

Mit CMake füge ich dem Quellcode jetzt einfach die passenden Dateien mit dem Namen “CMakeList.txt” hinzu und lasse mir von CMake ein Projekt für VS6 erzeugen. Vorteil: ich brauche keine Projektdateien im Versionsverwaltungssystem ablegen, kann mir das auschecken wohin ich will und mein Quellcodebaum enthält nur das nötigste. De facto war ich so sogar in der Lage, das alte Projekt, wo mir die Projektdateien fehlten, mit CMake zu bauen und dem auf die Finger zu gucken. Soviel zum »warum«, es folgt jetzt das »wie« …

Zunächst mal sei gesagt, wenn schon Visual Studio 6, dann auch das letzte Service Pack installieren. Ist ein FAQ1 und das Service Pack gibt’s bei Microsoft.

Da ich hier eine MFC-Anwendung entwickeln will, also ein Tool mit GUI, reicht mir der reine Code nicht aus, sondern ist sind noch ressource files nötig. Bevor ich also später die Projektdateien mit CMake generieren lasse, erzeuge ich mit dem Assistenten von Visual Studio ein neues MFC-Projekt, in meinem Fall »Dialogfeldbasierend«:

MFC-Anwendungs-Assistent Dialogfeldbasierend

Den Rest des Assistenten klickt man nach eigenen Vorstellungen durch und dann kann man Visual Studio erstmal wieder schließen. Man hat jetzt einen Ordner vorliegen, in dem folgende Dateien liegen:

von VS6 erzeugte Dateien für ein neues MFC-Projekt

Davon kopieren wir jetzt den Ordner res und folgende Dateien an einen neuen Ort:

  • foo.aps
  • foo.clw
  • foo.cpp
  • foo.h
  • foo.rc
  • fooDlg.cpp
  • fooDlg.h
  • Resource.h
  • StdAfx.cpp
  • StdAfx.h

Das ist jetzt unser neuer Source-Ordner und dort wird nun eine Datei namens CMakeLists.txt angelegt. Fortgeschrittene CMake-Nutzer können das auch auf getrennte Unterordner für Programmcode, Header und externe Ressourcen aufteilen, spar ich mir hier mal und zeige nur wie das mit einer einzigen CMakeLists.txt aussehen kann:

project(foo)
cmake_minimum_required(VERSION 2.8)

find_package(MFC)

set(FOO-H
    foo.h
    fooDlg.h
    Resource.h
    StdAfx.h
)

set(FOO-RC
    foo.rc
)

set(FOO-SRC
    foo.cpp
    fooDlg.cpp
    StdAfx.cpp
)

add_definitions(-D_AFXDLL)
set(CMAKE_MFC_FLAG 2)
add_executable(${PROJECT_NAME} WIN32
    ${FOO-H}
    ${FOO-RC}
    ${FOO-SRC}
)

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX})

Zu set(CMAKE_MFC_FLAG 2) bitte nochmal selbständig die Doku lesen und nicht verwirren lassen, die dort gezeigten Code-Abschnitte sind aus älteren Versionen vom Installer von CMake selbst kopiert. Wie eingangs angedeutet, machen wir jetzt einen Build außerhalb des Source-Verzeichnisses und rufen dazu das CMake-GUI auf:

CMake GUI für unser Mini-Projekt

Nach einem Klick auf Configure wird man nach dem Generator gefragt. Dort wählt man Visual Studio 6 aus der Liste und bestätigt. Ein weiterer Klick auf Generate erzeugt dann die Projektdateien im zuvor eingestellten Build-Ordner, alles oben im Screenshot zu sehen. Mit einem Doppelklick auf die Datei foo.dsw öffnet sich dann Visual Studio und man kann sein Projekt bauen. Schick auch, dass es gleich ein Unterprojekt gibt, was einem die Anwendung installiert. Theoretisch gibt’s auch noch CPack, womit man sich dann noch gleich einen Installer backen kann, aber das würde jetzt hier zu weit führen. ;-)

das von CMake erzeugte VC6-Projekt

Wenn das alles soweit schön kompiliert, kann man den Source-Ordner so nehmen wie er ist und in das Versionsverwaltungssystem seiner Wahl packen. Projektdateien für Visual Studio generiert sich dann jeder Entwickler selbst mit CMake. Bisschen umständlich ist das später beim Hinzufügen von neuen Dateien ins Projekt, weil man die CMakeLists.txt parallel pflegen muss, aber das ist es meiner Meinung nach wert.

  1. Visual Studio 6 Compiler : Freezing CMake Configuration []

Vortrag zu Template Toolkit 2

Das hat man nun von den guten Connections und dem positiven Feedback zum letzten Vortrag: der nächste Vortrag. Diesmal geht’s um das Thema, was ich letztens hier schon im Beitrag An Instant Messenger Emoticon Theme Generator angerissen hatte, nur diesmal mit Schwerpunkt auf Website und wie ich TT2 für lespocky.de eingesetzt habe. Die Folien wird’s dann, wenn sie soweit sind, unter CC-Lizenz auf bitbucket geben. Bis Montag dann! ;-)

Update: die Folien gibt’s auch bei bitbucket zum runterladen.

Text vs. Binary

Einer der täglichen Stolpersteine auf dem Weg zum C-Guru, hat mich gerade eine Stunde Lebenszeit gekostet. Vergleiche:

fopen( "header.bin", "wb" )

mit

fopen( "header.bin", "w" )

und dann noch den Auszug aus C in a Nutshell

The mode string may also include b as the second or third letter (that is, "ab+" for example is the same as "a+b"), which indicates a binary file, as opposed to a text file. The exact significance of this distinction depends on the given system.

»The given system« in diesem Fall Microsoft Visual C++® 6.0 unter Windows XP. Und was macht das, wenn man das b weg lässt? Es fügt vor jedes 0x0A, das man mit fwrite() in eine Datei schreibt, selbständig ein 0x0D ein, damit aus dem LF auch brav ein CRLF wird. Und ich wunder mich, warum meine Dateien größer sind, als sie sein sollten …

IT-Projekte 2009

Das Jahr ist zwar schon etwas fortgeschritten, trotzdem habe ich mir vorgenommen, bis zum Ende des Jahres in meiner Freizeit ein paar IT-Projekte voranzubringen. Aus der doch recht großen Auswahl der Projekte, die mich interessieren, habe ich die folgenden herausgepickt:

  1. IMPULS: Dieses Projekt hat inzwischen doch schon ein paar Jahre hinter sich und es gab diverse Situationen, in denen ich es gebraucht hätte. Bis Ende des Jahres sollten hier ein lauffähiger Daemon (aber auf Java-Basis) und ein paar Clients sowie mindestens ein Reader stehen.
  2. Antiblau: Den Server haben wir seit Ende 2005, aber noch immer sind ein paar Funktionen nicht verfügbar und auch die vorhandene Administrations-Infrastruktur kann mal modernisiert werden.
  3. Debian: Entwickler werde ich wohl in diesem Jahr nicht, aber ein paar Pakete aus eigenen Sachen möchte ich bauen und wenigstens soweit in die Community reinschauen, dass ich sicher entscheiden kann, ob ich überhaupt Entwickler werden will.
  4. QCaff: Eine grafische (Qt-basierte) Variante von CAFF, die sowohl unter Windows als auch unter Linux laufen soll und das Management von GPG-Keys für Jedermann ermöglichen soll. Insbesondere bei der Nachbereitung von Keysigning-Parties besteht hier offenbar Softwarebedarf. Wenn alles klappt, ist das aber trotzdem ein recht überschaubares Tool. Sofern vorhanden, werde ich bestehende Lösungen weiterverwenden.

Weiterhin warten auch bei UniMentor interessante Programmieraufgaben und der FaRaFIN kann ebenfalls mit einem interessanten Projekt aufwarten. Anfang 2010 werden wir sehen, was davon ich umsetzen konnte.

irssi-Hilight mit Jabber

Seit einigen Jahren läuft in meiner Screen-Session neben ICQ und anderen Tools auch ein irssi, um mich mit der Welt des IRC zu verbinden. In den meisten Channels bin ich einfach nur anwesend, gelegentlich spricht mich dann aber doch jemand an. Dank hilight im irssi wird man darüber ja eigentlich informiert. Nur leider schaue ich viel zu selten in das irssi-Fenster, um das dann letztendlich auch zu sehen. (Ja, screen informiert ueber Pings in anderen Fenstern, aber da guck ich doch erst Recht nicht hin …)

Da irssi eine schicke Perl-API hat, liegt es doch nahe, ein Perl-Script zu schreiben, mit dessen Hilfe ich mich anderweitig informieren lassen kann. Sehr nahe liegt da der Instant Messenger, der sowieso immer läuft, wenn ich am Rechner sitze – konkret Jabber.

Mit dem Perl-Modul Net::Jabber ist das alles kein Problem (abgesehen von den lückenhaften Dokumentationen, insbesondere in der irssi API) und so gibt es nun das Script irssi2jabber.pl, das als irssi-Script geladen werden kann und mir nun bei jedem Hilight oder jeder privaten Nachricht, die auftreten, während ich /away bin, eine Nachricht an meinen Jabber-Account schicken.

Das Script ist etwas kommentiert, die notwendigen Einstellungen stehen ganz am Anfang und müssen in die irssi-Config. Unter der GPLv3 darf es jeder weiterverwenden, natürlich nehme ich auch Patches an, die, wenn sie nützlich sind, eingepflegt werden.

Penguineering

Penguineering ist ein Kunstwort, das aus penguin und engineering zusammengesetzt ist. Die Idee stammt von einer Freundin, die mir dieses Wort freundlicherweise überlassen hat, sodass ich mir gleich mal die Domain penguineering.com reservieren konnte.

Seit gestern Abend ist unter http://tools.penguineering.com eine Sammlung von Tools zu finden, die in einzelner oder gemeinsamer Arbeit der Blog-Autoren entstanden sind und allgemein verfügbar sein sollen.

Die Seite sieht noch etwas mager aus, aber das wird sich im Lauf der Zeit ändern.

Ein Evolutions-Spiel und die Denkfehler des Kreationismus

Nachdem ich wieder einmal auf eine angeblich wissenschaftliche Begründung für die Unmöglichkeit der Evolution gestoßen bin, habe ich doch das Bedürfnis, mit den paar Denkfehlern aufzuräumen.

Denkfehler 1: Die Kreationisten behaupten, ein komplexer Organismus kann unmöglich durch zufälliges Zusammenstellen und Ändern von DNS entstanden sein.

Dieser Aussage schließe ich mich an. Der Fehler liegt in der Voraussetzung, die davon ausgeht, dass Evolution nur zufällige Änderung bedeutet. Die Annahme beschränkt sich auf die Mutation und ignoriert den weit wichtigeren Schritt, die Selektion.

Im Gegensatz zur Mutation ist Selektion keineswegs zufällig, sondern folgt dem Prinzip Survival of the fittest, also dem Überleben des Stärkeren beziehungsweise angepassteren. Während also die Mutation eine zufällige Änderung eines Individuums bewirkt, sorgt die Selektion dafür, dass nur Verbesserungen beibehalten werden.

Korrekt wäre es deshalb, zu sagen, dass Evolution ein Prozess zufälliger Verbesserungen ist.

Denkfehler 2: Die Kreationisten behaupten, dass Evolution nicht funktionieren kann, weil es sehr unwahrscheinlich ist, dass bei dieser zufälligen Verbesserung der Mensch herauskommt.

Diese Behauptung zeugt von einer gewissen Arroganz, nämlich in der Annahme, dass das Ziel der Evolution immer der Mensch sein müsse. Tatsächlich ist das aber nicht gegeben. Evolution hat kein Ziel in dem Sinne, sondern ist lediglich ein Prozess, bei dem die beteiligten Individuen von Generation zu Generation angepasster sind. Das geschieht durch die oben angesprochene zufällige Verbesserung.

In der Formalisierung der Evolutionstheorie spricht man von einer Fitness-Funktion, die angibt, wie gut ein Individuum angepasst ist. Einziges Ziel der Evolution ist, diese Fitness zu erhöhen.

Würde also der Evolutionsprozess auf der Erde noch einmal starten, käme sehr wahrscheinlich nicht der Mensch heraus. Mir ist aber auch kein Naturgesetz bekannt, nach dem die Erde irgendwann von Menschen bevölkert sein müsse.

Um die Vorgänge bei der Evolution etwas zu verdeutlichen, schlage ich folgendes Evolutionsspiel vor, das an einen “Beweis” der Kreationisten angelehnt ist:

Man nehme sechs Zettel, die mit den Zahlen 1 bis 6 beschrieben sind und lege sie in zufälliger Reihenfolge vor sich auf den Tisch. Weiterhin wird ein W6 (das ist ein “normaler” sechsseitiger Würfel, wie er in jedem gut sortierten Haushalt zu finden ist) benötigt.

Innerhalb der “Spielwelt” wird nun davon ausgegangen, dass diese sechs Zettel ein Individuum darstellen, das umso stärker ist, je besser die Zettel der größe ihrer Zahl nach geordnet sind.

Ein Spielzug besteht aus zwei Aktionen:

  1. Zuerst wird mutiert: Mit dem W6 wird zweimal gewürfelt. Die Zettel, deren Position der Würfel anzeigt, werden zum Vertauschen vorgemerkt. Mit ihnen soll das neue Individuum gebildet werden.
  2. Anschließend wird selektiert: Nur stärkere Individuen sollen überleben, deswegen werden die Zettel nur dann ausgetauscht, wenn anschließend der Zettel auf der niedrigeren Position auch die kleinere Zahl hat.

Wenn man Aktionen ein paarmal wiederholt, wird man sehen, dass die Zettel zunehmend in eine sortierte Reihenfolge gebracht werden. Wichtig ist hier der zweite Schritt, der verhindert, dass schwächere Individuen, also schlechter sortierte Zettelfolgen, sich durchsetzen können. Das ist der Schritt, der in der kreationistischen Denkweise unterschlagen wird.

Das Spiel macht auch deutlich, dass Evolution ein langwieriger Prozess ist. Während sich am Anfang recht schnell eine gewisse Ordnung einstellt, dauert es recht lange, bis wirklich alle Zettel ausgewählt wurden. Jedoch sind die Individuen der späteren Generationen recht stark, enthalten also kaum falsch sortierte Zahlen.