Archive for the 'Computer Science' Category

Page 3 of 6

ICSE 2008

Schöne Grüße aus “Leipsch” von der ICSE 2008 (International Conference of Software Engineering). Wie auf dem Bild zu erkennen, haben wir hervorragendes sonniges Mai-Wetter. Das Westin-Hotel und natürlich die Konferenz sind erstklassig. Gestern habe ich einen weiteren Turing-Award-Preisträger (das ist der Nobelpreis für Informatiker) getroffen, nämlich Peter Naur, dessen BNF sicherlich schon so manchen Informatik-Studenten wie mir das Leben schwer gemacht hat. Hier das Foto vom Leipziger Messegelände :)

ICSE 2008

Verbinden von Apache und Tomcat

Auf dieser Seite finden Sie eine Anleitung zum Verbinden des HTTP-Servers Apache mit dem JSP-Server Tomcat auf dem Betriebssystem SuSE 9.1. Weitere Informationen zur Konfiguration des “Connector” finden Sie hier.

1. Schritt:
Wenn Sie die 32-bit-Version von SuSE 9.1 verwenden, müssen Sie diese *.so-Datei herunterladen und im folgenden Verzeichnis ablegen:

/usr/lib/apache2-prefork/

Falls Sie die 64-bit-Version von SuSE 9.1 einsetzen, können Sie auch diese *.so-Datei herunterladen und im folgenden Verzeichnis ablegen:

/usr/lib64/apache2-prefork/

In diesem HOWTO wird die Version 1.2 des JK-Moduls verwendet. Weiterhin wird davon ausgegangen, dass Apache >= 2 und Tomcat >= 5 eingesetzt werden und auf dem System eingerichtet sind.

2. Schritt:
Damit Apache und Tomcat miteinander über das AJP v1.3 (= Apache JServ Protocol, Version 1.3) kommunizieren können, müssen zunächst im Tomcat-Server so genannte Workers eingerichtet werden. Es empfiehlt sich, das dazugehörige HOWTO zu “überfliegen”, um einen kurzen Einstieg in dieses Thema zu erhalten.

Normalerweise müssen lediglich zwei Anpassungen in der workers.properties-Datei vorgenommen werden, da der Tomcat-Server bereits mit einer lauffähigen Standardkonfiguration ausgeliefert wird. Die workers.properties-Datei finden Sie hier:

/usr/local/tomcat-5.5.12/conf/workers.properties

Suchen Sie nach den beiden folgenden Einträgen (Homeverzeichnis des Tomcat-Servers und des Java-JDKs) und passen Sie diese an Ihre Systemumgebung an:

workers.tomcat_home=/usr/local/tomcat-5.5.12
workers.java_home=/usr/java/jdk1.5.0_05

Bitte beachten Sie, dass Sie ein JDK >= 1.5 einsetzen sollten. Andernfalls könnte es zu Problemen mit neueren Version des Tomcat-Servers kommen (u.a. Servlets).

3. Schritt:
Anschließend müssen Sie dem Tomcat-Server das JK-Modul anhand eines Listeners bekannt machen. Dazu ist es notwendig, die server.xml zu ändern. Die server.xml-Datei finden Sie hier:

/usr/local/tomcat-5.5.12/conf/server.xml

Fügen Sie innerhalb des Engine-Tags die folgende Zeile ein und passen Sie im Attribut mod_jk den Pfad zu Ihrem JK-Modul an (siehe Schritt 1). Starten Sie anschließend den Tomcat neu.

<engine>
    <listener className="org.apache.jk.config.ApacheConfig"
              modJk="/usr/lib64/apache2-prefork/mod_jk.so" />
</engine>

4. Schritt:
In den vorherigen Schritten haben Sie u.a. die JK-Datei ins Modulverzeichnis kopiert. Damit dieses Modul auch beim Starten des Apache-Servers geladen wird, müssen Sie die httpd.conf-Datei Ihrer Apache-Installation anpassen. Die httpd.conf-Datei finden Sie hier:

/etc/apache2/httpd.conf

Fügen Sie am Ende der Datei die folgenden Einträge hinzu und starten Sie anschließend auch den Apache-Server neu.

# JK-Modul laden
LoadModule jk_module /usr/lib64/apache2-prefork/mod_jk.so
 
# Tomcat-Workers einbinden
JkWorkersFile /usr/local/tomcat-5.5.12/conf/workers.properties
 
# Log-Datei, -Level und -Format festlegen
JkLogFile        /var/log/apache2/mod_jk.log
JkLogLevel       info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
 
# Optionen
JkOptions          +ForwardKeySize +ForwardURICompat +ForwardDirectories
JkRequestLogFormat "%w %V %T"

