Author Archive

Fehlerhafte Keymap in FreeNX-Session beheben

Nach dem Aufsetzen eines FreeNX-Servers stand ich vor dem Problem, dass im Client viele Tasten zu falschen Resultaten führten – insbesondere wurde die Taste AltGr als Enter interpretiert – keine Chance auf Sonderzeichen.

Der Fehler lässt sich dadurch beheben, dass man zunächst die Keymap des Client-Systems exportiert und diese anschließend (automatisiert) in der NX-Session lädt und die falschen Zuordnungen überschreibt.

Der erste Schritt besteht im Speichern der Keymap des Clients. Dazu führt man in einem XTerm den folgenden Befehl aus:

xmodmap -pke > nxclient.xmodmap

Dieser speichert die Keymap des Clients in der Datei nxclient.xmodmap; diese Datei muss man nun auf den NX-Server transferieren und sie bspw. in das Home-Verzeichnis des Benutzers legt. In einer geöffneten NX-Session kann man anschließend mit dem folgenden Befehl die falsche Keymap ersetzen:

xmodmap ~/nxclient.xmodmap

Natürlich lässt sich dies auch (eingeschränkt) automatisieren. Die Variable $NXSESSIONID wird bei einer Remote-Verbindung durch NX gesetzt. Überprüft man in seiner .profile, ob sie gesetzt ist, kann man die Keymap automatisch ersetzen:

if [ -n "$NXSESSIONID" ]; then
 /usr/bin/xmodmap ~/nxclient.xmodmap
fi

Dies funktioniert natürlich nur, wenn alle verbindenden Clients die gleiche Keymap nutzen.

Fehler in Eclipse beheben: RenderBadPicture Bug

Bei der aktuellen Version von Eclipse ist es auf meinem System urplötzlich dazu gekommen, dass die IDE nach dem Eintippen weniger Zeilen Programmcode abstürzt. Die einzige Fehlermeldung, die man erhält, ist eine Auflistung der Argumente, mit denen die abgestürzte JVM gestartet wurde.
Erst ein Blick auf die Konsole brachte mehr Licht ins Dunkel, den hier wird folgende Fehlermeldung angezeigt:

The program 'Eclipse' received an X Window System error.
This probably reflects a bug in the program.
The error was 'RenderBadPicture (invalid Picture parameter)'.
(Details: serial 43551 error_code 158 request_code 148 minor_code 7)
...

Eine Suche nach dem Stichwort RenderBadPicture förderte dann auch relativ schnell diesen Bugreport zutage. Scheinbar lädt Eclipse die falsche XULRunner-Komponente, die ihrerseits für das Rendern von HTML-Code innerhalb der IDE zuständig ist – in meinem Fall waren es scheinbar die bei Autocompletion auftauchenden Popups.

Die im Bugreport vorgeschlagene Hilfestellung hat zumindest in meinem Fall auf Anhieb funktioniert. Man muss Eclipse einfach direkt den Pfad zum zu verwendenen XULRunner mitteilen. Der Standardweg scheint zumindest im aktuellen openSUSE 11.3 über update-alternatives zu gehen, evtl. liegt hier auch das Problem.

Um Eclipse wieder ans Laufen zu bringen, muss man einfach die folgende Zeile in die eclipse.ini einfügen – allerdings erst nach der Zeile -vmargs !

-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/lib/xulrunner-1.9.2/xulrunner

Und für ein 64-bit-System sieht es wie folgt aus:

-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/lib64/xulrunner-1.9.2/xulrunner

Mittels wget eine dynamische Webseite in eine statische Struktur umwandeln

Oftmals erstellt man eine Webseite unter Nutzung eines dynamischen Systems, beispielsweise eines Content-Management-Systems, eines Wikis oder einer Blogsoftware. Viele dieser Seiten werden einige Zeit lang gepflegt und danach nicht mehr aktiv genutzt. Insbesondere bei dynamischen Systemen müsste man die Seite aus Sicherheitsgründen eigentlich vom Netz nehmen.

Um jedoch die Inhalte der Seite weiterhin verfügbar zu halten bietet es sich an, eine statische Kopie der Seite mittels wget zu erzeugen. Hier erhält man nur noch statische HTML-Dateien und muss sich um Sicherheit keine Sorgen machen.

