Thursday, November 25, 2010

Die Prozess ID (PID) eines Prozesses unter Unix speichern - Beispiel ApacheDS

Immer wieder kommt es vor, dass Daemon-Prozesse ihre Prozess IDs nicht speichern können. Das hat den Nachteil, dass der Prozess später nicht mehr akkurat erkannt und beendet werden kann.

Zum Beispiel Apache Directory Server in der Version 1.5.4. Der proprietäre IBM Rational Directory Server für IBM Rational Synergy verlässt sich auf diese Version.

Das mitgelieferte .sh-Startskript ist unbrauchbar, weil nach dem Starten mit dem Bash-builtin $! nur die PID des Bash-Prozesses des Startskripts abrufbar ist. So kann die PID trotzdem gespeichert werden:
# ApacheDS implementiert in dieser Version keine PID Speicherung
# java Kommando aus der .sh Datei greppen
# Ausgabe ist ein ApacheDS logo, deshalb nach dev null
# Daemonisiert sich nicht ordentlich, deshalb muss STDERR auch nach dev null
$(grep ^java apacheds_1.5.4/apacheds.sh) >/dev/null 2>&1 &
echo $! > apacheds.pid

beim Beenden ist es dann möglich, diese PID gezielt zu killen. Hier bietet sich killproc an, weil es auch noch überprüft, ob die PID aus dem laufenden Linux Kernel zum Prozess "java" gehört:
/sbin/killproc -p apacheds.pid -TERM /pfad/nach/jre/bin/java

Problem gelöst. Für ApacheDS werden neuere Versionen sicher eine bessere Lösung bieten, zum Beispiel durch ein neues Installationslayout.

Monday, November 22, 2010

Google App Engine: Packliste Webapp Alpha

Nach etwas Arbeit habe ich endliche eine funktionierende Version online bekommen: Packliste Webapp Alpha (Disclaimer: keine vollständige Packliste, alpha)

Google App Engine ist ein kostenloser Hoster für Web Anwendungen. Die Free Quotas sind meiner Meinung nach sehr groß und sollten für die Packliste reichen. Wer für App Engine programmiert darf sich erstmal zwischen Java und Python entscheiden.

Java kenne ich schon und deshalb habe ich mich für Python und Django als Template Engine entschieden und dabei gelernt, dass Django auf Google etwas anders ist. Inzwischen finde ich mich in den Templates zurecht und kann produktiv sein.

Sehr schön ist das Framework jQuery Mobile. Es stellt das komplette Interface bereit und kümmert sich um Gerätekompatibilität. Gleichzeitig sind damit auch alle jQuery Funktionen verfügbar.

Aktuelle Funktionen meiner App:
- Anzeigen einer Packliste
- Packstücke einpacken -> durchstreichen und nach Unten bewegen
- AJAX-Onlinezähler zum Registrieren der Packhäufigkeit
- Hinzufügen von Items

TODO:
- HTML5 Local Storage für gepackte Teile
- Kategorisierung / Übersichtlichkeit
- Umwandlung in native App

Für Ideen und Verbesserungsvorschläge bin ich dankbar.

Danke an Charlotte für die Idee und an die Google Tools User Group München und das Bootcamp 2010 für die erste Android App, die zu dieser App geführt hat.

Tuesday, November 16, 2010

App-Programmierung - Web oder Nativ? Marktforschung

Am Anfang steht eine Idee: Eine Packliste, die Intelligent ist. Die mir beim Kofferpacken genau das anzeigt was am wichtigsten ist und dabei die Intelligenz der Massen nutzt.


Web oder Nativ?

Wie programmiert man heute Apps? In Java für Android oder in Objective-C fürs iPhone? Ich habe mir beides angesehen und eine Java-Android Applikation für meine Packliste geschrieben.

Allerdings will ich weder Android noch iPhone bevorzugen. Dafür gibt es Webapps. Diese können heute dank HTML5 auch offline-fähig sein. Und zum Bereitstellen für den Android oder iPhone Store kann man apparat.io oder thephonegap verwenden. Wenn man das überhaupt will, da beide derzeit Eintrittsgebühren verlangen. Vielleicht ist der Cydia Appstore besser.

Welches Framework für Web?

Zur Zeit gibt es für mobile App Entwicklung 2 große Frameworks, JQTouch von Sencha Labs und Jquery Mobile, die sich vor allem in der Lizenz unterscheiden. JQTouch bietet nur die GPL und JQuery Mobile auch alternative Lizenzen. Meine Wahl: JQuery Mobile.

Gibt es überhaupt einen Markt für eine Packliste Applikation?

Eine kleine Erkundungstour über Google Trends zeigt, dass das Suchvolumen nach Packliste sehr gering ist. Das englische "packing list" wird 10 mal häufiger gesucht. Vielleicht eine bessere Wahl als Titel?

Was bietet die Konkurrenz?

Selbst bei kostenlosen Apps will ich mir die Konkurrenz anschauen um nicht unnötigerweise Dinge zu duplizieren.

Für iPhone ist die Mammut Packing List sehr beliebt
http://www.mammut.ch/en/packinglist.html

Für Web-Anhänger gibt es eine universal packing list, die allerdings ein etwas betagtes Design hat:
http://upl.codeq.info

