<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cogito Ergo Blog</title>
	<atom:link href="http://cogito-ergo-blog.de/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://cogito-ergo-blog.de/blog</link>
	<description>Technical articles related to Java, HomeCinema PCs</description>
	<lastBuildDate>Sun, 15 Apr 2012 17:32:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Audible Hörbücher in MP3 wandeln mit Tags und Kapiteln</title>
		<link>http://cogito-ergo-blog.de/blog/2012/04/15/audible-horbucher-in-mp3-wandeln-mit-tags-und-kapiteln/</link>
		<comments>http://cogito-ergo-blog.de/blog/2012/04/15/audible-horbucher-in-mp3-wandeln-mit-tags-und-kapiteln/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 17:29:58 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10119</guid>
		<description><![CDATA[Seit Audible zu Amazon gehört, bin ich mal wieder Audible-Kunde. In der Tat gibt es hier das eine oder andere Schnäppchen zu machen. Immer noch ärgerlich: das Audible eigene Dateiformat, was sich nur mit den Audible Software-Playern abspielen läßt. Einziger &#8230; <a href="http://cogito-ergo-blog.de/blog/2012/04/15/audible-horbucher-in-mp3-wandeln-mit-tags-und-kapiteln/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit Audible zu Amazon gehört, bin ich mal wieder Audible-Kunde. In der Tat gibt es hier das eine oder andere Schnäppchen zu machen.</p>
<p>Immer noch ärgerlich: das Audible eigene Dateiformat, was sich nur mit den Audible Software-Playern abspielen läßt. Einziger Vorteil: die Kapitelnavigation.</p>
<p>Nun gibt es Möglichkeiten die Audible-Formate nach mp3 zu konvertieren. Am einfachsten geht das mit dem &#8220;alten&#8221; 4er Format (Datei-Endung .aa). Für dieses gibt es noch einen DirectShow-Filter (<em>AudibleMediaPlayerFilter</em>.<em>exe) </em>über den sich mit Programmen wie Goldwave oder anderen direkt ein grosses MP3-File erzeugen läßt.</p>
<p>Wie ich erst gestern gefunden habe, gibt es <a href="http://www.hydrogenaudio.org/forums/index.php?s=&amp;showtopic=87677&amp;view=findpost&amp;p=749475">Programme</a> die aus .aa oder .aax auch noch die Kapitel Informationen extrahieren, da diese auch vergleichsweise einfach (weil unverschlüsselt) auszulesen ist.</p>
<p>Damit kann man dann ein .cue Sheet für MP3DirectCut erstellen e voila schon hat man kapitelweise geschnittene MP3s aus dem langen Hörbuch gemacht.</p>
<p>Ein einfacher Converter, der Zeilen im Format HH:MM:SS einliest und ein fertiges CUE-File schreibt, sieht in Java so aus:</p>
<pre class="brush: java; title: ; notranslate">
    public void convert(String[] args) {
        try {
            PrintStream cue = new PrintStream(new File(args[0]+&quot;.cue&quot;));
            BufferedReader r = new BufferedReader(new InputStreamReader( new FileInputStream(args[0]),&quot;Cp1252&quot;));
            String line;
            String name = new File(args[0]).getName();
            String title = args[1];
            String artist = args[2];

            name = name.substring(0,name.lastIndexOf(&quot;.&quot;));
            cue.format(&quot;PERFORMER \&quot;%3$s\&quot;\r\n&quot; +
            		&quot;TITLE \&quot;%2$s\&quot;\r\n&quot; +
            		&quot;FILE \&quot;%1$s.mp3\&quot; MP3\r\n&quot;,name,title,artist);
            int i = args.length&gt;3?Integer.parseInt(args[3]):1;
            while( ( line = r.readLine() ) != null ) {
                String p[] = line.split(&quot;:&quot;);
                int m = Integer.parseInt(p[0])*60 + Integer.parseInt(p[1]);
                int s = Integer.parseInt(p[2]);
                cue.format(&quot;  TRACK %1$02d AUDIO\r\n&quot; +
                		&quot;    TITLE \&quot;(Track %1$02d)\&quot;\r\n&quot; +
                		&quot;    INDEX 01 %2$02d:%3$02d:00\r\n&quot; +
                		&quot;&quot;,i,m,s);
                i++;
            }
            r.close();
            cue.close();
        } catch( Exception e) {
            e.printStackTrace();
        }
    }
</pre>
<p>Dieses CUE-File läßt sich in MP3DirectCut als Projekt laden und mit &#8220;Split save &#8230;&#8221; werden die einzelnen MP3-Files erzeugt, gleich mit richtigem Namen und ID3 Tags.</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2012/04/15/audible-horbucher-in-mp3-wandeln-mit-tags-und-kapiteln/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Untertitel und Kapitel für MKV erzeugen mit DVDate</title>
		<link>http://cogito-ergo-blog.de/blog/2012/03/20/untertitel-und-kapitel-fur-mkv-erzeugen-per-dvdate/</link>
		<comments>http://cogito-ergo-blog.de/blog/2012/03/20/untertitel-und-kapitel-fur-mkv-erzeugen-per-dvdate/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 20:53:30 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[chapter]]></category>
		<category><![CDATA[dvdate]]></category>
		<category><![CDATA[kapitel ´]]></category>
		<category><![CDATA[mkv]]></category>
		<category><![CDATA[srt]]></category>
		<category><![CDATA[untertitel]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10111</guid>
		<description><![CDATA[Wenn man &#8211; wie ich &#8211; noch viele alte miniDV Kasetten hat und vor der Herausforderung steht diese Archivieren zu müssen, hat man ein Problem: was ist nur alles drauf auf den ganzen Kassetten? Meine Lösung: Komplett per Firewire auf &#8230; <a href="http://cogito-ergo-blog.de/blog/2012/03/20/untertitel-und-kapitel-fur-mkv-erzeugen-per-dvdate/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wenn man &#8211; wie ich &#8211; noch viele alte miniDV Kasetten hat und vor der Herausforderung steht diese Archivieren zu müssen, hat man ein Problem: was ist nur alles drauf auf den ganzen Kassetten?</p>
<p>Meine Lösung: Komplett per Firewire auf den Rechner, dann mit x.264 komprimieren und nun als MKV speichern. Der Inhalt erschließt sich so aber immer noch nicht.</p>
<p>Da viel mir ein, dass miniDV ja einen DateCode schreibt, zu jeder Aufnahme also weiss, wann sie gemacht wurde. Etwas Googeln liefert das Tool DVDate, was diese Daten ans Licht bringt.</p>
<p>Damit lassen sich Szenen auffinden und man hat auch wieder die Information, wann etwas aufgenommen wurde.</p>
<p>Die Idee: erzeuge eine OGM Kapitel Datei und eine SRT Untertitel Datei und packe das Ganze mit mkvmerge in eine einzige MKV Datei.</p>
<p>Ein kleiner Converter in Java erzeugt die beiden Files. Einfach die Scenen als Text exportieren und den Converter mit &#8220;java -jar ChapConvert.jar bla_scn.txt&#8221; auf rufen und schon werden die Files erzeugt.</p>
<p>Zuvor sollte man allerdings den Scene-Editor von DVDate nutzen und die Scenen benennen. Mindestens eine Zeitstempel mit &#8220;%D&#8221; ist Pflicht. Wer sich die Mühe macht echte Namen zu vergeben, findet die Namen als Kapitelname und auch in den Untertiteln wieder.</p>
<p>Hier gibt das <a href="http://cogito-ergo-blog.de/blog/wp-content/uploads/ChapConvert.jar_.zip">ChapConvert.jar</a></p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2012/03/20/untertitel-und-kapitel-fur-mkv-erzeugen-per-dvdate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring Dependency Graph mit yEd / Graphml</title>
		<link>http://cogito-ergo-blog.de/blog/2012/03/05/spring-dependency-graph-mit-yed-graphml/</link>
		<comments>http://cogito-ergo-blog.de/blog/2012/03/05/spring-dependency-graph-mit-yed-graphml/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 08:54:05 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Spring Dependency Graph yEd Graphml]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10083</guid>
		<description><![CDATA[Wenn man ein fremdes Projekt, was mit Spring gemacht ist, zum ersten Mal anschaut, ist es nicht leicht sich einen Überblick zu verschaffen. Insbesondere die Abhängigkeiten der SpringBeans untereinander sind nicht leicht zu überschauen. Verschiedene IDE Integrationen versprechen Abhilfe. Die &#8230; <a href="http://cogito-ergo-blog.de/blog/2012/03/05/spring-dependency-graph-mit-yed-graphml/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wenn man ein fremdes Projekt, was mit Spring gemacht ist, zum ersten Mal anschaut, ist es nicht leicht sich einen Überblick zu verschaffen. Insbesondere die Abhängigkeiten der SpringBeans untereinander sind nicht leicht zu überschauen.</p>
<p>Verschiedene IDE Integrationen versprechen Abhilfe. Die Spring Tool Suite (STS) kann beispielsweise einen Abhängigkeitgraphen anzeigen, allerdings erlebt man eine Enttäuschung wenn man dies mit einem auch nur halbwegs ernsthaften Projekt versucht.<span id="more-10083"></span>Das Ergebnis ist enttäuschend: man sieht schlicht nichts, das Layout der Beans ist starr und die Kanten, die die Abhängigkeiten darstellen, laufen wild durch den Graphen. Man kann nicht mal erkennen, welcher Knoten mit welchem verbunden ist.</p>
<p>Die Möglichkeiten mit einem Graph zu arbeiten und so Übersicht zu erzeugen fehlt komplett. Wenn man hier den Luxus eines Werkzeugs wie yEd gewohnt ist, der vielfältige Möglichkeiten bietet, ist die Lösung schnell gefunden:</p>
<p>Man generiert einen Graphen im graphml Format, um ihn dann mit yEd bearbeiten zu können. Das ist, mit einem Satz gesagt, das was die angehängte Klasse tut.</p>
<p>Der Spring-Context wird mit Spring selbst gelesen und analysiert und dann wird ein graphml File ausgegeben. Dieses muss zu Beginn mindestens einmal durch einen Layout-Algorithmus (am besten Hierachisch), weil sonst alle Knoten übereinander liegen.</p>
<p>Mit einer Property-Datei kann man die Knoten noch automatisch einfärben, um bestimmte Knotentypen zu unterscheiden.</p>
<p>Den Quellcode gibts hier <a href="https://github.com/sker65/Spring-Dependency-Graph">SpringDependencyGraphGenerator</a>.</p>
<p>Mit dem yEd lassen sich mit dem fertigen Graphen auch noch weitere nützliche Dinge anstellen. So kann man z.B. ganz leicht Untergraphen erzeugen, die nur Vorgänger oder nur die Nachfolger eines Knotens zeigen.<a href="http://cogito-ergo-blog.de/blog/wp-content/uploads/graph-all-ausschnitt.jpg"><img class="alignright size-medium wp-image-10106" title="graph-all-ausschnitt" src="http://cogito-ergo-blog.de/blog/wp-content/uploads/graph-all-ausschnitt-300x159.jpg" alt="" width="300" height="159" /></a></p>
<p>Wie schlecht die Bilder mit STS werden können zeigt dieser Ausschnitt:</p>
<p>Einen Graphen der mit yEd layoutet wurde sieht man unten. Mit Hilfe der Vorgänger-Funktion sind in einem zweiten Bild nochmal die Abhängigkeiten einer DataSource herausgestellt.<a href="http://cogito-ergo-blog.de/blog/wp-content/uploads/graph-komplett.jpg"><img class="alignright size-medium wp-image-10107" title="graph-komplett" src="http://cogito-ergo-blog.de/blog/wp-content/uploads/graph-komplett-300x168.jpg" alt="" width="300" height="168" /></a><a href="http://cogito-ergo-blog.de/blog/wp-content/uploads/neu2.jpg"><img class="alignright size-medium wp-image-10108" title="neu2" src="http://cogito-ergo-blog.de/blog/wp-content/uploads/neu2-160x300.jpg" alt="" width="160" height="300" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2012/03/05/spring-dependency-graph-mit-yed-graphml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debuggen bei der JDBC Programmierung</title>
		<link>http://cogito-ergo-blog.de/blog/2012/02/02/jdbc-programmierung-debugger/</link>
		<comments>http://cogito-ergo-blog.de/blog/2012/02/02/jdbc-programmierung-debugger/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 18:47:47 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jdbc]]></category>

		<guid isPermaLink="false">http://euve3303.vserver.de/stefan/blog/?p=92</guid>
		<description><![CDATA[Schon zum zweiten Mal in den letzten drei Monaten hat mich ein Projektauftrag wieder tief hinunter an die Datenbank-Persisitenz geführt, wo noch richtige SQL-Statements im Code zu finden sind Für eigene Projekte und insbesondere auch für das Einarbeiten in fremde &#8230; <a href="http://cogito-ergo-blog.de/blog/2012/02/02/jdbc-programmierung-debugger/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Schon zum zweiten Mal in den letzten drei Monaten hat mich ein Projektauftrag wieder tief hinunter an die Datenbank-Persisitenz geführt, wo noch richtige SQL-Statements im Code zu finden sind <img src='http://cogito-ergo-blog.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Für eigene Projekte und insbesondere auch für das Einarbeiten in fremde Projekte ist es da sehr nützlich, wenn man genau sieht, was auf der Datenbank so alles passiert.</p>
<p>Hier hilft das Tool <a href="http://code.google.com/p/log4jdbc-remix/">log4jdbc-remix</a> sehr gut weiter, weil es sowohl alle Anfragen als auch die Ergebnisse mitschreiben kann. Es lassen sich auch eigene LogFormatter integrieren und selbst der Umgang mit mehreren Datenbanken ist in der neusten Release 0.2.8 kein Problem.</p>
<p>Da ich selbst auch schon über ein paar kleinere Probleme gestolpert bin, kann ich ausserdem den guten Entwickler-Support unterstreichen: Jedesmal hat Tim, der Owner des Projekts, sehr schnell reagiert und das Problem beseitigt oder einen Patch übernommen.</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2012/02/02/jdbc-programmierung-debugger/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Energiesparlampen / LED Leuchtmittel</title>
		<link>http://cogito-ergo-blog.de/blog/2012/01/31/energiesparlampen-led-leuchtmittel/</link>
		<comments>http://cogito-ergo-blog.de/blog/2012/01/31/energiesparlampen-led-leuchtmittel/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 15:20:10 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10080</guid>
		<description><![CDATA[Neulich wollte ich etwas für mein Ökogewissen tun und einige der stromfressende Halogenlampen (12V GU5.3) durch LED-Leuchtmittel ersetzen. Zufällig fand ich welche von NBS angeboten mit nominellen 210 Lumen bei 3 W und der Farbe warmweiss. Das zu einem Preis &#8230; <a href="http://cogito-ergo-blog.de/blog/2012/01/31/energiesparlampen-led-leuchtmittel/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Neulich wollte ich etwas für mein Ökogewissen tun und einige der stromfressende Halogenlampen (12V GU5.3) <img class="alignright size-thumbnail wp-image-10081" title="halogen-gu53" src="http://cogito-ergo-blog.de/blog/wp-content/uploads/halogen-gu53-150x150.jpg" alt="" width="150" height="150" /> durch LED-Leuchtmittel ersetzen. Zufällig fand ich welche von NBS angeboten mit nominellen 210 Lumen bei 3 W und der Farbe warmweiss. Das zu einem Preis von unter 10 Euro was mir ein guter Preis zu sein schien.</p>
<p>Mit dem Kauf der Lampen ging allerdings der Spass erst los &#8230;<span id="more-10080"></span>Bei uns im Haus gibt es nämlich viele solcher Halogenlampen als Einbauleuchten in der Decke. Das erste, was ich feststellen mußte, war, dass die neuen LEDs die Normmasse gar nicht einhalten.</p>
<p>Was bei manchen Leuchten nicht sonderlich stört, ist bei Einbauleuchten u.U. fatal, weil die LEDs schlicht nicht reinpassen.</p>
<p>Das nächste Ärgernis ist der eigentlich erwünschte geringe Energieverbrauch! Meinst sind bei Halogenbeleuchtungen nämlich elektronische Trafos verbaut (Schaltnetzteile), die eine gewisse Mindestleistungsabnahme benötigen. Wird zuwenig Strom verbraucht, dann beginnt die Spannung zu schwanken und die Netzteile laufen gefahr mit der Zeit zerstört zu werden.</p>
<p>Eingebaute LED Leuchtmittel quittieren solche Spannungsschwankungen mit einem hässlichen Flackern, schlimmer wie jede Neonröhre. Also musste ich auch noch die Netzteile austauschen, die freilich in der Zwischendecke versteckt und nur mit erhöhtem Aufwand zu erreichen waren.</p>
<p>Bleibt noch, dass LEDs immer noch nicht dimmbar sind und auch die Lichtfarbe &#8211; auch die sogenannten Warmweissen &#8211; leider nicht mit dem angenehmen Licht einer Halogenlampe mithalten können.</p>
<p>Soviel zum Thema Ernergiesparlampen / LEDs.</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2012/01/31/energiesparlampen-led-leuchtmittel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cassandra CQL mit JDBC-Driver</title>
		<link>http://cogito-ergo-blog.de/blog/2011/12/16/cassandra-cql-mit-jdbc-driver/</link>
		<comments>http://cogito-ergo-blog.de/blog/2011/12/16/cassandra-cql-mit-jdbc-driver/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 19:11:51 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10072</guid>
		<description><![CDATA[Hatte endlich mal Gelegenheit mich mit einer NoSQL Datenbank zu beschäftigen: Cassandra von Apache. Allerdings fühlte ich mich aus Anwender &#8211; in meinem Fall also Anwendungsprogrammierer &#8211; in die Steinzeit der Datenbankprogrammierung zurückversetzt: es gibt nur proprietäre Schnittstellen und die sind auch &#8230; <a href="http://cogito-ergo-blog.de/blog/2011/12/16/cassandra-cql-mit-jdbc-driver/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hatte endlich mal Gelegenheit mich mit einer NoSQL Datenbank zu beschäftigen: Cassandra von Apache. Allerdings fühlte ich mich aus Anwender &#8211; in meinem Fall also Anwendungsprogrammierer &#8211; in die Steinzeit der Datenbankprogrammierung zurückversetzt: es gibt nur proprietäre Schnittstellen und die sind auch nicht abgekündigt (Thrift). Selbst Apache empfiehlt auf ein abstrakteres API wie zum Bespiel Hector zu setzen.</p>
<p>Leider fühlt sich auch Hector in keiner Weise so an wie man es von konventioneller Datenbank-Programmierung gewohnt ist. Das Java-API ist nach meinem Geschmack &#8220;gewöhnungsbedürftig&#8221; um es einmal diplomatisch auszudrücken.</p>
<p>Dabei gibt mit Spring-JDBC (oder neuerdings mit Spring-Data) längst gute Beispiele wie man es gut machen kann. Jetzt kann man natürlich einwenden, dass diese &#8220;alten&#8221; Ansätze für SQL-Datenbanken gemacht sind und sich daher nicht für NoSQL Lösungen eignen, aber wenn man zweimal hinsieht, dann merkt man schnell, dass das gar nicht stimmt.</p>
<p><span id="more-10072"></span>Der Unterschied bei der Sicht auf die Daten besteht meiner Meinung nach im Wesentlichen im Datenmodell, oder in der Art wie man zum Datenmodell kommt: entweder klassisch relational und normalisiert, oder Abfrage-Orientiert und de-normalisiert.</p>
<p>Wenn das Datenmodell aber steht, ließe sich mit den Daten eigentlich genauso arbeiten wie mit SQL-Datenbanken: über eine Abfrage-Sprache. Im Falle von Cassandra ist das CQL. Parallelen gibt es mit Keyspace = Database, ColumnFamily = Tabelle, und Column / Row genug. Die Einschränkungen / Erweiterungen con CQL sind eben der Datenbank geschuldet (z.B. kein Join) und stören erst mal nicht, wenn man sich für das NoSQL Modell entschieden hat.</p>
<p>Jetzt gibt es mit Cassandra-JDBC sogar einen JDBC-Treiber für Cassandra, der auch CQL über JDBC in jeder Java-Anwendung verfügbar macht. Man sollte also meinen alles Handwerkzeug in Händen zu halten, um &#8220;vernünftig&#8221; arbeiten zu können.</p>
<p>Leider ist dem im aktuellen Release 1.0.5 (Dez 2011) von Cassandra nicht so.</p>
<p>Die Umsetzung ist etwas lückenhaft, so dass praktisch bei jeder anderen Anwendung (außer &#8220;Hello World&#8221;) Probleme auftreten.</p>
<p><strong>Spalten sind nicht löschbar</strong></p>
<p>Will man eine Spalte löschen, dann wird man im normalen SQL ein UPDATE &#8230; Feldname = NULL verwenden, was aber beide Spaltenorientierten Cassandra mit CQL nicht funktioniert. Dort muss stattdessen die Spalte selbst gelöscht werden mit DELETE Column(s) FROM ColumnFamily WHERE &#8230;</p>
<p>Unnötig umständlich wie ich finde. Man ist gezwungen UPDATES auf Rows in ein UPDATE und ein DELETE Statement aufzuspalten, wenn man einen Teil der Spalten löschen will. Gerade weil Cassandra aber kein festes Schema mit beliebig vielen Spalten, die auch nicht notwendigerweise gefüllt sein müssen, unterstützt, ist dies doppelt ärgerlich.</p>
<p><strong>Selects auf NULL-Spalten funktionieren nicht</strong></p>
<p>Wie schon erwähnt wird man in einer Cassandra Persistenz sicher häufig auf Rows treffen, bei der nicht alle Spalten mit Werten belegt sind. Statt bei einer CQL Anfrage dann aber NULL, oder zumindest in der JDBC Darstellung NULL bzw. den passenden Default zu liefern, stolpert man über eine Exception. Man kann gar keine Spalten abfragen, die nicht gesetzt sind.</p>
<p><strong>Unzureichende Expression-Language</strong></p>
<p>Cassandra kennt zwar bestimmte Typen Spalten. Allerdings liefert CQL kaum ausreichen Ausdrucksmöglichkeiten mit diesen Typen umzugehen. Man kann nicht einmal einen Timestamp erzeugen, ausser den nackten Long-Wert direkt einzugeben, um nur ein Beispiel zu geben. Dies erschwert die Formulierung von Abfragen wiederum unnötig. Man hätte leicht bestehende Implementierungen von ELs adaptieren können, um halbwegs verwendbare Ausdrücke in CQL einsetzen zu können.</p>
<p><strong>PreparedStatements funktionieren nicht</strong></p>
<p>In JDBC ist es eigentlich der Normalfall PreparedStatements zu nutzen. Nicht nur weil man dem Server Gelegenheit gibt, die Anfragen zu optimieren, auch Injection wird damit wirkungsvoll verhindert. Leider unterstützt Cassandra 1.0.5 solche Anfragen bislang nicht. Der JDBC-Treiber bietet sie dennoch an.</p>
<p>Wie man in der Beschreibung und im Quellcode nachlesen kann, werden die Bindings jedoch schon auf der Clientseite aufgelöst und dann zum Server geschickt. Damit könnte man leben, wenn das wenigstens funktionieren würde. Leider ist auch hier die Implementierung fehlerhaft, sodass oft genug die Bindung schlicht falsch ist und der Server die Anfrage mit einem Fehler quittiert.</p>
<p><strong>Fazit</strong></p>
<p>Will man Cassandra einsetzen, hat man sich so an das eine oder andere zu gewöhnen (oder wieder zu gewöhnen). Und damit meine ich nicht in erster Linie die Art der Datenmodellierung. Ich jedenfalls fühlte mich in mancher Hinsicht um eine paar Jahre in die Vergangenheit zurück versetzt, als man mit Oracle noch per Oracle Call Interface (OCI) sprechen musste. Aber wenns denn Cassandra sein muss &#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2011/12/16/cassandra-cql-mit-jdbc-driver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serendipty auf WordPress migriert</title>
		<link>http://cogito-ergo-blog.de/blog/2011/12/02/serendipty-auf-wordpress-migriert/</link>
		<comments>http://cogito-ergo-blog.de/blog/2011/12/02/serendipty-auf-wordpress-migriert/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 20:43:20 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://cogito-ergo-blog.de/blog/?p=10047</guid>
		<description><![CDATA[Nach einiger Mühe ist das Blog nun endlich auf WordPress umgestellt. Das Update von Serendipity auf die neuste Version war eh überfällig, also warum nicht gleich umsteigen auf WordPress. Sieht einfach hübscher aus und kann mehr. Leider ging der Import &#8230; <a href="http://cogito-ergo-blog.de/blog/2011/12/02/serendipty-auf-wordpress-migriert/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Nach einiger Mühe ist das Blog nun endlich auf WordPress umgestellt.</p>
<p>Das Update von Serendipity auf die neuste Version war eh überfällig, also warum nicht gleich umsteigen auf WordPress. Sieht einfach hübscher aus und kann mehr.</p>
<p>Leider ging der Import der Daten nicht so einfach wie gedacht.</p>
<p>Zwar gibt es <a href="http://code.google.com/p/snowulf/source/browse/#svn/trunk/wordpress/s9y-to-wp">hier</a> von Snowulf einen Importer und noch ein Update zur 1.5 <a href="http://tellini.info/2010/10/serendipity-to-wordpress/">hier</a>. Aber zum einen muss man das Readme genau lesen und sich trauen, das SQL direkt anzuwenden auch wenn die WP Version nicht mehr stimmt, zum anderen sind dann immer noch nicht alle Inhalte mirgiert.</p>
<p>Der erste Importversuch wurde gleich mittendrin abgebrochen, weil der Nutzernamen im Import schon vergeben war und das Import-Script das nicht abfängt. Leider waren die Kategorien aber schon importiert.</p>
<p>Dann wurde die mehrsprachigen Artikel nicht übernommen. Okay das waren hier nur 4 und da konnte man das Englische manuell rüberziehen.</p>
<p>Aber es geht auch die Hierarchie der Kommentare verloren. Und die Formatierung von Quellcode geht in WP auch ganz anders (zum Glück aber besser, nur umstellen muss man trotzdem).</p>
<p>Noch eine gute Quelle ist <a href="http://wiki.nodomain.cc/projekte/blog-migration">hier</a> zu finden. Dort wird auch beschrieben was man tun muss damit die alten Permlinks wieder funktionieren. Allein die Post-IDs konstant zu halten reicht natürlich nicht, weil die Links von s9y ganz anders aussehen und sich mit den Standard-Einstellungen von WP auch nicht nachbilden lassen.</p>
<p>Leider nutzt der Autor zum Umschreiben der URL eine Konfiguration lighttpd, was bei Apache2 natürlich nicht passt. Mit etwas PHP bekommt man das aber auch in der Griff. Nur die Feed-URL sind hier jetzt noch nicht gerade gezogen, aber ich befürchte soviele Abbonnenten hab ich gar nicht <img src='http://cogito-ergo-blog.de/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Naja jetzt ist&#8217;s geschafft und vielleicht lebt dadurch das Blog wieder etwas auf.</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2011/12/02/serendipty-auf-wordpress-migriert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Der Gott des Gemetzels</title>
		<link>http://cogito-ergo-blog.de/blog/2011/12/02/der-gott-des-gemetzels/</link>
		<comments>http://cogito-ergo-blog.de/blog/2011/12/02/der-gott-des-gemetzels/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 19:48:11 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Movies]]></category>

		<guid isPermaLink="false">http://euve3303.vserver.de/stefan/blog/?p=10020</guid>
		<description><![CDATA[Nachdem das Blog nun endlich auf WordPress umgezogen ist, hab ich auch wieder etwas mehr Schreiblust und möchte daher einen Film empfehlen: der neue Polanski Film &#8220;Der Gott des Gemetzels&#8221;. Herrlich anzuschauen, absolute Empfehlung ein &#8220;Kammerspiel&#8221; im Kino mit tollen &#8230; <a href="http://cogito-ergo-blog.de/blog/2011/12/02/der-gott-des-gemetzels/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://cogito-ergo-blog.de/blog/wp-content/uploads/gott.jpg"><img class="size-full wp-image-10022 alignleft" title="gott" src="http://cogito-ergo-blog.de/blog/wp-content/uploads/gott.jpg" alt="" width="168" height="239" /></a>Nachdem das Blog nun endlich auf WordPress umgezogen ist, hab ich auch wieder etwas mehr Schreiblust und möchte daher einen Film empfehlen:</p>
<p>der neue Polanski Film &#8220;Der Gott des Gemetzels&#8221;. Herrlich anzuschauen, absolute Empfehlung ein &#8220;Kammerspiel&#8221; im Kino mit tollen Charakteren, einer langsamen Entwicklung hin zum kompletten &#8220;Gemetzel&#8221; wirklich sehenswert. Von <a href="http://www.constantin-film.de/kino/der-gott-des-gemetzels/">Constantin Film</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2011/12/02/der-gott-des-gemetzels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Coverage messen</title>
		<link>http://cogito-ergo-blog.de/blog/2011/11/23/sql-coverage-messen/</link>
		<comments>http://cogito-ergo-blog.de/blog/2011/11/23/sql-coverage-messen/#comments</comments>
		<pubDate>Wed, 23 Nov 2011 19:01:00 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://euve3303.vserver.de/stefan/blog/?p=44</guid>
		<description><![CDATA[Seit langem bin ich mal wieder aktiv in der Implementierung einer Komponente, wenn auch erst mal nur ein Prototyp. Die Persistenz ist &#8211; nach dem neusten Trend &#8220;back to the roots&#8221; &#8211; nur noch mit dem JdbcTemplate von Spring gemacht. &#8230; <a href="http://cogito-ergo-blog.de/blog/2011/11/23/sql-coverage-messen/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit langem bin ich mal wieder aktiv in der Implementierung einer Komponente, wenn auch erst mal nur ein Prototyp.</p>
<p>Die Persistenz ist &#8211; nach dem neusten Trend &#8220;back to the roots&#8221; &#8211; nur noch mit dem JdbcTemplate von Spring gemacht. Da kann man wieder richtiges SQL schreiben und weiß auch genau was passiert (bei Hibernate war ich mir nicht immer so ganz sicher).</p>
<p>Als es dann ans Testen ging und ich mir Gedanken um die Testabdeckung machte, fiel mir auf, dass das was bei if-Anweisungen oder bedingter Zuweisung im Java-Code als &#8220;missed 2 of 4 branches&#8221; an gemeckert wurde, an vielen Stellen in den Where-Clauses der SQL-Statements genauso auftritt.</p>
<p>Die Coverage in Java war also bei mancher Methode auf 100% aber das SQL-Statement ließ viele Varianten von ResultSets zu je nach dem, was man für Testdaten verwendet und welche konkreten Parameter man bindet.</p>
<p>Wie also läßt sich die SQL-Coverage messen?<br />
<span id="more-43"></span></p>
<h2>SQL tracen</h2>
<p>Zunächst einmal ist es nützlich die SQL-Statement mitschrieben zu lassen, die tatsächlich ausgeführt werden inklusive der aktuell gebundenen Parameter. Hierfür kann man Tools wie <a class="moz-txt-link-freetext" href="http://code.google.com/p/log4jdbc-remix/">http://code.google.com/p/log4jdbc-remix/</a> bzw. <span class="moz-txt-link-freetext"><a href="http://code.google.com/p/log4jdbc/">http://code.google.com/p/log4jdbc/</a> verwenden. Diese JDBC-Treiber arbeiten als Proxy und werden einfach &#8220;zwischen&#8221; die Applikation und den echten Treiber &#8220;gehängt&#8221;. Dadurch wird es einfach möglich alle SQL-Statements die man bei Ablauf einer Testsuite an die Datenbank schickt mitzuschreiben.</span></p>
<p>Aber leider weiss man damit immer noch nicht, ob man nun alle möglichen &#8220;Zweige&#8221; aller Where-Bedingungen aller SQL-Statements durchlaufen hat.</p>
<h2>SQL Rules und QAShrink</h2>
<p><span class="moz-txt-link-freetext">SQL Rules und QAShrink sind zwei Tool, die genau darüber Aufschluss geben können. Sie sind in der Lage ein gegebenes SQL-Statement zu analysieren nach der &#8220;Full Predicate Coverage&#8221; Methode. Es werden also Regeln erzeugt, die alle Verzweigungen oder Varainten die ein SQL-Statement erzeugen kann, berücksichtigt.</span></p>
<p>Dabei werden nicht nur Where-Bedingungen in Betracht gezogen, sondern natürlich auch Joins oder Group By-Klauseln. SQLRules zeigt zu einen einzelnen Statement diese Rules an, so dass man sich anschauen kann, welche möglichen &#8220;Pfade&#8221; zur Ergebnisfindung durchlaufen werden können.</p>
<h2>Regeln anwenden</h2>
<p><span class="moz-txt-link-freetext">Im nächsten Schritt lassen sich diese Regeln dann gegen einen Testdatenbestand anwenden / testen. Als Ergebnis bekommt man eine Aussage, ob die betreffende Regel verwendet wurde oder nicht, also ob dieser Pfad bei den zugrunde gelegten Daten durchlaufen wurde oder nicht. Das ist genau die SQL-Coverage die man braucht.</span></p>
<p>Das andere Tool QAShrink kann dieses Prinzip gleich auf eine ganze Liste von SQL-Statements anwenden<span class="moz-txt-link-freetext">. Es erzeugt dann Aussagen bzgl. der Coverage der SQL-Statements und der Vollständigkeit bzw. der Redundanz der Testdaten.</span></p>
<p>Auf diese Weise kann man also ziemlich schnell herausfinden, welche Testdaten überflüssig und welche noch zu ergänzen sind, um &#8211; bei gegebener Liste der SQL-Statements &#8211; die SQL-Coverage möglichst hoch zu machen.</p>
<h2>Zusammenfassung</h2>
<p>Das Vorgehen zum Erreichen einer möglichst hohen SQL-Coverage läßt sich also so zusammenfassen:</p>
<ol>
<li>Mit einem JDBC-Proxy Treiber erzeugt man eine Liste von konkreten SQL-Abfragen, die von einer TestSuite mit hoher Code-Coverage erzeugt wird.</li>
<li>Die Liste der SQL-Statemant füttert man in QAShrink und läßt sie gegen den gleichen Testdatenbestand wie die TestSuite laufen.</li>
<li>Anhand der Ergebnisse kann man den Testdatenbestand so lange um Datensätze ergänzen, bis eine optimale SQL-Coverage erreicht ist.</li>
</ol>
<p>Links zu den Tools:<br />
<a class="moz-txt-link-freetext" href="http://in2test.lsi.uniovi.es/sqltools/sqlrules/">http://in2test.lsi.uniovi.es/sqltools/sqlrules/</a><br />
<a class="moz-txt-link-freetext" href="http://in2test.lsi.uniovi.es/sqltools/qashrink/">http://in2test.lsi.uniovi.es/sqltools/qashrink/</a></p>]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2011/11/23/sql-coverage-messen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Workflow-Engine einmal anders</title>
		<link>http://cogito-ergo-blog.de/blog/2009/07/28/workflow-engine-einmal-anders/</link>
		<comments>http://cogito-ergo-blog.de/blog/2009/07/28/workflow-engine-einmal-anders/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 20:52:13 +0000</pubDate>
		<dc:creator>steve40</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://euve3303.vserver.de/stefan/blog/?p=43</guid>
		<description><![CDATA[Schon in einigen Projekten war die Herausforderung bestimmte Abläufe oder auch „Prozesse“ hochskalierbar, verlässlich ausführen zu können. Dabei kam dann von den einen Projektverantwortlichen schnell der Ruf nach einer Workflow-Engine, von den anderen eher das Gegenteil: „Bloß keine Workflow-Engine &#8230;“. &#8230; <a href="http://cogito-ergo-blog.de/blog/2009/07/28/workflow-engine-einmal-anders/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0cm;">Schon in einigen Projekten war die Herausforderung bestimmte Abläufe oder auch „Prozesse“ hochskalierbar, verlässlich ausführen zu können. Dabei kam dann von den einen Projektverantwortlichen schnell der Ruf nach einer Workflow-Engine, von den anderen eher das Gegenteil: „Bloß keine Workflow-Engine &#8230;“.</p>
<p style="margin-bottom: 0cm;">Ich selbst bin auch nicht unbedingt ein Freund von „graphischer Programmierung“ oder geschwätzigem XML, was fast schon Programmiersprache sein will, aber in fast jeder<br />
Hinsicht unhandlicher ist als eine „normale“ Programmiersprache wie <a href="http://www.scala-lang.org/">Scala</a> oder Java.</p>
<p style="margin-bottom: 0cm;">Aus diesem Grund reizte mich die Idee einen alternativen Ansatz zu versuchen. Da ich, wie gerade schon erwähnt, kein Freund von „in XML programmieren“ bin, sollte die<br />
Beschreibung des „Prozesses“ &#8211; das Prozessmodell – in Java erfolgen.</p>
<p style="margin-bottom: 0cm;">Hier bietet sich das <a href="http://de.wikipedia.org/wiki/Zustand_(Entwurfsmuster)">State-Pattern</a> an, welches eine Prozessablauf mit Hilfe von Zustandsobjekten und einem Kontext beschreibt. Konkret werden also nur Interfaces bzw. abstrakte Basisklassen benötigt, die von einem konkreten Prozess implementiert<br />
werden. Dazu der „Contract“ der den Ablauf / die Semantik beschreibt und schon kann ein „Prozess“ statt in XML in Java geschrieben werden.</p>
<p><span id="more-41"></span></p>
<p style="margin-bottom: 0cm;">Allerdings kann man nun einwenden, dass das normale Ausführungsmodell einer JVM mit Threads nicht die gleichen Vorteile bietet wie eine Workflow-Engine.</p>
<p style="margin-bottom: 0cm;">Inspiriert von den Ansätzen von <a href="https://dalma.dev.java.net/nonav/maven/index.html">Dalma</a> und <a href="http://commons.apache.org/sandbox/javaflow/">Javaflow</a> oder auch den Arbeiten von Doug Lea (FJTasks) ist aber auch auf einer Java VM mehr möglich, als einfach für jeden Prozess<br />
und jede seiner Nebenläufigkeiten einen neuen Thread zu starten.</p>
<p style="margin-bottom: 0cm;">Würde man das tun, wären diese bei den eingangs genannten Anforderungen sicher bald aufgebraucht (viele Prozessinstanzen, womöglich viele davon nur wartend).</p>
<p style="margin-bottom: 0cm;">Auch mit der Skalierbarkeit haben viele Workflow-Engines gewisse Probleme, weil sich die Arbeit schlecht über einen Cluster verteilen läßt. Aber auch hier gibt es im Standard<br />
Java gute Lösungansätze, wie z.B. <a href="http://www.gridgain.com/">GridGain</a>.</p>
<p style="margin-bottom: 0cm;">Ein weiterer Aspekt, den Workflow-Engine bedienen, ist Prozesspersistenz. Prozesse, die auf der Engine ablaufen, lassen sich persistieren. Damit ist der Ablauf unterbrechbar, wiederherstellbar und nachvollziehbar. Wenn allerdings Prozesse normale durch normale Java-Objekte dargestellt werden, dann lassen sie sich auch mit einfachen ORM Mitteln persistieren.</p>
<p style="margin-bottom: 0cm;">Zu guter letzt sind die meisten Prozesse immer auf irgendwelche Services angewiesen, die von ihnen aufgerufen werden, oder Calls an die Prozesse absetzen. Hierzu soll<br />
für das Java basierende Prozessmodell ein Container /Application-Server zum Einsatz kommen. Meine Wahl fiel auf <a href="http://www.springsource.org/">Spring</a>, wobei sicher auch andere Lösungen denkbar wären.</p>
<p style="margin-bottom: 0cm;">Das Rezept für <em>meine </em>Workflow-Engine lautet also:</p>
<ul>
<li>
<p style="margin-bottom: 0cm;">Prozesse sind Java-Klassen, die nach dem State-Pattern einen Ablauf implementieren.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Diese Klassen sind typischerweise Spring-Beans, die vom Container „Services“ konsumieren.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Die Klassen sind Serializable und damit „Remoting“-fähig für GridGain.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Die Klassen tragen (optional) Persistenz-Annotationen, welche die Engine dafür nutzt den Prozesszustand zu persistieren.</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">Heraus kommt eine Lösung,</p>
<ul>
<li>
<p style="margin-bottom: 0cm;">die hochskalierbar ist, weil Prozesse über GridGain auf einem Cluster von Nodes verteilt werden können.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">die den gewohnten Komfort einer IOC-Umgebung genießt, bei der nach Belieben „Services“ genutzt werden können (natürlich nicht nur Webservices).</p>
</li>
<li>
<p style="margin-bottom: 0cm;">die den Prozesszustand nach jedem Prozessschritt mit Hilfe eines Persistenzproviders wie z.B. Hibernate persistiert.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">die Prozesse einfach als Java-Programm beschrieben, welches mit einfachsten Mitteln und voller IDE Untersützung entworfen werden kann.</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">Besonders den letzten Punkt möchte ich noch einmal unterstreichen: Man kann es gar nicht hoch genug bewerten, wie viele Vorteile sich allein dadurch ergeben, dass man in<br />
der gewohnten Umgebung arbeiten kann:</p>
<ul>
<li>
<p style="margin-bottom: 0cm;">kein Lernen einer Prozessbeschreibungssprache (in XML).</p>
</li>
<li>
<p style="margin-bottom: 0cm;">alle Möglichkeiten und Konstrukte einer Programmiersprache wie Java.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">die gewohnte IDE.</p>
</li>
<li>
<p style="margin-bottom: 0cm;">simples Debuggen und Testen (noch besser zu unterstützen durch Mocks und eine spezielle Engine, die ein lokales Debuggen direkt ermöglicht).</p>
</li>
<li>
<p style="margin-bottom: 0cm;">Einfachstes Wiederverwenden von vorhandenem Code oder vorhandenen Services (meist sind keinerlei „Wrapper“ oder „Adapter“ notwendig).</p>
</li>
</ul>
<p style="margin-bottom: 0cm;">Wie die Lösung konkret aussieht, werde ich wohl heute nicht mehr zusammenschreiben, deshalb wird’s demnächst hier ne Fortsetzung geben &#8230;</p>
<p style="margin-bottom: 0cm;">
]]></content:encoded>
			<wfw:commentRss>http://cogito-ergo-blog.de/blog/2009/07/28/workflow-engine-einmal-anders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