Der folgende Befehl lädt die Inhalte der Domain example.com herunter und speichert sie im Ordner /tmp/example.com:

wget -nc -nH -E -r -k -P /home/you/example.com -np http://example.com/

Die Links werden entsprechend auf die neue Struktur umgeschrieben. Oftmals ist anschließend noch ein bisschen Handarbeit nötig, da wget in CSS-Anweisungen referenzierte Bilder nicht mitkopiert. Diese müssen somit manuell in das entsprechende Verzeichnis kopiert werden. Weitere Fehlerquellen sind Umlaute und Sonderzeichen in den ursprünglichen URLs (selten).

Mysqldump und die Fehlermeldung “Unknown command ‘\0′”

Sofern man versucht, einen von mysqldump erzeugten Datenbankdump in einen (anderen) MySQL-Server zu importieren, kann man unter Umständen auf folgende Fehlermeldung stoßen:

Unknown command '\0'

Die wahrscheinlichste Ursache sind Datenfelder vom Typ BLOB, welche mysqldump beim Speichern im Textformat nicht richtig kodiert hat.

Der einfachste Weg zur Umgehung dieses Problems besteht darin, bereits beim Exportieren der Datenbank die Option –hex-blob zu setzen:

mysqldump -ubenutzername -p --hex-blob datenbankname > datenbankname.sql

Damit erzeugt mysqldump für jeden BLOB eine hexadezimale Repräsentation, wie es beispielsweise auch bei phpMyAdmin seit geraumer Zeit Standard ist.

Den PHP-Fehler “Exception thrown without a stack frame in Unknown on line 0″ beheben

Wenn man viel mit (objektorientiertem) PHP arbeitet, stößt ab und an auf die wenig aussagekräftige Fehlermeldung “Exception thrown without a stack frame in Unknown on line 0“.

Dieser Fehler ist wenig hilfreich, insbesondere bricht die Programmausführung ab und man hat keine Möglichkeit zu erkennen, wo die Ursache der Meldung liegt. Ich habe diese Meldung häufig erhalten und nie versucht zu begreifen, was sie eigentlich bedeutet. Stattdessen habe ich solang am Code gepatcht, bis das Programm wieder lief. Für alle, die ähnliche Probleme haben, findet sich hier eine Übersicht der Ursachen dieser Meldung.

Solange PHP “normal” läuft, erzeugt es für jede geworfene Exception einen Stacktrace, bei nicht abgefangenen Exceptions wird dieser Stacktrace im Log ausgegeben. Es gibt jedoch bestimmte Zustände, in denen PHP noch nicht respektive nicht mehr vollständig läuft, in diesen Fällen ist es scheinbar nicht möglich, einen Stacktrace zu erzeugen. Die folgende (nicht vollständige) Liste enthält alle  Ursachen, die mir bisher untergekommen sind:

  • Eine Exception im benutzerdefinierten Exception-Handler werfen: Wen man in PHP mittels set_exception_handler() eine Funktion registriert, die ihrerseits eine weitere Exception wirft, kann PHP mit dieser nichts anfangen und gibt exakt die oben genannte Fehlermeldung aus.
    Somit ist es ratsam, im Exception-Handler sämtlichen Code in einen try-catch-Block zu verfrachten und etwaig auftauchende Exceptions beispielsweise mittels error_log() in den Log zu schreiben.
  • Im Konstruktor oder Destruktor Exceptions werfen: Eine Exception im Konstruktor sorgt dafür, dass das Objekt nicht vernünftig erzeugt wird, es wird somit in einem undefinierten Zustand hinterlassen. Im Destruktor hingegen kann es sein, dass das Objekt (oder andere, referenzierte Objekte) bereits nicht mehr existieren. Auch hier ist es ratsam, alle Funktionsaufrufe, die potentiell eine Exception werfen können, mit einem try-catch-Block zu umschliessen.
  • Exceptions im Autoloader: Es scheint nur teilweise der Fall zu sein, dass eine im mittels spl_autoload_register() registrierten Autoloader geworfene Exception ebenfalls diese Fehlermeldung erzeugt.

