FastCGI und Standard Out

Gestern habe ich mich eine kleine Ewigkeit mit Ruby on Rails, RMagick und FastCGI geärgert.

Mit kleinen Schwierigkeiten habe ich meine ImageMagick Installation soweit gebracht, dass RMagick und Rails problemlos funktionierten.

Ziel war ein Imageupload mit anschliessender Verarbeitung durch RMagick. Da nicht immer eine temporäre Datei beim Upload ensteht, habe ich mich an ein Tutorial gehalten, wo folgende Code empfohlen wurde:

Magick::Image::read_inline(Base64.b64encode(feld.read)).first

Image::read_inline liest einen Base64 kodierten String. Soweit kein Problem, es funktionierte auch alles. Bis ich wieder auf Production und somit auf FastCGI umschaltete.

Die Anwendung stürzte nach dem Upload und der Verarbeitung der Bilder ab.

Im Apache error.log stand nur:

 FastCGI: comm with server "/Users/msimons/Entwicklung/rails/daily/public/dispatch.fcgi" aborted: error parsing headers: malformed header '/9j/4TseRXhpZgAASUkqAAgAAAALAA4BAgAgAAAAkgAAAA8BAgAFAAAAsgAA'

Drollig. Ich hab längere Zeit gesucht, bis ich den Hinweis fande, dass man beim FastCGI Prozess besser nicht ins Stdout schreibt. Genau das macht Base64.b64encode aber. Hatte mich schon geärgert, weil das verlangsamt das ganze natürlich bei großen Dateien.

Wenn ich obige Zeile in

Magick::Image::read_inline(Base64.encode64(feld.read)).first

ändere, ist alles in bester Ordnung. Der Malformed Header hatte ergo nichts mit RMagick zu tun. Toll.

| Comments (0) »

03-Oct-06


Spring und JNDI Datasources

Ich nutze gerade das J2EE Framework Spring zusammen mit Hibernate und Oracle für eine Webanwendung.

Die Hibernate DataSource kann entweder über eine DriverManagerDataSource und Angabe der Verbindungsparameter innerhalb der Webanwendung gesteuert werden, oder es kann eine JNDI Datasource des Application Containers (in dem Fall Tomcat) genutzt werden:

<bean id="serverDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
	<property name="jndiName"  value="java:comp/env/jdbc/blah"/>
</bean>

Der Trick dabei ist, den vollständigen Namen der DataSource anzugeben, also “java:comp/env/jdbc/blah” statt “jdbc/blah”, ansonsten bekommt nur “javax.naming.NameNotFoundException: Name jdbc is not bound in this Context” um die Ohren geschlagen, auch wenn man die DataSource im Tomcat konfiguriert hat.

Bah, das sowas immer soviel Zeit kosten muss….

| Comments (0) »

21-Sep-06


Der virtuelle Nachsendeauftrag

Passend zum vorherigen Eintrag Der Umzug ein kleiner HTTP Redirect Tipp:

Ich habe mich ein bisschen schlau gemacht, wie man der Welt im allgemeinen und Suchmaschinen im speziellen am besten mitteilt, dass sich eine URL geändert hat.

Der goldene Weg ist der entsprechende HTTP Header: 301, permanently moved. Das ist mit wenigen Zeilen PHP schnell erledigt:

<?php
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://info.michael-simons.eu");
	exit();
?>

Diese Methode ist auf jedenfall einem Refresh über Meta Tags vorzuziehen, da die Bots der Suchmaschinen so ihre Indizes aktualisieren.

In dem Zusammen stieß ich auf folgenden Artikel: Redirects using HTTP 301 headers. Dort wird anschaulich dagelegt, dass es für das Suchmaschinen Ranking einer Seite nicht gut ist, wenn z.B. www.michael-simons.eu auf www.michael-simons.eu zeigt, michael-simons.eu auf michael-simons.eu. Suchmaschinenbetreiber stufen dadurch teilweise beide Seiten schlechter ein, weil identischer Content über unterschiedliche Domains zu erreichen sind.

Das kann vermieden werden, indem entweder beide Domains auf michael-simons.eu verweisen oder beide auf www.michael-simons.eu. Beispiel: Wird www.michael-simons.eu als Zieladresse in den Browser eingegeben, landet man genauso auf michael-simons.eu, als wenn man es direkt eingibt. Umgekehrt ist es genauso in Ordnung.

Das Problem lässt sich durch einen Eintrag in die .htaccess Datei mit aktivierten mod_rewrite leicht lösen:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.michael-simons\.eu [nc]
RewriteRule (.*) http://michael-simons.eu/$1 [R=301,L]

| Comments (0) »

09-Sep-06


Umzug!

Es ist erstaunlich, so habe ich mein kleines Nerdblog noch nicht erlebt: Schnell, wie andere WordPressblogs sind.

Gehostet wird die Domain michael-simons.eu bei Tiggerswelt.net und davon profitiert jetzt auch Just another nerd blog, dass von msimons.info nach info.michael-simons.eu umgezogen ist.

So macht das Bloggen mit WordPress tatsächlich Spaß und deshalb wird hier in Zukunft auch öfter etwas erscheinen.

| Comments (4) »

08-Sep-06


Oracle JDBC Driver und AspectJ

Edit for non-german speakers:
This is a solution for “java.lang.ClassNotFoundException: oracle.security.pki.OracleWallet” or “java.lang.ClassNotFoundException: oracle.security.pki.OracleSecretStore”

The Oracle OJDBC driver is missing the two classes oracle.security.pki.OracleWallet and oracle.security.pki.OracleSecretStore. Normally not a problem but with a class loader that preloades all referenced classes, runtime will certainly fail. A work around is to create these to classes as stubs with the exact package name. That will do the trick.

Edit: As an alternative, you can add ${ORACLE_HOME}/jlib/oraclepki.jar to your classpath if you did a full install of a recent oracle client.

Der Oracle OJDBC Treiber hat mir mittlerweile schon mehr als einmal Ärger bereitet.

Der vorläufge Höhepunkt ist sein Nichtfunktionieren im Zusammenhang mit dem Load Time Weaving Class Loader aus dem AspectJ Projekt.

Dem normalen Java Classloader fällt es nicht auf, wenn ich per Class.forName “oracle.jdbc.driver.OracleDriver”, dass zwei Klassen fehlen: oracle.security.pki.OracleWallet und oracle.security.pki.OracleSecretStore. Dem Weaving Classloader hingegen schon.

Ich weiß nicht, was diese beiden Klassen machen, ich sehe nur, dass die entsprechende private Methode in OracleDriver unweigerlich auf einen Fehler laufen muss, so sie denn benutzt wird.

Jedenfalls, das Weaving schlägt fehl, bums, aus die Maus mit LTW Aspekten.

Auf dem Klo hatte ich die simple Idee, einfach in meinem Projekt obige Klassen leer anzulegen. Und siehe da: Wenn sie im Klassenpfad sind, kann ich OracleDriver instanzieren und alle sind glücklich.

Edit: Als Alternative kann man auch ${ORACLE_HOME}/jlib/oraclepki.jar zum Klassenpfad hinzufügen, falls man eine vollständige Installation eines halbwegs aktuellen Oracle Clients hat.

| Comments (3) »

26-Jul-06