<?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>blogzwei</title>
	<atom:link href="http://www.wortzwei.de/blogzwei/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.wortzwei.de/blogzwei</link>
	<description>der Blog von Wortzwei</description>
	<lastBuildDate>Mon, 07 May 2012 07:31:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Scripting Java mit JavaScript</title>
		<link>http://www.wortzwei.de/blogzwei/2012/05/scripting-java-mit-javascript/</link>
		<comments>http://www.wortzwei.de/blogzwei/2012/05/scripting-java-mit-javascript/#comments</comments>
		<pubDate>Fri, 04 May 2012 07:50:59 +0000</pubDate>
		<dc:creator>Dirk Dittmar</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=1022</guid>
		<description><![CDATA[Ein Kollege mit sehr guten JavaScript Kenntnissen hat mir letztens beim Umbau einer Seite geholfen. Im Zuge dessen musste eine riesen JS-Datei zusammen kopiert werden, was er mal schnell mit Visual-Basic (oder wie das jetzt heißt) gelöst hat. Nachdem dann alles fertig war musste das natürlich noch von mir übernommen werden. Deshalb hat er mir [...]]]></description>
			<content:encoded><![CDATA[<p>Ein Kollege mit sehr guten JavaScript Kenntnissen hat mir letztens beim Umbau einer Seite geholfen. Im Zuge dessen musste eine riesen JS-Datei zusammen kopiert werden, was er mal schnell mit Visual-Basic (oder wie das jetzt heißt) gelöst hat. Nachdem dann alles fertig war musste das natürlich noch von mir übernommen werden. Deshalb hat er mir mal sein VB-Script zugeschickt. Nur leider konnte ich mit VB gar nichts mit anfangen. Die Sprache ist einfach zu weit weg von C und Konsorten als das man sofort etwas lesen könnte. Wir haben es natürlich dann gemeinsam umgeschrieben aber mir ist dann später in der S-Bahn eingefallen das man ja auch Java Skripten kann! <span id="more-1022"></span></p>
<p>Seit einiger Zeit (seit Java5?) ist eine JavaScript-Engine (Rhino von Mozilla) in das JDK eingebettet und es gibt auch ein Kommandozeilen-Tool (jrunscript) um eben mal schnell Scripte auszuführen. Ich hab mir das zu Hause natürlich gleich mal angesehen und es funktioniert prächtig. Als Beispiel hab ich mal die <code>copyFile</code> Methode aus den <code>FileUtils</code> von Apache-Commons-IO neu in JavaScript geschrieben:</p>
<pre>
importClass(java.io.File);
importClass(java.io.FileOutputStream);
importClass(java.io.FileNotFoundException);
importClass(java.io.IOException);

var FileUtils = new function() {

    this.copyFile = function(file1, file2) {

        var source = new File(file1);
        var destination = new File(file2);

        //check source exists
        if (!source.exists()) {
            var message = "File " + source + " does not exist";
            throw new FileNotFoundException(message);
        }

        // does destinations directory exist?
        if (destination.getParentFile() != null &amp;&amp; !destination.getParentFile().exists()) {
            destination.getParentFile().mkdirs();
        }

        // make sure we can write to destination
        if (destination.exists() &amp;&amp; !destination.canWrite()) {
            var message = "Unable to open file " + destination + " for writing.";
            throw new IOException(message);
        }

        // makes sure it is not the same file
        if (source.getCanonicalPath().equals(destination.getCanonicalPath())) {
            var message = "Unable to write file " + source + " on itself.";
            throw new IOException(message);
        }

        var input = new FileInputStream(source);
        try {
            var output = new FileOutputStream(destination);
            try {
                streamCopy(input, output);
            } finally {
                closeQuietly(output);
            }
        } finally {
            closeQuietly(input);
        }

        if (source.length() != destination.length()) {
            var message = "Failed to copy full contents from " + source + " to " + destination;
            throw new IOException(message);
        }

    }

    function streamCopy(input, output) {
        var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096);
        var count = 0;
        var n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }

    function closeQuietly(stream) {
        try {
            stream.close()
        } catch (e if e.javaException instanceof IOException) {
            // ignore
        }
    }

};

try {
    FileUtils.copyFile('/tmp/test.txt','/tmp/test_cpy.txt');
} catch (e) {
    println(e);
}
</pre>
<p>Das Beispiel zeigt eigentlich eine ganze Menge (viel Spaß beim lesen). Ausführen könnt ihr das einfach mit dem Tool <code>jrunscript</code> (auf der Kommandozeile).</p>
<p>Bei einigen Sachen hab ich ein bisschen länger geguckt, deshalb hier noch mal hervorgehoben:</p>
<dl>
<dt><strong>Importieren von Java-Klassen:</strong></dt>
<dd><code>importClass(java.io.File);</code></dd>
<dt><strong>Fangen einer Exception mit Type-Check:</strong></dt>
<dd><code>} catch (e if e.javaException instanceof IOException) {</code></dd>
<dt><strong>Erstellen eines Java-Byte-Arrays (für das Kopieren der Streams):</strong></dt>
<dd><code>var buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 4096);</code></dd>
<dt><strong>Etwas auf der Konsole ausgegeben (sehr nützlich zum debuggen):</strong></dt>
<dd><code>print('foo');</code> oder auch <code>println('bar')</code></dd>
</dl>
<p>Ansonsten kann man fast normal Java schreiben und die volle Java Power kann genutzt werden. Was ich mir noch nicht angesehen hab ist wie man Apache-Commons-IO oder etwas ähnlich nützliches auf den Classpath bekommt damit man die dort enthaltenen Klassen auch verwenden kann. Hier hab ich ja das Rad neu erfunden das hätte man sicher auch einfacher haben können.</p>
<p>Nächstes mal werden mein Kollege und ich das dann in JavaScript machen. Dann brauchen wir nicht eine Stunde Pair-Programming einschieben. Außerdem hatte VB-Script dann auch implizit irgendwas gemacht das wir so natürlich nicht nachgebaut hatten. Da konnten wir dann auch noch debuggen&#8230;</p>
<p><i>naja&#8230; nächstes mal ist man schlauer&#8230;</i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2012/05/scripting-java-mit-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grails: Methodenmocking per MetaClass kann seltsame Seiteneffekte erzeugen</title>
		<link>http://www.wortzwei.de/blogzwei/2012/04/grails-methodenmocking-per-metaclass-kann-seltsame-seiteneffekte-erzeugen/</link>
		<comments>http://www.wortzwei.de/blogzwei/2012/04/grails-methodenmocking-per-metaclass-kann-seltsame-seiteneffekte-erzeugen/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 10:31:51 +0000</pubDate>
		<dc:creator>john</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Mock]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=1009</guid>
		<description><![CDATA[Gerade in UnitTests kann es sinnvoll sein, einzelne GORM-Methoden über die MetaClass des DomainObjects zu mocken. Etwa so: registerMetaClass MyDomainObject MyDomainObject.metaClass.findAllByMyField = { return [] } Aufrufe dieser Methode geben so immer eine leere Liste zurück, was sehr praktisch ist, wenn man bei komplexen Domain Models nicht sämtliche Abhängigkeiten und Beziehungen über Fake-Daten mocken möchte, [...]]]></description>
			<content:encoded><![CDATA[<p>Gerade in UnitTests kann es sinnvoll sein, einzelne GORM-Methoden über die MetaClass des DomainObjects zu mocken. Etwa so:</p>
<p><code>registerMetaClass MyDomainObject<br />
MyDomainObject.metaClass.findAllByMyField = { return [] }</code></p>
<p>Aufrufe dieser Methode geben so immer eine leere Liste zurück, was sehr praktisch ist, wenn man bei komplexen Domain Models nicht sämtliche Abhängigkeiten und Beziehungen über Fake-Daten mocken möchte, um nur einen einzelnen Sondefall zu testen.</p>
<p>Wenn man damit aber nicht aufpasst, kann das zu einigen grauen Haaren führen.<br />
<span id="more-1009"></span></p>
<p>Wird nämlich <code>registerMetaClass</code> mehrfach für das selbe Objekt aufgerufen hat Grails Schwierigkeiten, damit durchgeführte Änderungen nach Beenden des Tests wieder aufzuräumen. Ab und zu funktioniert es, ab und zu nicht &#8211; ohne für den Entwickler erkennbaren Zusammenhang. Besonders gefährlich: Während die Tests, die diese Art von Mock benutzen, i.d.R. tadellos ihren Dienst tun, schlagen nun völlig andere Tests in scheinbar unzusammenhängenden Bereichen fehl.<br />
In unserem Fall sorgte diese Sache für obskure und schlicht falsche Constraints-Fehler in Integration-Tests, wenn diese über <code>grails test-app</code> zusammen mit dem betroffenen Unit-Test ausgeführt wurden! Hinzu kam, dass diese Fehler nur auftraten, wenn die Tests direkt nach einem Clean des Projektes durchgeführt wurden.</p>
<p>Der gleiche Fehler kann auftreten, wenn man <code>mockDomain</code> mehrfach oder zusammen mit <code>registerMetaClass</code> aufruft. Das macht nämlich nichts anderes, als intern <code>registerMetaClass</code> zu verwenden, um die GORM-Eigenschaften zu mocken.</p>
<p>Kurz: Immer darauf achten, dass DomainObjects nicht &#8220;mehrfach&#8221; gemockt werden. Am besten ist es, wenn man in der setUp()-Methode von UnitTests einmalig ein Test-Modell zusammenbaut und dieses dann in den einzelnen Tests verwendet, statt hier individuell zu mocken. So behält man leicht die Übersicht, welche Mocks wo verwendet werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2012/04/grails-methodenmocking-per-metaclass-kann-seltsame-seiteneffekte-erzeugen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>jQuery.ajax() Status-Code und Caches</title>
		<link>http://www.wortzwei.de/blogzwei/2012/04/jquery-ajax-status-code-und-caches/</link>
		<comments>http://www.wortzwei.de/blogzwei/2012/04/jquery-ajax-status-code-und-caches/#comments</comments>
		<pubDate>Mon, 02 Apr 2012 15:14:18 +0000</pubDate>
		<dc:creator>Dirk Dittmar</dc:creator>
				<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[http-status]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=995</guid>
		<description><![CDATA[Nur ein kurzer Artikel dieses mal. Ich hatte gerade echt Probleme mit dem Status-Code den JQuery in den Fehler-Handler übergibt. Ich hatte mir einen AJAX-Call zusammen gebaut (ähnlich dem folgenden): $.ajax({ url: 'ajax.php', data: {}, cache: false, type: 'GET', success: function(data, textStatus, jqXHR) { // TODO alert(data); }, error: function(jqXHR, textStatus, errorThrown) { if (jqXHR.status [...]]]></description>
			<content:encoded><![CDATA[<p>Nur ein kurzer Artikel dieses mal. Ich hatte gerade echt Probleme mit dem Status-Code den JQuery in den Fehler-Handler übergibt.<br />
<span id="more-995"></span></p>
<p>Ich hatte mir einen AJAX-Call zusammen gebaut (ähnlich dem folgenden):</p>
<pre>
$.ajax({
	url: 'ajax.php',
	data: {},
	cache: false,
	type: 'GET',
	success: function(data, textStatus, jqXHR) {
		// TODO
		alert(data);
	},
	error: function(jqXHR, textStatus, errorThrown) {
		if (jqXHR.status == 302) {
			// TODO 302 behandeln
		}
		alert(jqXHR.status);
	}
});
</pre>
<p>Der Server liefert dabei so lange &#8220;200 Success&#8221; mit einem String der den Grad der Fertigstellung anzeigt (z.B. 22%) bis die neue Resource zusammen gesetzt ist und liefert dann ein &#8220;302 Found&#8221;. Worauf hin ich den Browser auf die neue Resource lenken wollte. Hier das PHP-Script (ajax.php) das den 302 liefert (nur zum testen):</p>
<pre>
&lt;?php
header("HTTP/1.1 302");
header("Location: http://www.google.de/");
</pre>
<p>Leider ist es nun so das der Status-Code im JS nicht richtig gesetzt ist (wo auch immer das Problem liegt). Die Browser die ich probiert habe liefert folgenden Ergebnisse:</p>
<ul>
<li>Firefox 11 lieferte <b>0</b></li>
<li>Chrome 17 lieferte <b>0</b></li>
<li>IE9 lieferte <b>12017</b></li>
</ul>
<p>Ich habe in dem Projekt JQuery 1.5.1 aber 1.7.1 scheint das gleiche zu machen.</p>
<p>Man sollte sich also nicht darauf verlassen das man im Error-Handler noch mit dem Status-Code etwas anfangen kann. Ich hab das dann einfach so gelöst das der AJAX-Call immer JSON liefert in dem dann steht wie der Zustand jetzt ist. So habe ich alles im Success-Handler und der Error-Handler ist dann wirklich nur noch für unvorhergesehenes.</p>
<p>Neben bei bemerkt hat das <code>cache: false</code> sehr geholfen den IE davon abzuhalten das Ergebniss des AJAX-Calls zu cachen. Das hat auch schon zu lustigen Problemen geführt.</p>
<p><i>bis denn&#8230;</i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2012/04/jquery-ajax-status-code-und-caches/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Warten auf Ajax-Requests in Selenium 2 mit PHP</title>
		<link>http://www.wortzwei.de/blogzwei/2012/02/warten-auf-ajax-requests-in-selenium-2-mit-php/</link>
		<comments>http://www.wortzwei.de/blogzwei/2012/02/warten-auf-ajax-requests-in-selenium-2-mit-php/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 09:58:07 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=971</guid>
		<description><![CDATA[Mittlerweile ist die Nutzung von Ajax-Requests Standard in aktuellen Webapplikationen, was gerade das funktionale Testen aufwändiger gestaltet, als &#8220;klassische&#8221; Techniken. Für die Abbildung funktionaler Tests nutzen wir unter Symfony PHPUnit in Kombination mit Selenium 2 und die Selenium Webdriver bindings for PHP. Für einen Kunden haben wir vor kurzer Zeit ein relativ aufwändiges Ajax-lastiges Formular [...]]]></description>
			<content:encoded><![CDATA[<p>Mittlerweile ist die Nutzung von Ajax-Requests Standard in aktuellen Webapplikationen, was gerade das funktionale Testen aufwändiger gestaltet, als &#8220;klassische&#8221; Techniken. Für die Abbildung funktionaler Tests nutzen wir unter Symfony <a href="https://github.com/sebastianbergmann/phpunit/">PHPUnit</a> in Kombination mit <a href="http://seleniumhq.org/">Selenium 2</a> und die <a href="http://code.google.com/p/php-webdriver-bindings/">Selenium Webdriver bindings for PHP</a>.<br />
<span id="more-971"></span><br />
Für einen Kunden haben wir vor kurzer Zeit ein relativ aufwändiges Ajax-lastiges Formular erstellt, bei dem bei jedem Blur-Event eines Eingabefeldes ein serverseiter Validator getriggert wird und das Ergebnis anhand eines Indicators neben dem Eingabefeld angezeigt wird. Dies wollten wir auch mit dem Test prüfen. Da die serverseitige Validierung nicht unmittelbar reagiert, war der erste Ansatz, einfach mit <code>sleep()</code> oder <code>usleep()</code> eine Zeit zu warten und dann implizit davon auszugehen, dass der Ajax-Request nach dieser Zeit abgeschlossen ist. Das funkioniert&#8230; meistens. Dank eines Artikels von <a href="http://agilesoftwaretesting.com/?p=190">Dirma</a> möchte ich eine Methode vorstellen, mit der unter Verwendung von jQuery auf Ajax-Requests &#8220;gewartet&#8221; werden kann:</p>
<p><code>jQuery.active == 0</code> liefert true sobald keine aktiven Ajax-Requests mehr anliegen, die über jQuery gezündet wurden. Das ist zwar nicht exakt dass, was wir wissen wollen, erfüllt aber für die Tests voll und ganz den Zweck. Die Javascript-Schnipsel muss nur noch über den PHP-Webdriver ausgeführt werden. Ich nutze hierzu die folgende Methode innerhalb meines TestCases:</p>
<pre>protected function waitForAjax($timeout = 15) {
 $retries = 0;
 while( $retries++ &lt; $timeout*10 ) {
  if($this-&gt;getWebdriver()-&gt;execute('return jQuery.active == 0', array())) {
   return true;
  }
  usleep(100000);
 }
 return false;
}
</pre>
<p>Der Javascript-Code wird alle 100ms abgefeuert und gibt bei Erfolg true zurück. Dies wird für max. <code>$timeout</code> Sekunden durchgeführt. <code>$this-&gt;webdriver</code> ist hierbei die WebDriver-Klasse, die in den Testcases innerhalb der Setup-Methode erstellt wird:</pre>
<pre>protected function setUp() {
 $config = self::getConfiguration();
 $webdriver = new WebDriver($config['webdriver']['hub']['host'], $config['webdriver']['hub']['port']);
 $webdriver-&gt;connect($this-&gt;browser);
 $this-&gt;rootUrl = $config['webdriver']['url'];
 $webdriver-&gt;get($this-&gt;getRootUrl());
 $this-&gt;setWebDriver($webdriver);
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2012/02/warten-auf-ajax-requests-in-selenium-2-mit-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KEENON FASHION ist live &#8211; und wir sind dabei!</title>
		<link>http://www.wortzwei.de/blogzwei/2012/01/keenon-fashion-ist-live-und-wir-sind-dabei/</link>
		<comments>http://www.wortzwei.de/blogzwei/2012/01/keenon-fashion-ist-live-und-wir-sind-dabei/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 14:33:01 +0000</pubDate>
		<dc:creator>joris</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=966</guid>
		<description><![CDATA[Vermutlich herrschte schon allenthalben das Gefühl, wir von der wortzwei GmbH würden unser Blog still und leise zu Grabe tragen &#8211; dem ist aber nicht so! Wir hatten einfach nur unglaublich viel zu tun! Um so mehr freuen wir uns nun etwas großes, großartiges und neues vorzustellen: KEENON FASHION ist live! Wir haben für die [...]]]></description>
			<content:encoded><![CDATA[<p>Vermutlich herrschte schon allenthalben das Gefühl, wir von der wortzwei GmbH würden unser Blog still und leise zu Grabe tragen &#8211; dem ist aber nicht so! Wir hatten einfach nur unglaublich viel zu tun!<br />
<span id="more-966"></span><br />
Um so mehr freuen wir uns nun etwas großes, großartiges und neues vorzustellen: KEENON FASHION ist live! </p>
<p>Wir haben für die Otto-Tochter <a href="https://www.hermesworld.com/int/about_us/hermes_group/otto_international_gmbh/otto-international-gmbh.html">Hermes-OTTO International</a> die B2B-Handelsplattform KEENON FASHION umgesetzt und waren hierzu auch beratend tätig.</p>
<p>Mehr in der aktuellen Ausgabe der TextilWirtschaft und online <a href="http://etailment.de/2012/otto_b-to-b-plattform/">hier</a>.</p>
<p>Die Umsetzung erfolgte mittels Java &amp; Grails.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2012/01/keenon-fashion-ist-live-und-wir-sind-dabei/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java als Service unter Windows</title>
		<link>http://www.wortzwei.de/blogzwei/2011/11/java-als-service-unter-windows/</link>
		<comments>http://www.wortzwei.de/blogzwei/2011/11/java-als-service-unter-windows/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 12:49:57 +0000</pubDate>
		<dc:creator>Dirk Dittmar</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[procrun]]></category>
		<category><![CDATA[prunsrv]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[srvany]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=878</guid>
		<description><![CDATA[Um ein Java-Programm als Service unter Windows zu betreiben benötigt man einen Service-Wrapper (da führt kein Weg dran vorbei). Unter Linux gibt es auch Service-Wrapper aber dort kann man Java auch direkt als Daemon ausführen. Unter Linux habe ich mir bis jetzt immer ein passendes init.d Script runtergeladen und das leicht angepasst. Linux ist da [...]]]></description>
			<content:encoded><![CDATA[<p>Um ein Java-Programm als Service unter Windows zu betreiben benötigt man einen Service-Wrapper (da führt kein Weg dran vorbei). Unter Linux gibt es auch Service-Wrapper aber dort kann man Java auch direkt als Daemon ausführen. Unter Linux habe ich mir bis jetzt immer ein passendes <code>init.d</code> Script runtergeladen und das leicht angepasst. Linux ist da eben (wie immer) einen Schritt weiter. Aber manchmal kommt man eben nicht daran vorbei einen Service unter Windows laufen zu lassen. <i>*seufz*</i> <span id="more-878"></span></p>
<p>Für Windows hab ich auf die schnelle zwei Wrapper gefunden:</p>
<ul>
<li>srvany (von Microsoft)</li>
<li><a href="http://commons.apache.org/daemon/procrun.html">Procrun (von Apache)</a></li>
</ul>
<p>Da <i>Procrun</i> von Apache ist und wohl auch vom Tomcat verwendet wird habe ich mich entschlossen das Tool zu nutzen.</p>
<p><i>Procrun</i> besteht aus zwei Programmen:</p>
<ol>
<li>Prunmgr (Procrun monitor application) ist eine GUI um <i>Procrun</i> Dienste zu konfigurieren.</li>
<li>Prunsrv (Procrun service application) ist der eigentliche Service-Wrapper</li>
</ol>
<p>Die Monitor-Applikation ist nicht so interessant deshalb betrachten wir hier nur den Wrapper. Der Wrapper kann in drei Modes laufen:</p>
<ol>
<li>Im Mode <code>jvm</code> wird direkt die <code>jvm.dll</code> verwendet um das Java-Programm zum Service zu machen. Das gewünschte Java-Programm läuft so in dem Prozess des Wrappers.</li>
<li>Im Mode <code>exe</code> kann eine beliebige anderes (native) Programm als Service gestartet werden. Das Programm wird dabei in einem eigenen Prozess gestartet.</li>
<li>Der Mode <code>java</code> ähnelt sehr dem Mode <code>exe</code> nur das hier automatisch die <code>java.exe</code> in einem eigenen Prozess gestartet wird.</li>
</ol>
<p>Ich finde eigentlich den Mode <code>jvm</code> am besten. Die Idee das Java-Programm in dem Prozess laufen zu lassen finde ich eigentlich recht charmant und die Implementierung kann man leicht so gestalten das mein <code>init.d</code> Ansatz für Linux mit dem gleichen Source-Code funktioniert.</p>
<p>Um unser Beispiel-Programm als Service zu installieren lädt man sich die Binaries von der Apache-Seite herunter. Dann braucht ihr natürlich auch meine <a href='http://www.wortzwei.de/blogzwei/wp-content/uploads/2011/11/SimpleService.zip'>Sample-App</a> (ist Eclipse-Projekt). Dann entpackt ihr das Sampel und entpackt die Distribution von Apache so das die <code>prunsrv</code> in dem Verzeichnis liegt in das ihr mein Beispiel entpackt habt. Dann könnt ihr mit dem Batch-Script (<code>service_install.bat</code>) den Service installieren:</p>
<pre>
@ECHO OFF
%~dp0\prunsrv //IS//SimpleService  ^
	--Jvm=auto --StartMode=jvm --StopMode=jvm  ^
	--Classpath %~dp0\SimpleService.jar  ^
	--StartClass de.wortzwei.simpleService.Service --StartParams start  ^
	--StopClass de.wortzwei.simpleService.Service --StopParams stop  ^
	--StartPath %~dp0 --LogPath %~dp0
</pre>
<p>Der Inhalt ist leicht erklärt (genauer könnt ihr das in der Dokumentation nachlesen): Es wird ein Service mit dem Namen &#8220;SimpleService&#8221; installiert. Die Jvm wird automatisch bestimmt und das Starten bzw. Stoppen passiert im Modus <code>jvm</code>. Natürlich muss der <code>Classpath</code>, das Working-Directory (<code>StartPath</code>) und der <code>LogPath</code> (hier schreibt das Tool sein eigenes Log) gesetzt werden. Das Working-Directory ist deshalb so wichtig da unser Service dort seine Einstellungen sucht. Dieses seltsame <code>%~dp0</code> wird übrigens zum Verzeichnis erweitert in dem sich diese Bat-Datei befindet. Wirklich wichtig sind die Einstellungen <code>StartClass</code>, <code>StopClass</code>, <code>StartParams</code> und <code>StopParams</code> denn hier wird eingestellt das die Methode <code>main</code> (ist der default und kann auch noch eingestellt werden) in der Klasse <code>de.wortzwei.simpleService.Service</code> mit dem Parameter <code>start</code> zum starten bzw. <code>stop</code> zum stoppen aufgerufen wird. Die Main-Methode wird dabei nicht zum starten der VM aufgerufen sondern wird wie eine normale statische Methode aufgerufen.</p>
<p>Sehen wir uns die Main-Methode an:</p>
<pre>
public static void main(final String[] args) {
	// default ist "start"
	String cmd = CMD_START;
	if (args.length &gt; 0) {
		cmd = args[0];
	}

	if (cmd.equalsIgnoreCase(CMD_START)) {
		Thread.setDefaultUncaughtExceptionHandler(new ExtUncaughtExceptionHandler());
		try {
			final Settings settings = new Settings();
			// den Server starten
			server = new Server(settings.getPort(),
			        settings.getMaxRequests(), new FileFactory(
			                settings.getOutput()));
			server.start();
		} catch (final IOException e) {
			System.out.println("fatal error!");
			e.printStackTrace();
			System.exit(-1);
		}
	} else {
		if (server != null) {
			server.shutdown();
			try {
				server.join();
			} catch (final InterruptedException e) {
				System.out.println("Interrupted?");
				e.printStackTrace();
			}
		}
	}
}
</pre>
<p>Wie man sieht wird der <code>Server</code> (ein Thread) gestartet wenn &#8220;start&#8221; als erster Parameter übergeben wird. Jeder andere String wird als &#8220;stop&#8221; interpretiert. Hier ist es wichtig beim stoppen <b>nicht</b> <code>System.exit()</code> aufzurufen. Das würde ja die JVM abbrechen, die wir nicht selber gestartet haben (da wir hier in der <code>main</code> Methode sind täuscht das ein wenig) und unter Windows werden dann wirre Meldungen angezeigt von wegen der Service konnte nicht gestoppt werden. Im Prinzip macht der Service-Wrapper nichts anderes als dieses kleine Programm:</p>
<pre>
/**
 * Diese Methode startet den Service; wartet ein bisschen und stoppt ihn dann
 * wieder. Ähnlich wie der Service-Wrapper das macht.
 */
private static void startStopService() {
	// starten
	Service.main(new String[] { "start" });

	// warten
	try {
		Thread.sleep(1000);
	} catch (final InterruptedException e) {
		System.out.println("Interrupted?");
		e.printStackTrace();
	}

	// stoppen
	Service.main(new String[] { "stop" });
}
</pre>
<p>Wie bereits erwähnt ist das beste an diesem Ansatz das ich diese Main-Methode fast ohne Änderung so unter Linux auch verwenden kann. Unter Linux ruft das <code>init.d</code> Script zum stoppen des Daemons nur <code>kill -15 &lt;pid&gt;</code> auf (SIGTERM). Wenn man jetzt einen Shutdown-Hook registriert kann dieser das stoppen des Server-Threads übernehmen und mit ein bisschen Refactoring kann der Code der jetzt im Else-Zweig steht sogar von beiden Ansätzen verwendet werden.</p>
<p>problem soved! bis denn&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2011/11/java-als-service-unter-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Locale in einem Grails-Controller erzwingen</title>
		<link>http://www.wortzwei.de/blogzwei/2011/09/locale-in-einem-grails-controller-erzwingen/</link>
		<comments>http://www.wortzwei.de/blogzwei/2011/09/locale-in-einem-grails-controller-erzwingen/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 12:12:46 +0000</pubDate>
		<dc:creator>Martin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[Action]]></category>
		<category><![CDATA[Controller]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Locale]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=867</guid>
		<description><![CDATA[Manchmal kann es nötig sein ein bestimmtes Locale zu erzwingen, dazu genügt es im betroffenen Controller das localeResolver-Bean injecten zu lassen und dann in einer Action oder im beforeInterceptor, wenn das erzwungene Locale für alle Actions gelten soll, per localeResolver.setLocale(...) das gewünschte Locale zu setzen. class LocaleEnforcingController { def localeResolver ... def beforeInterceptor = { [...]]]></description>
			<content:encoded><![CDATA[<p>Manchmal kann es nötig sein ein bestimmtes Locale zu erzwingen, dazu genügt es im betroffenen Controller das <code>localeResolver</code>-Bean injecten zu lassen und dann in einer Action oder im <code>beforeInterceptor</code>, wenn das erzwungene Locale für alle Actions gelten soll, per <code>localeResolver.setLocale(...)</code> das gewünschte Locale zu setzen.</p>
<p><span id="more-867"></span></p>
<pre>
class LocaleEnforcingController {

  def localeResolver

  ...

  def beforeInterceptor = {
    localeResolver.setLocale(request, response, new Locale(...))
  }

  ...

  def someAction = {
    ...
    localeResolver.setLocale(request, response, new Locale(...))
    ...
  }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2011/09/locale-in-einem-grails-controller-erzwingen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groovy Meta-Programming mit der ExpandoMetaClass</title>
		<link>http://www.wortzwei.de/blogzwei/2011/04/groovy-meta-programming-mit-der-expandometaclass/</link>
		<comments>http://www.wortzwei.de/blogzwei/2011/04/groovy-meta-programming-mit-der-expandometaclass/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 22:07:52 +0000</pubDate>
		<dc:creator>Dirk Dittmar</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=858</guid>
		<description><![CDATA[Ich bin gerade dabei Groovy zu lernen. Wenn ich etwas komplett neues lerne gehe ich eigentlich immer so vor: Im Internet soviel Dokumentation lesen wie verfügbar ist. Ein gutes Buch kaufen und komplett lesen. machen&#8230; Bei Groovy bin ich gerade beim &#8220;machen&#8221; angekommen . Besonders cool finde ich die Unterstützung für Meta-Programming. Nur die Suche [...]]]></description>
			<content:encoded><![CDATA[<p>Ich bin gerade dabei Groovy zu lernen. Wenn ich etwas komplett neues lerne gehe ich eigentlich immer so vor:</p>
<ol>
<li>Im Internet soviel Dokumentation lesen wie verfügbar ist.</li>
<li>Ein gutes Buch kaufen und komplett lesen.</li>
<li>machen&#8230;</li>
</ol>
<p>Bei Groovy bin ich gerade beim &#8220;machen&#8221; angekommen <img src='http://www.wortzwei.de/blogzwei/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .<br />
<span id="more-858"></span></p>
<p>Besonders cool finde ich die Unterstützung für Meta-Programming. Nur die Suche nach einem sinnvollen Beispiel gestaltete sich etwas schwierig. Groovy hat die grundlegenden Klassen von Java bereits mit genügend sehr nützlichen Funktionen ausgestattet. Mir ist allerdings aufgefallen das in String keine Funktion wie <a href="http://commons.apache.org/lang/api-2.5/org/apache/commons/lang/StringUtils.html#isBlank(java.lang.String)">StringUtils.isBlank()</a> hinzugefügt wurde. Die Funktion gehört zu meinen Lieblingsfunktionen und ich verwende sie sehr oft.</p>
<p>Dank der ExpandoMetaClass lässt sich die Funktion leicht hinzufügen:</p>
<pre>
void testIsBlank() {
    String.metaClass.isBlank = {
        -&gt;
        int strLen;
        if ((strLen = delegate.length()) == 0) {
            return true;
        }
        for (int i = 0; i &lt; strLen; i++) {
            if ((Character.isWhitespace(delegate.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    assertTrue &#039; &#039;.blank
    assertTrue &#039;&#039;.blank
    assertFalse &#039;bob&#039;.blank
    assertFalse &#039; bob &#039;.blank
}
</pre>
<p>Vielleicht finden sich ja noch andere nützliche Funktionen in den StringUtils die man einfach String hinzufügen kann?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2011/04/groovy-meta-programming-mit-der-expandometaclass/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eigene Android ListView mit Selektionsdarstellung</title>
		<link>http://www.wortzwei.de/blogzwei/2011/03/eigene-android-listview-mit-selektionsdarstellung/</link>
		<comments>http://www.wortzwei.de/blogzwei/2011/03/eigene-android-listview-mit-selektionsdarstellung/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 10:57:33 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Softwareentwicklung]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ListView]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=834</guid>
		<description><![CDATA[In diesem Artikel möchte ich vorstellen, wie man eine Android ListView erstellt, die wie android.R.layout.simple_list_item_single_choice mit Radiobuttons anzeigt, welches Element gerade selektiert ist, allerdings mit einem eigenen Layout verfeinert wurde. Ziel ist es eine ListView zu implementieren, die wie folgt aussieht: Jeder Eintrag verfügt über ein Icon auf der linken Seite und ein RadioButton auf [...]]]></description>
			<content:encoded><![CDATA[<p>In diesem Artikel möchte ich vorstellen, wie man eine Android ListView erstellt, die wie <code>android.R.layout.simple_list_item_single_choice</code> mit Radiobuttons anzeigt, welches Element gerade selektiert ist, allerdings mit einem eigenen Layout verfeinert wurde.</p>
<p><span id="more-834"></span>Ziel ist es eine ListView zu implementieren, die wie folgt aussieht:</p>
<p><a href="http://www.wortzwei.de/blogzwei/wp-content/uploads/2011/03/listViewDemo1.png"><img class="aligncenter size-medium wp-image-844" src="http://www.wortzwei.de/blogzwei/wp-content/uploads/2011/03/listViewDemo1-197x300.png" alt="" width="197" height="300" /></a></p>
<p>Jeder Eintrag verfügt über ein Icon auf der linken Seite und ein RadioButton auf der rechten Seite, welches den selektierten Eintrag anzeigt. Das Layout für die Aktivität <code>list_view_demo.xml</code>:</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent"&gt;

&lt;RelativeLayout android:layout_width="fill_parent"
android:orientation="horizontal" android:layout_height="wrap_content"
android:paddingTop="10dp" style="@android:style/ButtonBar"&gt;

&lt;Button android:id="@+id/choose_btn" android:text="@string/choose_btn"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:enabled="true" android:layout_alignParentRight="true" /&gt;

&lt;/RelativeLayout&gt;

&lt;ListView android:id="@+id/list_view" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:drawSelectorOnTop="false" /&gt;

&lt;/LinearLayout&gt;</pre>
<p>und speziell für jeden Listeneintrag soll das Layout <code>list_entry.xml</code> genutzt werden. Hier gilt es zu beachten, dass nicht eine <code>CheckBox</code> sondern eine <code>CheckedTextView</code> genutzt wird. Damit wird der Touch-Event immer von der Liste verarbeitet.</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="64dip"
android:gravity="center_vertical" android:ignoreGravity="@+id/icon"&gt;

&lt;ImageView android:id="@+id/icon"
android:layout_alignParentLeft="true" android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:src="@drawable/icon" /&gt;

&lt;TextView android:id="@+id/label"
android:layout_width="200dp" android:paddingLeft="9dip"
android:layout_height="wrap_content" android:layout_toRightOf="@id/icon"
android:layout_centerVertical="true" android:textSize="23dp" /&gt;

&lt;CheckedTextView android:id="@+id/checkstate"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginRight="6dip" android:layout_alignParentRight="true"
android:background="#00000000" android:focusable="false"
android:clickable="false" android:checked="false"
android:checkMark="@android:drawable/btn_radio"
android:layout_centerVertical="true"
/&gt;

&lt;/RelativeLayout&gt;</pre>
<p>Damit ist das Layout definiert und muss nur noch an die Liste übergeben werden. Dies erfolgt durch die Implementierung eines eigenen Adapters. Hierzu habe ich eine private Klasse <code>DomainExampleAdapter</code> erstellt, die mit dem DomainObject <code>DomainExample</code> zusammenarbeitet.</p>
<pre>private class DomainExampleAdapter extends ArrayAdapter&lt;DomainExample&gt; {

  DomainExampleAdapter() {
    super(getApplicationContext(), R.layout.list_entry, itemList);
  }

  public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;

    if (row == null) {
      LayoutInflater inflater = getLayoutInflater();
      row = inflater.inflate(R.layout.list_entry, parent, false);
    }

    TextView label = (TextView) row.findViewById(R.id.label);
    CheckedTextView checkBox = (CheckedTextView) row.findViewById(R.id.checkstate);

    label.setText(itemList.get(position).toString());
    checkBox.setChecked(listView.getCheckedItemPosition() == position);
    return (row);
  }
}</pre>
<p>Das zuvor vorgestellte Layout wird im Konstruktor und Inflater explizit genutzt. Das Überschreiben der Methode <code>getView</code>, welches für jeden Listeneintrag aufgerufen wird, bewirkt, dass das Label und die Checkbox entsprechend gesetzt wird. Hier der Vollständigkeit halber die Klasse <code>DomainExample</code>:</p>
<pre>
public class DomainExample {

  private int id;

  private String name;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String toString() {
    return getName();
  }
}
</pre>
<p>Die Initialisierung der Activity erfolgt wie folgt:</p>
<pre>public class ListViewDemo extends Activity implements View.OnClickListener {

  private ListView listView = null;
  List&lt;DomainExample&gt; itemList = null;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list_view_demo);

    itemList = getItemList();
    listView = (ListView) findViewById(R.id.list_view);
    listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    listView.setAdapter(new DomainExampleAdapter());
    ...
}
...
}</pre>
<p>Die Liste mit den Einträgen wird durch die private Method <code>getItemList</code>. Erzeugt. Anschließend wird die listView anhand der Id ermittelt und der ChoiceMode auf <code>single</code> gesetzt. Dies ist besonders wichtig, da die selektierte Zeile ansonsten nicht über die Methode <code>getCheckedItemPosition()</code> abgefragt werden kann. Zu guter letzt wird der eigene Adapter an die ListView gehängt. Damit haben wir die oben prästentierte ListView komplett umgesetzt.</p>
<p>Ein vollständiges implementiertes Beispiel kann <a href='http://www.wortzwei.de/blogzwei/wp-content/uploads/2011/03/ListViewDemo.zip'>hier</a> heruntergeladen werden. Viel Spaß damit!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2011/03/eigene-android-listview-mit-selektionsdarstellung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>div-Element mit float-Content</title>
		<link>http://www.wortzwei.de/blogzwei/2011/02/div-element-mit-float-content/</link>
		<comments>http://www.wortzwei.de/blogzwei/2011/02/div-element-mit-float-content/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 11:10:56 +0000</pubDate>
		<dc:creator>sven</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>

		<guid isPermaLink="false">http://www.wortzwei.de/blogzwei/?p=461</guid>
		<description><![CDATA[Häufig wünscht sich der gewiefte Webentwickler einen div-Container, in dem diverse Elemente herum-floaten. Der Wunsch nach einer automatischen Höhenanpassung des umschließenden div führt gerne zu einem zusätzlichem Subelement, welches mit style="clear:both" das floating beendet und somit die umschließende Höhenberechnung anstößt. Doch es gibt da auch einen anderen Weg, denn dieses Problem ist komplett mit CSS [...]]]></description>
			<content:encoded><![CDATA[<p>Häufig wünscht sich der gewiefte Webentwickler einen <code>div</code>-Container, in dem diverse Elemente herum-floaten. Der Wunsch nach einer automatischen Höhenanpassung des umschließenden <code>div</code> führt gerne zu einem zusätzlichem Subelement, welches mit <code>style="clear:both"</code> das floating beendet und somit die umschließende Höhenberechnung anstößt. Doch es gibt da auch einen anderen Weg, denn dieses Problem ist komplett mit CSS und ohne ein solch semantisch sinnbefreites Element lösbar!</p>
<p><span id="more-461"></span></p>
<p><strong>Zunächst das Ausgangsproblem:</strong></p>
<pre>&lt;div class="container"&gt;
	&lt;div class="element"&gt;Lorem ipsum ...&lt;/div&gt;
	&lt;div class="element"&gt;Lorem ipsum ...&lt;/div&gt;
&lt;/div&gt;</pre>
<pre>.container {
	margin: 10px;
	padding: 10px;
	background: red;
}
.element {
	margin: 5px; background: yellow;
	float: left;
}</pre>
<p>Aktuelle Situation:<br />
<img src="http://www.wortzwei.de/blogzwei/wp-content/uploads/2010/10/floating_problem.png" alt="floating_problem" width="280" height="70" class="size-full wp-image-473" /><br />
So soll es aussehen:<br />
<img src="http://www.wortzwei.de/blogzwei/wp-content/uploads/2010/10/floating_geloest.png" alt="floating_geloest" width="280" height="70" class="size-full wp-image-473" /></p>
<p><strong>Lösung mittels zusätzlichem Subelement:</strong><br />
Durch Anhängen eines Subelements (bspw. <code>br</code>) mit <code>style="clear:both"</code> wird das floating unterbrochen und die Containerhöhe korrekt berechnet.</p>
<pre>&lt;div class="container"&gt;
	...
	&lt;br style="clear:both" /&gt;
&lt;/div&gt;</pre>
<p><strong>Lösung mit CSS und nichts als CSS:</strong><br />
Fügt man dem Container-<code>div</code> lediglich die folgenden beiden CSS-Attribute zu, so kann man sich das Subelement sparen!</p>
<pre>.container {
	...
	overflow: hidden;	/* für den IE7 und drunter */
	display: table;		/* für den Rest der Browserwelt */
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.wortzwei.de/blogzwei/2011/02/div-element-mit-float-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