Diese Liste ist sicher noch nicht vollständig, sofern mir neue Ursachen unterkommen füge ich sie entsprechend ein.

Mittels CSS DIV-Elemente mit 100% Höhe erzeugen

Um in HTML ein DIV-Element zu erzeugen, welches tatsächlich die gesamte Höhe des Fensters ausfüllt, reicht es nicht, diesem per CSS die Höhe 100% zuzuweisen.

Zusätzlich müssen nämlich noch sämtliche Elternknoten die Höhe 100% annehmen, dazu gehören insbesondere die Element HTML und Body.

Der folgende CSS-Code zeigt, wie es richtig geht:

html{
  height: 100%;
}

body{
  height: 100%;
}

div#fullHeight{
  height: 100%;
}

Natürlich muss das DIV-Element in diesem Fall direkt unterhalb des BODY-Elements eingefügt werden, andernfalls ist auch für alle zwischenliegenden Knoten die Höhenangabe obligatorisch.

Ein Subversion-Repositories mittels svnsync spiegeln

Für einige Einsatzzwecke ist es erforderlich, ein komplettes Subversion-Repository zu spiegeln. Ein gutes Beispiel hierfür ist Trac, welches zumindest nach meinem Kenntnisstand derzeit nur auf lokale Repositories zugreifen kann.

Anstatt nun den gesamten Verzeichnisinhalt etwa per rsync synchon zu halten bietet es sich an, direkt auf Ebene des Subversion-Protokolls zu spiegeln. Dazu dient das Programm svnsync, welches in den Subversion-Pakete der meisten Distributionen enthalten sein sollte.

Im Folgenden wird davon ausgegangen, dass das entfernte Repository unter der Adresse http://example.com/svn verfügbar ist und ein Zugriff mit dem Benutzernamen svnsync möglich ist. Das Zielrepository soll in diesem Fall l0kal unter dem Pfad /srv/svnMirror vorliegen. Da Subversion die Protokolle transparent handhabt sollten auch beliebige Kombinationen mit http(s), ssh und file möglich sein.

Zunächst muss das lokale Repository mit leerem Inhalt angelegt werden:

svnadmin create /srv/svnMirror

Anschließend hat man die Wahl: Sofern aus das gespiegelte Repository keine weiteren Benutzer als der svnsync-Benutzer zugreifen, kann man gefahrlos die folgenden beiden Kommandos ausführen:

echo "#!/bin/bash" > /srv/svnMirror/hooks/pre-revprop-change
chmod u+x /srv/svnMirror/hooks/pre-revprop-change

Allerdings haben in diesem Fall alle Benutzer einen Vollzugriff auf das Verzeichnis, können insbesondere auch Revisionen löschen. Sofern also weitere Benutzer Zugriff auf die Kopie erhalten soll, empfiehlt es sich, die folgenden Zeilen in die Datei /srv/svnMirror/hooks/pre-revprop-change einzutragen und diese anschließend ausführbar zu machen:

#!/bin/sh
USER="$3"
if [ "$USER" = "svnsync" ]; then exit 0; fi
echo "Only the svnsync user can change revprops" >&2
exit 1

Mit dieser Kombination erhält nur der Benutzer svnsync den Vollzugriff.

Wie auch immer man sich entschieden hat, anschließend erfolgt eine initiale Synchronisation, hier muss man unter anderem das Passwort für den Zugriff eingeben:

svnsync init --username=svnsync /srv/svnMirror

Anschließend stößt man den Synchronisationsvorgang mit folgendem Befehl an:

svnsync /srv/svnMirror

Die erste Synchronisation kann, je nach Alter und Größe des entfernten Repositories, einige Zeit in Anspruch nehmen, da jede einzelne Revision sukzessive kopiert werden.

Auch für jede weitere Kopiervorgang benutzt man nun das obige Kommando, es empfiehlt sich in den meisten Fällen, dies in einen Cronjob einzutragen.

Den Fehler “no database selected” im Typo3 Installtool beheben