Und dann hat sich noch jemand an ein modernes webbasiertes Packlistenmanagement gewagt, allerdings sind dort bisher keine Inhalte hinterlegt.
http://www.packliste.org/

Ich denke da ist noch Platz für eine benutzerfreundliche, intelligente Packliste.

Sunday, November 7, 2010

Eclipse Tips For Android Programming

A small collection of Eclipse Android tips I found for little problems before Google Dev Day 2010 PreHackathon

Eclipse is quite slow in the default configuration. Quick tip:
edit (your eclipse dir)/opt/eclipse/Eclipse.app/Contents/MacOS/eclipse.ini
change
-Dosgi.requiredJavaVersion=1.5
into
-Dosgi.requiredJavaVersion=1.6
http://www.inteism.com/2010/05/how-to-speed-up-eclipse-on-os-x-10-6-snow-leopard/

Eclipse Android creates the R.class file on its own. You can remove it or use Menu - Project - Clean and it will be recreated. Good idea to do this from time to time.
http://stackoverflow.com/questions/3796490/error-unable-to-open-class-file-r-java
If you get Android Packaging Problem also use Menu - Project - Clean

Make sure you have the project selected when running build all, and not some resource
http://soft-dev-pro.blogspot.com/2010/03/android-mainoutxml-error.html


Make sure you create resources before using them or you will get Error: No resource found that matches the given name
http://brainflush.wordpress.com/2009/03/15/understanding-android-themes-and-styles/

AndroidManifest Activity Name should always be kept in sync with the classname:
http://stackoverflow.com/questions/3361896/runtime-exception-in-android-junit-testing 

Saturday, November 6, 2010

UNIX: Fehler finden mit Strace

Oft reicht die Fehlersuche über Logmeldungen nicht aus, um einen Fehler zu beheben. Dann ist ein kontrolliertes Ausführen des Programms in einem Debugger erforderlich. Dafür sind debug-Symbole nötig, und meist ein Neubau erforderlich.

Ohne debug-Symbole können allerdings auch schon nützliche Informationen mit "strace" gewonnen werden. Das Programm zeigt alle "System Calls" einer Applikation auf. Meist ist dann im Fehlerfall schon zu erkennen, welche Datei geöffnet wird oder wo genau der Fehler tatsächlich entsteht.

Natürlich muss ein Daemon vorher im Vordergrund ausgeführt werden, um die strace Befehle zu sehen. Konkret habe ich das verwendet um PPTPd in Freetz zu debuggen, siehe Dokumentation im Freetz-Wiki.

Einfaches Beispiel der Strace-Verwendung:

# strace echo 3
execve("/bin/echo", ["echo", "3"], [/* 15 vars */]) = 0
brk(0)                                  = 0x1ec03000
uname({sys="Linux", node="unknown-namer", ...}) = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb3aa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=42988, ...}) = 0
mmap(NULL, 42988, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aeadb3ac000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\355\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1432968, ...}) = 0
mmap(NULL, 3541032, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aeadb5ac000
mprotect(0x2aeadb704000, 2093056, PROT_NONE) = 0
mmap(0x2aeadb903000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x157000) = 0x2aeadb903000
mmap(0x2aeadb908000, 18472, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2aeadb908000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb90d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadb90e000
arch_prctl(ARCH_SET_FS, 0x2aeadb90db20) = 0
open("/dev/urandom", O_RDONLY)          = 3
read(3, "(\333\372\211\343\357\201", 7) = 7
close(3)                                = 0
mprotect(0x2aeadb903000, 16384, PROT_READ) = 0
mprotect(0x2aeadb5a9000, 4096, PROT_READ) = 0
munmap(0x2aeadb3ac000, 42988)           = 0
brk(0)                                  = 0x1ec03000
brk(0x1ec24000)                         = 0x1ec24000
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3927616, ...}) = 0
mmap(NULL, 3927616, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aeadb90f000
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aeadbcce000
write(1, "3\n", 23
)                      = 2
close(1)                                = 0
munmap(0x2aeadbcce000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?

Tuesday, November 2, 2010

Fritzbox Rettungsupdate Freetz Recover mit Push_Firmware

Über einen kleinen eingebauten FTP-Server, der nur beim Booten aktiv ist, kann man auch die Fritzbox Firmware updaten:
# ./tools/push_firmware images/neues_firmware.image
(box neustarten)
Dabei gingen meine Firmware-Einstellungen nicht verloren.

Auf Mac OS X funktionierte bei mir nur ncftp zum kopieren und ich musste im Skript auch noch einige Änderungen bei uname und mktemp vornehmen, weil die BSD-Apps vom Mac hier strikter sind.

Ich verwende gerne die neueste Version des Fritzbox-Mods Freetz, den so genannten SVN Trunk. Die Bleeding-Edge Version wird laufend aktualisiert und enthält stundenaktuelle Neuerungen, ist deshalb allerdings auch extrem instabil.

Zum Beispiel im Changeset 6093 wurde ein Bug aus 6078 vorerst revertet. Ich habe allerdings dazwischen eine neue Firmware gebaut und eingespielt - danach startete die Box nicht mehr neu. Ein Recover half mir wieder ins Internet.