5. Schritt:
Überprüfen Sie die Log-Dateien im folgenden Verzeichnis auf mögliche Fehlermeldungen:

/var/log/apache2/

Sobald der Apache-Server fehlerfrei läuft, können Sie mit der Alias-Anweisung und dem JkMount-Befehl einzelne URL-Anfragen vom Port 80 (Apache) zum Port 8080 (Tomcat) weiterleiten. Dazu muss u.a. das Verzeichnis Ihrer Webapplikation dem Apache bekanntgemacht werden. Im folgenden Schritt wird daher als Beispiel die URL “/test” auf die Webapplikation “test” umgeleitet. Sie können dazu die folgenden Zeilen in Ihrer httpd.conf (siehe Schritt 4) hinzufügen.

Alias /test "/usr/local/tomcat-5.5.12/webapps/test"
 
<directory "/usr/local/tomcat-5.5.12/webapps/test">
    Options Indexes FollowSymLinks
    DirectoryIndex index.html index.htm index.jsp
</directory>
 
<location "/test/WEB-INF/*">
    AllowOverride None
    deny from all
</location>
 
<location "/test/META-INF/*">
    AllowOverride None
    deny from all
</location>
 
JkMount /test ajp13
JkMount /test/* ajp13

Tipp:
Wenn Sie alle Webapplikationen des Tomcat-Servers über den Apache-Server erreichen möchten, können Sie alternativ auch den JkAutoAlias-Befehl verwenden.

Siehe auch: Jakarta Tomcat Connector – Apache HowTo

Der erste iPhone System Crash

Schließlich musste es ja irgendwann mal passieren: Mein iPhone hatte seinen ersten System Crash! Wie sowas aussieht sieht man auf dem ersten Foto – wie sowas behoben wird auf dem zweiten Foto. Und da soll noch mal einer sagen, dass Apple Produkte nicht abstürzen. :(

iPhone1

iPhone2

Converting Data From Long Binary To String using OdbcDataReader

I’m currently migrating some data from an old Access database to a new MySQL database. So I have to write a converter application due to the incompatible data types in these RDBMS’s. More precisely the BLOB fields (OLE objects) within the Access DB should be transformed into string fields (varchar) in the MySQL DB. But how can you transform that data if the database connections are established by ODBC?

Here I’d like to give you a conversion method that takes an instance of an OdbcDataReader and the zero-based index of the field according to the current fetched row. At first I’m calling GetBytes with zero’s and NULL’s to determine the field-size of the Long Binary. By the way this purpose is really scarcely described in the MSDN documentation! After this I’m recalling GetBytes to retrieve the actual bytes. Finally the byte array is converted into a real string object. And of course, usually you have to check if index >= 0 and so on. But I omit that issue for reason of clarity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string GetLongBinary(OdbcDataReader reader, int index)
{
    // is field NULL?
    if (reader.IsDBNull(index))
        return string.Empty;
 
    // is field empty?
    long fieldSize = reader.GetBytes(index, 0, null, 0, 0);
    if (0 == fieldSize)
        return string.Empty;
 
    // read field content and convert to string            
    byte[] buffer = new byte[fieldSize];
    reader.GetBytes(index, 0, buffer, 0, buffer.Length);
    return Encoding.Default.GetString(buffer);
}

Enumerating Settings in .NET Applications

Today I’d like to give you a short example how to simply enumerate all current settings in your .NET application. Fortunately the following C# code snippet works for both application and user settings: :)

1
2
foreach (SettingsProperty sp in Properties.Settings.Default.Properties)
    Console.WriteLine(sp.Name + " = " + Properties.Settings.Default[sp.Name]);

First of all the detection of all property names is quit easy cp. sp.Name. However after this the query of the current property value is a bit tricky ’cause SettingsProperty only provides the attribute DefaultValue. As you remember the DefaultValue is the value you defined in Visual Studio and it can naturally differ if your customer change the config file by hand. So with the sample above properties can be determined at runtime using the property name as an index in Properties.Settings.Default.

Using Console in Windows Forms Applications

I’m currently working on a Windows Application that can be executed as a Forms as well as a Console Application. In this program I’m using the well-known Console.WriteLine() statements to log some stuff to the command prompt when running in console mode. Well, I know there is a much better way e.g. log4net but in this case it’s a sufficient solution.

When I ran the application via the console I was wondering ’cause Console.WriteLine() wrote nothing to the command prompt. Of course, the program is a Windows Application and there’s no plan for a console window. And that’s the cause why Console.WriteLine() is “disabled”.

But finally you can simply “enable” the console window by calling the Win32 API function AttachConsole / FreeConsole. All information for this purpose can be found at pinvoke.net.

Time Machine-Backups auf Netzwerkfreigaben

Apple’s Mac OS X 10.5 alias Leopard ist schon eine tolle Sache – besonders das integrierte Backup-Werkzeug namens Time Machine. Dummerweise können Sicherungen und Wiederherstellungen von Dateien derzeit nur auf lokalen Datenträgern durchgeführt werden, beispielsweise externe Festplatten, die direkt am USB-Port des Macs angeschlossen sind.

Offiziell werden Netzwerk-Backups erst mit Time Capsule unterstützt. Inoffiziell gibt es jedoch die Möglichkeit, Time Machine-Backups auf Netzwerkfreigaben (SMB, NFS, etc.) mit Bordmitteln zu aktivieren. Dazu muss nur ein Terminal geöffnet werden und das folgende Kommando eingegeben werden:

defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1

Dieser Befehl setzt letztendlich nur die Systemeinstellung, dass Time Machine auch nicht unterstützte Netzwerkmedien (Unsupported Network Volumes) anzeigen soll. Das war’s! :)

Patching ThickBox to support dynamically PHP-generated images

ThickBox is a very cool JavaScript to give your home page a famous Web 2.0 look and feel when displaying images. I love this tool, it’s so easy to use ’cause basically you must only declare the following html snippet (and of course include the CSS and JavaScript files before):

<a href="image.jpg" title="title" class="thickbox">
  <img src="image_thumbnail.jpg" alt="Image"/>
</a>

Unfortunately ThickBox support only static pictures out of the box. More precisely only image sources (img src) including the file extension “.jpg” etc. will be displayed correctly. Dynamically generated images e.g. that ends with “.php” will be displayed as follows:

<a href="image.php?id=1001" title="title" class="thickbox">
  <img src="image.php?id=1001&thumbnail=1" alt="Image"/>
</a>

ThickBox 1

So how can you teach ThickBox to support this type of pictures? This is very important if you create images on demand using PHP or if the image is on a location which is not within the document root (and must be loaded from disk e.g. for permission reasons). Just add the .php extension to the thickbox.js JavaScript file (line 65 and 68) as follows. Afterwards it will look perfectly.

65
66
67
68
69
70
var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$|\.php$/;
var urlType = baseURL.toLowerCase().match(urlString);
 
if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' ||
   urlType == '.gif' || urlType == '.bmp' || urlType == '.php'){
   //code to show images

ThickBox 2

Sending Mail within a Perl Script

Here comes a Perl script that uses a real SMTP connection for sending mail. That’s very useful e.g. if you want to send the result of a backup process via mail to the administrator. The only thing you have to do is complete the 5 variables server, sender, recipient, subject and message.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/perl
 
use Net::SMTP;
 
$server    = "localhost";
$sender    = "sender <sender\@host.tld>";
$recipient = "recipient\@host.tld";
$subject   = "Test";
$message   = "Hello World!";
 
$smtp = Net::SMTP->new($server);
$smtp->mail($sender);
$smtp->to($recipient);
$smtp->data();
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("From: $sender\n");
$smtp->datasend("To: $recipient\n");
$smtp->datasend("\n");
$smtp->datasend("$message");
$smtp->dataend();
$smtp->quit;

And here are two further hints:

  • Use the tag symbols inside the sender variable to define an additional real name for the mail address
  • Use the <STDIN> keyword to read text from the standard input to fill the subject or message variable

Simple Backup Shell Script

Here comes an example of a simple backup shell script that “tar“s the specified directory to an archive and uploads it on a FTP server using curl. Afterwards the local backup file will be removed. The only thing you have to do is define at least BACKUP_DATA, BACKUP_SERVER, BACKUP_USERNAME and BACKUP_PASSWORD.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/sh
 
# Name of the backup file
BACKUP_NAME="backup.tar.gz"
 
# Directory of the backup file
BACKUP_PATH="/tmp/"
 
# Directory + Name
BACKUP=${BACKUP_PATH}${BACKUP_NAME}
 
# Backup data
BACKUP_DATA="/home/username"
 
# Backup server
BACKUP_SERVER="ftp.backup.tld"
 
# Username and password
BACKUP_USERNAME="username"
BACKUP_PASSWORD="password"
 
# Execute backup
tar --exclude=${BACKUP} -czf ${BACKUP} ${BACKUP_DATA}
if [ "$?" -ne "0" ]; then
  echo "tar: Backup failed!"
  exit 1
fi
 
curl --upload-file ${BACKUP} ftp://${BACKUP_SERVER}\
--user ${BACKUP_USERNAME}:${BACKUP_PASSWORD}
if [ "$?" -ne "0" ]; then
  echo "curl: Backup failed!"
  exit 1
fi
 
rm ${BACKUP}
echo "Backup (" $(date) ") successful!"