Die Typo3 version 4.3.3 scheint einen Fehler im Installtool aufzuweisen. Bei der Erstinstallation im 1-2-3-Mode werden auf der ersten Seite zunächst die Datenbankparameter abgefragt. Nach einem Klick auf Submit wird man auf eine Fehlerseite weitergeleitet, die nur folgende Meldung enthält:

no database selected

Außerdem werden in der localconf.php keinerlei Datenbankparameter hinterlegt und es gibt keine Möglichkeit, mit der Installation fortzufahren.

Ein einfacher Workaround hierzu ist es, die Datenbankparameter direkt in der Konfigurationsdatei einzufügen. Dazu öffnet man einfach die Datei typo3conf/localconf.php mit einem Texteditor und passt die folgenden Zeilen an die eigenen Gegebenheiten an:

$typo_db_username = 'user';
$typo_db_password = 'password';
$typo_db_host = 'localhost';
$typo_db = 'dbname';

Anschließend kann man die Fehlerseite im Installtool neu laden und die Installation mit dem Importieren des Datenbankdumps fortfahren.

Tipp: Falls man das Installtool schon weggeklickt hat oder nicht mehr im 1-2-3-Mode ist nutzt man den folgenden Link:

http://serveradresse/typo3/install/index.php?mode=123&step=2

Backticks in MySQL

Ich habe mich immer gefragt, warum bestimmte Programme wie phpMyAdmin in von ihnen generierten SQL-Queries immer Backticks verwenden, während andere System diese nie nutzen.

Der Grund dafür ist eigentlich sehr simpel und soll in einem kurzen Beispiel erläutert werden. Angenommen, innerhalb einer Datenbank soll folgende Tabelle erzeugt werden:

Table-1

Das ist in MySQL ein durchaus gültiger Tabellenname. Um nun den Inhalt dieser Tabelle aufzulisten würde man beispielsweise den folgenden Query nutzen:

SELECT * FROM Table-1;

Weit gefehlt, anstatt den Inhalt der Tabelle zu Gesicht zu bekommen erhält man eine Fehlermeldung wie “You have an error in your SQL syntax”. Wenn man sich den Query genauer ansieht wird man feststellen, dass dieser nicht eindeutig ist. Der Parser kann also nicht mit Sicherheit sagen, ob man die Tabelle Table-1 referenzieren möchte oder von einem Feld mit dem Namen Table die Eins subtrahieren möchte.

Um dem Parser genau zu erläutern, was gemeint ist, nutzt man einfach die Backticks, die den von ihnen eingeschlossenen Inhalt als Feld-, Tabellen- oder Datenbanknamen ausweisen:

SELECT * FROM `Table-1`;

Natürlich gilt gleiches auch für andere Feld- oder Datenbanknamen. Ein weiteres (beliebtes) Beispiel ist eine Tabelle, die ein Feld max oder min enthält. Hier ist sich MySQL nicht darüber im Klaren, ob die Funktionen MAX() respektive MIN() oder das entsprechende Feld gemeint ist.

Ein Hinweis für tippfaule Leute: Es ist durchaus möglich, die Backticks nur bei benötigten Teilen des Queries zu nutzen.

Typo3: Falsches Auslesen der PHP-Einstellung für safe_mode

Die derzeit aktuelle Typo3-Version 4.4.0 enthält einen Bug, durch welche Typo unter Umständen suggeriert, PHP würde im Safe Mode laufen obwohl es dies gar nicht tut.

Das Problem liegt im Abfragen der PHP-Einstellung, die in etwa wie folgt aussieht:

if(ini_get('safe_mode')){
  //Safe Mode ist aktiviert
}

Solange in der PHP- und Apache-Konfiguration eine 0 oder eine 1 für deaktivierten respektive aktivierten Safe Mode stehen, bereitet diese Abfragetechnik kein Problem. Allerdings ist es auch erlaubt, die Wörter “off ” oder “on” zu nutzen. Eine Einstellung wie diese

safe_mode=off

führt jedoch unweigerlich dazu, dass Typo3 fälschlicherweise einen aktiven Safe Mode erkennt, obwohl dieser deaktiviert ist.

Das Problem ist bereits in einem Bugreport vorhanden und sollte mit einer der nächsten Versionen gefixt werden.

Return top