<?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>Phpmonkeys</title>
	<atom:link href="http://www.phpmonkeys.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phpmonkeys.de</link>
	<description>Software Development in PHP</description>
	<lastBuildDate>Fri, 04 May 2012 08:36:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Mockito Magie</title>
		<link>http://www.phpmonkeys.de/2012/05/04/mockito-magie/</link>
		<comments>http://www.phpmonkeys.de/2012/05/04/mockito-magie/#comments</comments>
		<pubDate>Fri, 04 May 2012 08:35:50 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[argumentcaptor]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[mock]]></category>
		<category><![CDATA[mockito]]></category>
		<category><![CDATA[Unittest]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1825</guid>
		<description><![CDATA[Wer Unittests schreibt, weiß wie praktisch Mock-Objekte und die Frameworks sind, die diese zur Verfügung stellen. Heute konnte ich im Mockito-Java Umfeld etwas interessantes von einem Kollegen lernen und gebe das gerne weiter. Mockito ist schon an sich ein sehr &#8230; <a href="http://www.phpmonkeys.de/2012/05/04/mockito-magie/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Wer Unittests schreibt, weiß wie praktisch Mock-Objekte und die Frameworks sind, die diese zur Verfügung stellen. Heute konnte ich im <a href="http://code.google.com/p/mockito/" target="_blank">Mockito</a>-Java Umfeld etwas interessantes von einem Kollegen lernen und gebe das gerne weiter.<br />
<span id="more-1825"></span><br />
Mockito ist schon an sich ein sehr geniales Framework und es macht immer wieder Spaß <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#1" target="_blank"><code>verify</code></a> zu benutzen. Mit dieser Funktion kann man überprüfen, ob eine Methode eines Mock-Objekts aufgerufen wurde. Selbstverständlich kann man diesen Aufurf noch genauer spezifizieren. Beispielsweise geht auch das Gegenteil &#8211; also wurde die Methode <em>nicht</em> aufgerufen. Oder man überprüft, ob diese <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#4" target="_blank">x-mal</a> aufgerufen wurde. Das liegt alles im Ermessen des Programmierers und wird dann sinnvoll eingesetzt.</p>
<p>Der wichtige Punkt ist, das man die Parameter einer Methode angeben muss. Man kann entweder einen festen Wert (oder genauer Objekt) angeben, oder einen <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#3" target="_blank">Matcher</a> nutzen. Matcher erlauben eine gewisse Varianz. Es ist somit möglich zu überprüfen, ob als Parameter eine Klasse des Typs <code>Foo</code> benutzt wurde. Ob das Objekt als valide Eingabe akzeptiert wird, hängt von der Implementierung des Matchers ab.<br />
Nur der Sinn des Tests und die Lesbarkeit sind die Grenze dessen was man machen kann. </p>
<p>Richtig spannend ist der <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#15" target="_blank"><code>ArgumentCaptor</code></a>. Dieser erlaubt es dem Entwickler einen allgemeingültigen Matcher für eine Klasse implizit zu definieren und man erhält auch noch Zugang zum eigentlichen Objekt. D.h. wenn ich wie im unten angeführten Beispiel weiß, dass meine UI im Test ein <code>ResizeEvent</code> feuert und ich den genauen Inhalt des Events benötige, ist der ArgumentCaptor genau die richtige Art und Weise, um den Inhalt relativ leicht zu bekommen.</p>
<pre class="brush: java; title: ; notranslate">
ArgumentCaptor&lt;ResizeEvent&gt; resizeEventCaptor
   = ArgumentCaptor.forClass(ResizeEvent.class);
Mockito.verify(eventBusMock)
   .fireEvent(resizeEventCaptor.capture());
Assert.assertEquals(testPresenter.getMaxW(),
   resizeEventCaptor.getValue().getWidth());
</pre>
<p>In der ersten Zeile wird programmatisch der Captor erzeugt. Dessen <code>capture</code> Methode geben wir als Matcher an und nutzen <code>verify</code> wie wir es gewohnt sind. Da wir auf static-Imports verzichten ist der Aufruf etwas umständlich <code>Mockito.verify</code>. Danach kann man mit <code>assertEquals</code> den Inhalt des Captor-Werts vergleichen. Da der Captor mit Generics arbeitet kann man sich das Casting sparen.</p>
<p>Als kleine Ergänzung kann man statt des programmatischen Aufrufs auch mit Annotationen arbeiten. Dann gibt man <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#21" target="_blank"><code>@Captor</code></a> an und schon wird das Attribut in einen Captor verwandelt. Man sollte hierbei nicht die <a href="http://docs.mockito.googlecode.com/hg/latest/org/mockito/MockitoAnnotations.html#initMocks(java.lang.Object)" target="_blank">Verarbeitung der Annotationen</a> vergessen wie man sie von @Mock kennt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/05/04/mockito-magie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fallstricke: xhtml mit xsl modifizieren</title>
		<link>http://www.phpmonkeys.de/2012/04/05/fallstricke-xhtml-mit-xsl-modifizieren/</link>
		<comments>http://www.phpmonkeys.de/2012/04/05/fallstricke-xhtml-mit-xsl-modifizieren/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 07:16:11 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[problem]]></category>
		<category><![CDATA[xhtml]]></category>
		<category><![CDATA[xsl]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1802</guid>
		<description><![CDATA[Bei der täglichen Entwicklung bin ich auf ein interessantes Problem gestoßen und damit die Lösung etwas bekannter wird, gibt es dazu einen neuen Beitrag. Dieses Problem tat sich im Umfeld xhtml und xsl auf. Wenn man eine xhtml Datei per &#8230; <a href="http://www.phpmonkeys.de/2012/04/05/fallstricke-xhtml-mit-xsl-modifizieren/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Bei der täglichen Entwicklung bin ich auf ein interessantes Problem gestoßen und damit die Lösung etwas bekannter wird, gibt es dazu einen neuen Beitrag. Dieses Problem tat sich im Umfeld <a href="http://www.w3.org/TR/xhtml11/" target="_blank">xhtml</a> und <a href="http://de.wikipedia.org/wiki/XSL_Transformation" target="_blank">xsl</a> auf. Wenn man eine xhtml Datei per xsl modifizieren will, kann es passieren, dass die Modifikation nicht greift und das verursacht gerne mal das eine oder andere graue Haar.<br />
<span id="more-1802"></span><br />
Zuerst aber die Ausgangssituation. Wir haben eine xhtml Datei und müssen diese weiter verarbeiten. Der Aufbau dieser Datei ist aber für die Verarbeitung ungünstig und gewisse Elemente sollen daher entfernt bzw. vereinfacht werden. Die erste Idee ist xsl zu benutzen, da man damit über XPath-Ausdrücke den DOM schnell durchsuchen und Elemente manipulieren kann.</p>
<p>Also benötigt man zuerst eine Identitätsregel, damit die Eingabe-xhtml-Datei zur Ausgabe-xhtml-Datei umkopiert wird. Eine solche Regel sieht bspw so aus:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:template match=&quot;@*|node()&quot;&gt;
	&lt;xsl:copy&gt;
		&lt;xsl:apply-templates select=&quot;@*&quot; /&gt;
		&lt;xsl:apply-templates /&gt;
	&lt;/xsl:copy&gt;
&lt;/xsl:template&gt;
</pre>
<p>Nun ergänzt man Regeln, die auf bestimmte Elemente oder Elementkonstellationen reagieren. Beispielhaft entfernen wir einfach alle <code>input</code>-Elemente, da wir für diese keine Verwendung haben. Möglich sind natürlich beliebige andere Regeln.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;xsl:template match=&quot;input&quot; /&gt;
</pre>
<p>Setzt man dieses Stylesheet auf eine xhtml-Datei an, läuft man in das obige Problem. Da eine xhtml Datei üblicherweise einen Namespace hat, wird das Stylesheet nur die Identitätsregel anwenden können. Wir müssen also noch im Header des Stylesheets Modifikationen vornehmen, wie sie <a href="http://xmlplease.com/xhtmlxhtml" target="_blank">hier</a> beschrieben sind.</p>
<p>Dadurch erhalten wir folgendes Stylesheet und dieses funktioniert dann auch wie gedacht:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;xsl:stylesheet
	xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot; version=&quot;1.0&quot;
	xmlns:xhtml=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;
	exclude-result-prefixes=&quot;xhtml xsl xs&quot; &gt;
	&lt;xsl:output encoding=&quot;utf-8&quot; method=&quot;xml&quot;/&gt;

	&lt;xsl:template match=&quot;xhtml:input&quot; /&gt;

	&lt;xsl:template match=&quot;@*|node()&quot;&gt;
		&lt;xsl:copy&gt;
			&lt;xsl:apply-templates select=&quot;@*&quot; /&gt;
			&lt;xsl:apply-templates /&gt;
		&lt;/xsl:copy&gt;
	&lt;/xsl:template&gt; 

&lt;/xsl:stylesheet&gt;
</pre>
<p>Besonders zu beachten ist, das man entsprechende Namespace Prefixe in den Regeln verwenden muss. Und wie sooft gilt: Wenn man es weiß, ist es eigentlich ganz einfach.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/04/05/fallstricke-xhtml-mit-xsl-modifizieren/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deployment Descriptor, Servlet-Filter und die Error Codes</title>
		<link>http://www.phpmonkeys.de/2012/02/23/deployment-descriptor-servlet-filter-und-die-error-codes/</link>
		<comments>http://www.phpmonkeys.de/2012/02/23/deployment-descriptor-servlet-filter-und-die-error-codes/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 10:20:53 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[deployment descriptor]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mapping]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[status code]]></category>
		<category><![CDATA[web.xml]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1786</guid>
		<description><![CDATA[Diesmal gibt es einen kurzen Beitrag aus der Java Ecke, da mich das Thema beschäftigte und ich eine Lösung suchen musste, um das Problem zu lösen. Hinterher ist man immer schlauer und daran lasse ich euch gerne teil haben Die &#8230; <a href="http://www.phpmonkeys.de/2012/02/23/deployment-descriptor-servlet-filter-und-die-error-codes/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Diesmal gibt es einen kurzen Beitrag aus der Java Ecke, da mich das Thema beschäftigte und ich eine Lösung suchen musste, um das Problem zu lösen. Hinterher ist man immer schlauer und daran lasse ich euch gerne teil haben <img src='http://www.phpmonkeys.de/wp-includes/images/smilies/icon_wink.gif' alt="Icon Wink in Deployment Descriptor, Servlet-Filter und die Error Codes" class='wp-smiley' /><br />
<span id="more-1786"></span><br />
Die Konfiguration des Deployment Descriptors ist ganz schön umfangreich und so kann man da gerne mal den Überblick verlieren. Ich stand vor dem Problem, dass ein Filter nicht greifen wollte, wenn ein Status Code ungleich 200 gesendet wurde.</p>
<p>Aber eins nach dem anderen. Möchte man im Fehlerfall eine angepasste Fehlerseite ausliefern kann man zu dem jeweiligen Fehlercode eine Seite angeben. Dies passiert mit einem Codestück ähnlich diesem:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;error-page&gt;
    &lt;error-code&gt;404&lt;/error-code&gt;
    &lt;location&gt;/error404.html&lt;/location&gt;
&lt;/error-page&gt;
</pre>
<p>Der <code>Error-Code</code> entspricht dem Statuscode und die Location ist die Seite, die statt der Standard-Fehlerseite ausgeliefert werden soll.</p>
<p>Der Servlet-Filter wird vor und/oder nach dem eigentlichen Servlet, das den entsprechenden Request verarbeitet gesetzt. Es handelt sich dabei einfach um eine Klasse die von Filter abgeleitet werden muss. In der web.xml wird ein solcher Filter in etwa so verankert:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!-- define the filter --&gt;
&lt;filter&gt;
   &lt;filter-name&gt;MyMightyFilter&lt;/filter-name&gt;
   &lt;filter-class&gt;org.example.util.filters.MightyFilter&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;!-- now map this filter to a URL-pattern --&gt;
&lt;filter-mapping&gt;
   &lt;filter-name&gt;MyMightyFilter&lt;/filter-name&gt;
   &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
<p>Der Filter behandelt nun alle Urls und kann mit den Request und Response Daten etwas tun. Jetzt ist der Filter aber auch noch auf bestimmte Dispatcher eingeschränkt. Nur wenn ein Request oder Forward ausgeführt wird soll er aktiv werden. Somit sieht das Mapping ein wenig anders aus:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;filter-mapping&gt;
   &lt;filter-name&gt;MyMightyFilter&lt;/filter-name&gt;
   &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
   &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
   &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;
</pre>
<p>Nun kommen wir zu dem eigentlich Problem. Der Filter greift in diesem Fall nicht, wenn eine ErrorCode-Seite (wie oben definiert) ausgeliefert werden soll. Wenn bspw. die Verzeichnisse im Request umgeschrieben werden ist die Auswirkung recht eindeutig. Die Fehlerseite kann ihrerseits nicht gefunden werden. Wo liegt nun das Problem?</p>
<p>Die Lösung ist recht einfach. Man muss dem filter Mapping auch noch den ERROR-Dispatcher mitgeben, denn genau der wird betrachtet, wenn eine Fehlerseite ausgeliefert werden soll. Eigentlich ist das logisch und auch sinnvoll, da man so im Fehlerfall einen Filter umgehen kann. Der korrekte Code für das Problem lautet somit:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;filter-mapping&gt;
   &lt;filter-name&gt;MyMightyFilter&lt;/filter-name&gt;
   &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
   &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
   &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
   &lt;dispatcher&gt;ERROR&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/02/23/deployment-descriptor-servlet-filter-und-die-error-codes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rezension: Agiles Coaching</title>
		<link>http://www.phpmonkeys.de/2012/02/09/rezension-agiles-coaching/</link>
		<comments>http://www.phpmonkeys.de/2012/02/09/rezension-agiles-coaching/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 08:04:36 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[agile Entwicklung]]></category>
		<category><![CDATA[Coaching]]></category>
		<category><![CDATA[Scrum]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1743</guid>
		<description><![CDATA[Heute gibt es eine Rezension zu dem Buch &#8220;Agiles Coaching&#8221; von mitp. Da mich die agile Softwareentwicklung sehr interessiert und ich auch selbst Teil eines Scrum-Teams bin, ist es für mich spannend zu lesen wie man ein Team coached. Kommen &#8230; <a href="http://www.phpmonkeys.de/2012/02/09/rezension-agiles-coaching/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute gibt es eine Rezension zu dem Buch &#8220;<a href="http://www.mitp.de/9046" target="_blank">Agiles Coaching</a>&#8221; von mitp. Da mich die agile Softwareentwicklung sehr interessiert und ich auch selbst Teil eines Scrum-Teams bin, ist es für mich spannend zu lesen wie man ein Team coached.<br />
<span id="more-1743"></span><br />
Kommen wir erst einmal zu den Kenndaten des Buchs. Es ist von Rachel Davies und Liz Sedley geschrieben und hat ca. 300 Seiten. Thematisch bedingt richtet es sich &#8211; wie der Name schon sagt &#8211; hauptsächlich an Teamleiter, Projektmanager und ScumMaster. Unabhängig davon kann jeder, der in einem agilen Team arbeitet (oder arbeiten will), einen Blick in dieses Buch riskieren und mit Sicherheit noch den einen oder anderen Punkt lernen. </p>
<h4>Struktur</h4>
<p>Die Grobstruktur umfasst die Themenbereiche Coaching, Planen, Qualität und Feedback. Die einzelnen Themenbereiche sind in weiter Kapitel unterteilt. Diese haben immer einen sehr ähnlichen Aufbau. Einleitend gibt es eine Beschreibung, welches Thema betrachtet wird. Anschließend wird das Thema weiter vertieft. Sehr spannend ist der wiederkehrende Abschnitt über mögliche Hindernisse. Hier wird man als Coach auf bevorstehende Probleme vorbereitet. Und alle Kapitel werden mit einer Checkliste abgeschlossen, die die wichtigsten Ideen des aktuellen Kapitel noch einmal zusammenfasst.</p>
<p>Die Kapitel umfassen den gesamten agilen Prozess. Neben Themen wie <em>User Stories</em>, <em>Aufbau eines agilen Teams</em>, <em>Daily Standup</em>, <em>Retrospektive</em> kommt auch der Bereich Entwicklung nicht zu kurz: <em>Continuous Integration</em>, <em>Unit Tests</em>, <em>Refactoring</em> und <em>Clean Code</em> sind nur ein paar Beispiele.</p>
<p>Um das Ganze abzurunden gibt es in jedem Kapitel Beispiele aus der Praxis der beiden Autoren und weitere hilfreiche Tipps. </p>
<p>Wem die ganzen Informationen noch zuwenig sind, findet mit den Quellennachweisen weitere Bücher und Links, mit denen sich das Thema agile Softwareentwicklung und der agile Prozess vertiefen lässt. </p>
<h4>Fazit</h4>
<p>Mir hat das Buch sehr gut gefallen, da neben der durchdachten Struktur das Lesen auch richtig viel Spaß macht. Ich kann das Buch agilen Coaches empfehlen, aber auch die üblichen Mitglieder eines agilen Teams können hier viele nützliche Informationen finden, die die tägliche Arbeit verbessern können.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/02/09/rezension-agiles-coaching/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Review: Virtual GIT Summit</title>
		<link>http://www.phpmonkeys.de/2012/02/02/review-virtual-git-summit/</link>
		<comments>http://www.phpmonkeys.de/2012/02/02/review-virtual-git-summit/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 08:42:14 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[php|architect]]></category>
		<category><![CDATA[summit]]></category>
		<category><![CDATA[virtual Git Summit]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1748</guid>
		<description><![CDATA[Gestern Abend fand das Virtual GIT Summit statt und dazu gibt es hier ein kleines Review. Technik Da es &#8220;Virtual&#8221; heißt, kann man schon erraten, dass es sich nicht um eine normale Konferenz handelt. Vielmehr wurde alles über das Netz &#8230; <a href="http://www.phpmonkeys.de/2012/02/02/review-virtual-git-summit/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Gestern Abend fand das <a href="http://www.phparch.com/phparchitect-live-presents-the-virtual-git-summit/" target="_blank">Virtual GIT Summit</a> statt und dazu gibt es hier ein kleines Review.<br />
<span id="more-1748"></span></p>
<h2>Technik</h2>
<p>Da es &#8220;Virtual&#8221; heißt, kann man schon erraten, dass es sich nicht um eine normale Konferenz handelt. Vielmehr wurde alles über das Netz gestreamt und somit konnte man weltweit aus dem trauten Heim der Veranstaltung folgen. Als Basis diente die Vuze Meeting Seite. Über einen Link gelangte man in den entsprechenden Raum und über eine Skype Verbindung zu Vuze Meeting wurde die Tonspur bereitgestellt. Somit wurde eine bewährte Technik für den Audio-Stream genutzt, was ich recht schick finde. Es bestand auch die Möglichkeit den Stream über die Webseite zu beziehen aber laut den anderen Teilnehmern war die Skype-Lösung tendenziell besser. Die Einwahl per telefon wäre auch möglich gewesen, aber von Deutschland her wenig sinnvoll. Support wurde über einen IRC-Channel im freenode-Netz geleistet. Hierüber konnte man auch Fragen an die Referenten weitergeben.</p>
<h2>Speaker</h2>
<p>Es gab 4 Referenten, die jeweils ca. eine Stunde Sprechzeit hatten. Genutzt wurde zumeist für den Vortrag zwischen 45 und 50 Minuten. Danach gab es noch die Möglichkeit Fragen zu stellen. </p>
<h4><em>David Collier</em> &#8211; &#8220;Basics of Git&#8221;</h4>
<p>Der Vortrag von David war eine sehr gute Einführung zu den Grundlagen von Git. Vergleiche zu Subversion wurden gezogen und die Befehle vorgestellt, die einen Entwickler bei der täglichen Arbeit begleiten. Auf der Tonspur gab es sehr viele Informationen zu den recht übersichtlichen Folien. Leider gab es beim Screensharing ein paar technische Probleme und so musste eine Alternative gefunden werden. Diese war recht suboptimal und hat die Live-Vorführung etwas überflüssig gemacht. Der Bildaufbau war einfach zu langsam, oder David zu schnell. Aber die Grundlagen kann man natürlich auch leicht selbst ausprobieren.<br />
Folien: <a href="http://speakerdeck.com/u/davidcoallier/p/git-basics" target="_blank">http://speakerdeck.com/u/davidcoallier/p/git-basics</a></p>
<h4><em>John Mertic</em> &#8211; &#8220;Subversion to Git: A Sugar Story&#8221;</h4>
<p>Hier ging es schon ein bisschen weiter und John hat einige Anekdoten aus seiner Entwickler-Zeit erzählt. Wie man von Subversion zu Git migriert und welche Herausforderungen dadurch an ein Entwicklerteam gestellt werden. Insgesamt sehr spannend und unterhaltsam. Leider gab es einige Aussetzer im Audio Stream.<br />
Folien: <a href="http://www.slideshare.net/jmertic/the-virtual-git-summit-subversion-to-git-a-sugar-story" target="_blank">http://www.slideshare.net/jmertic/the-virtual-git-summit-subversion-to-git-a-sugar-story</a></p>
<h4><em>Chris Hartjes</em> &#8211; &#8220;You’ve Decided to Use Git as Your VCS for Your Team…So Now What?&#8221;</h4>
<p>Chris Vortrag ging noch einen Schritt weiter und das Thema war im Großen, wie man mit Git Branches organisiert. Dabei ging es um Feature-, Bugfix-, Staging-Branches und den Master. Er hat somit aus dem Leben eines Entwicklers berichtet der <a href="http://nvie.com/posts/a-successful-git-branching-model/" target="_blank">nach diesem Muster</a> branched. Diesmal gab es keine technischen Schwierigkeiten und der Vortrag war ebenfalls sehr gut und auch recht locker gehalten.<br />
Folien: <a href="http://speakerdeck.com/u/grumpycanuck/p/youve-decided-to-use-git-as-your-vcs-for-your-teamso-now-what" target="_blank">http://speakerdeck.com/u/grumpycanuck/p/youve-decided-to-use-git-as-your-vcs-for-your-teamso-now-what</a></p>
<h4><em>Travis Swicegood</em> &#8211; &#8220;Git’s Meat Cleavers&#8221;</h4>
<p>Travis hat schon auf einer höheren Ebene begonnen und hat mich als Git Laien nach ca. 15-20 Minuten vollkommen abgehängt. Es ging um die Themen Rebase und Bisect. Wer mit Git arbeitet wird in den Folien sicher wertvolle Informationen finden, ich werde diese wohl erst zu einem späteren Zeitpunkt zu schätzen wissen. Der Vortrag an sich war sehr strukturiert und nach jedem Abschnitt gab es die Möglichkeit für das Publikum Fragen zu stellen. Die Technik spielte auch diesmal mit und somit war der Vortrag ein gelungener Abschluß.<br />
Folien: <a href="http://speakerdeck.com/u/tswicegood/p/gits-meat-cleavers" target="_blank">http://speakerdeck.com/u/tswicegood/p/gits-meat-cleavers</a></p>
<h2>Fazit</h2>
<p>Das &#8220;Virtual Git Summit&#8221; hat wirklich Spaß gemacht und einen guten Motivations-Schub gegeben, sich mehr mit Git zu beschäftigen. Interessant war die Tatsache, dass die ersten 3 Referenten Github sehr gelobt haben und im Chat auch eine ähnliche Meinung vorherrschte. Nicht nur wegen der Opensource-Projekte, sondern vor allem im Firmenumfeld als Ersatz für ein Inhouse-Repository. Wenn Zeit und Themen passen, werde ich sicher bei weiteren virtuellen Summits dabei sein.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/02/02/review-virtual-git-summit/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>QR-Codes erstellen</title>
		<link>http://www.phpmonkeys.de/2012/01/26/qr-codes-erstellen/</link>
		<comments>http://www.phpmonkeys.de/2012/01/26/qr-codes-erstellen/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 09:07:40 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[qr code]]></category>
		<category><![CDATA[qrcode]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1705</guid>
		<description><![CDATA[Seit ein paar Jahren gibt es die QR-Codes zu sehen. Mit der Verbreitung der Smartphones hat sich die Verbreitung stark erhöht und überall stößt man auf die Quadrate, die an durcheinander gewürfelte Schachbretter erinnern. Sehr beliebt sind diese Muster im &#8230; <a href="http://www.phpmonkeys.de/2012/01/26/qr-codes-erstellen/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit ein paar Jahren gibt es die QR-Codes zu sehen. Mit der Verbreitung der Smartphones hat sich die Verbreitung stark erhöht und überall stößt man auf die Quadrate, die an durcheinander gewürfelte Schachbretter erinnern. Sehr beliebt sind diese Muster im Zusammenhang mit den vielen Android-Seiten.<br />
<span id="more-1705"></span></p>
<h2>Was ist der QR-Code eigentlich?</h2>
<p>Der Begriff QR-Code steht für Quick Response Code und es handelt sich um einen 2-dimensionalen Code, der von Denso Wave im Jahre 1994 entwickelt wurde. Die Größe ist abhängig von der Datenmenge und von der Güte der Fehlerkorrektur. Die kleineren Quadrate werden von der Erkennungssoftware zur Bestimmung der Ausrichtung genutzt. Im Code selbst werden Daten transportiert. Smartphones haben die Software zur Erkennung schon installiert oder aber sie lässt sich im jeweiligen AppStore/Market finden. Ich persönlich nutze Google Goggles unter Android. </p>
<h2>Welche Daten werden hinterlegt</h2>
<p>QR-Codes findet man inzwischen an vielen Stellen, an denen man eine Brücke zwischen einem Offline- und einem Online-Medium schlagen möchte oder muss. Werbung in Zeitschriften bspw. verweist auf die entsprechende Internetseite des Herstellers. Es können aber auch Telefonnummern, vCards oder speziellere Daten hinterlegt werden. Wlan-Zugangsdaten werden u.a. gerne in einem QR-Code für die Gäste eines Cafes hinterlegt.<br />
Die Erkennungssoftware ist normalerweise so programmiert, dass sie bestimmte Muster in den Daten erkennt und davon abhängig eine entsprechende Software startet. Solche Muster sehen bspw so aus:</p>
<h4>Webseiten</h4>
<ul>
<li>http://www.phpmonkeys.de</li>
<li>market://details?id=com.google.android.apps.unveil</li>
</ul>
<h4>Email</h4>
<ul>
<li>mailto:user@example.com</li>
<li>mailto:user@example.com?subject=Readme</li>
</ul>
<h4>Telefon</h4>
<ul>
<li>tel:012345678</li>
</ul>
<h4>Kontaktdaten (vCard)</h4>
<ul>
<li><a href="http://www.ietf.org/rfc/rfc2426.txt" target="_blank">siehe vCard Spec</a></li>
<li><a href="http://de.wikipedia.org/wiki/VCard" target="_blank">Kurzübersicht (Wikipedia)</a></li>
</ul>
<h2>QR-Codes generieren im Netz</h2>
<p>Wie so ein Code aussieht ist rudimentär klar und welche Daten darin enthalten sein können haben wir auch gesehen. Jetzt geht es an die Generierung. Der einfachste Weg ist eine entsprechende Seite zu nutzen. Dies bietet sich vor allem dann an, wenn man nicht viele Codes benötigt oder wenn man die Generierung auslagern möchte.</p>
<h4>Kaywa</h4>
<p>Ein besonders einfaches Formular zum Erstellen solches Codes findet man bei Kaywa. Dies ist auch der Hersteller von entsprechender Software, die die Codes analysieren kann. Dort kann man ein paar Informationen angeben und schon wird ein QR-Code generiert. Einen statischen Link dazu gibt es auch. Besonders nett an dem Formular ist die Auswahl nach den verschiedenen Möglichkeit. Vorlagen für URL, Telefon und SMS sind bereits vorhanden und ein generelles Text-Eingabefeld gibt es auch noch. Leider gibt es aber einige Limitierungen und das Formular ist auch nur für die private Nutzung erlaubt. Für die ersten Tests reicht dies aber allemal aus.<br />
<em>Link</em>: <a href="http://qrcode.kaywa.com/" target="_blank">http://qrcode.kaywa.com/</a></p>
<h4>Google Chart API</h4>
<p>Möchte man QR-Codes dynamisch erzeugen so bietet Google eine entsprechende API an. Über den Generator für Charts kann man neben schönen Diagrammen auch die QR-Codes generieren. Hierbei muss man im Gegensatz zu kaywa aber wissen, welchen textlichen Inhalt man im Code unterbringen muss. Wie sieht ein Telefonnummer-QR-Code aus? Und dann ist die Google API ein gutes Stück interessanter.<br />
Der Aufruf ist sehr überschaubar:</p>
<pre class="brush: bash; title: ; notranslate">

https://chart.googleapis.com/chart?chs=150x150&#038;cht=qr&#038;chl=Hello%20world
</pre>
<p>Die Parameter ergeben sich folgendermaßen:</p>
<ul>
<li><code>chs</code>: Die Größe des Codes im Format <em>Breite</em>x<em>Höhe</em></li>
<li><code>cht</code>: Hier steht qr, weil das eben der Typ ist</li>
<li><code>chl</code>: Der Inhalt des QR-Codes in einem URL-Encoded Format</li>
</ul>
<p>Netterweise kann man statt der GET-Syntax auch die Daten per POST übermitteln. Hierbei wird dann natürlich ein Formular oder eine Zwischenschicht benötigt, die die Daten per POST übermitteln kann. Zum Beispiel mit cURL auf der Kommandozeile oder natürlich mit  PHP, wie man das Übermitteln von POST-Daten ja kennt.<br />
Dadurch ist man auch in der Lage komplexere Daten in einem QR-Code unterzubringen und die Menge der Daten erhöht sich ebenfalls. Denn üblicherweise ist eine GET-Anfrage auf ca 2k beschränkt, POST hingegen kann 16k übermitteln. Unter dem angegebenen Link finden sich einige Beispiele für die Benutzung.<br />
<em>Link</em>: <a href="http://code.google.com/intl/de-DE/apis/chart/infographics/" target="_blank">http://code.google.com/intl/de-DE/apis/chart/infographics/</a></p>
<h2>PHP QR Code Library</h2>
<p>Die vorgestellten Methoden benutzen beiden den Service eines Dritten. Wer nun seine Codes selbst erstellen möchte, muss auf eine entsprechende Bibliothek zurückgreifen. Als Beispiel dient hier <a href="http://phpqrcode.sourceforge.net/" target="_blank">PHPQRCode</a>. Um einen QR-Code zu generieren muss man nur qrlib inkludieren. Die Generierung geschieht dann über den Aufruf einer statischen Methode. Hierbei sind einige Parameter verfügbar. Beispielhaft sieht dies so aus:</p>
<pre class="brush: php; title: ; notranslate">
require 'qrlib.php';
QRcode::png('http://www.phpmonkeys.de', 'code.png', QR_ECLEVEL_H, 10);
</pre>
<p>Die Daten werden als erster Parameter übergeben, dann folgt der Dateiname, die Fehlerkorrektur und die Größe. Fehlerkorrektur und Größe sind optional.</p>
<h2>Fazit</h2>
<p>Das eigentliche Geheimnis der QR-Codes liegt in den Daten und in der Formatierung dieser. Wenn eine Software ein spezielles Format unterstützt, so kann man viele Eingaben vereinfachen.<br />
Eine kommende Alternative könnten die NFC-Tags sein. Diese Aufkleber lassen sich ebenso mit Daten befüllen. Jedoch sind QR-Codes sehr viel einfacher und günstiger herzustellen und können von jedem Gerät mit Kamera gelesen und ausgewertet werden.</p>
<p>Ergänzend für nk hier noch 4 Testdateien. Diese haben 1k bis 4k an Daten als Inhalt. Wobei als letztes Zeichen ein A angegeben ist und alle Zeichen zuvor eine 1 sind. Dadurch kann man einfach sicherstellen, dass alle Zeichen im QRCode vorhanden sind.  </p>
<ul>
<li><a href="http://www.phpmonkeys.de/wp-content/uploads/2012/01/code_large_1k.png" target="_blank">QR Code 1k</a></li>
<li><a href="http://www.phpmonkeys.de/wp-content/uploads/2012/01/code_large_2k.png" target="_blank">QR Code 2k</a></li>
<li><a href="http://www.phpmonkeys.de/wp-content/uploads/2012/01/code_large_3k.png" target="_blank">QR Code 3k</a></li>
<li><a href="http://www.phpmonkeys.de/wp-content/uploads/2012/01/code_large_4k.png" target="_blank">QR Code 4k</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/01/26/qr-codes-erstellen/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Scrumwall &#8211; mit oder ohne digitale Hilfsmittel?</title>
		<link>http://www.phpmonkeys.de/2012/01/19/scrumwall-mit-oder-ohne-digitale-hilfsmittel/</link>
		<comments>http://www.phpmonkeys.de/2012/01/19/scrumwall-mit-oder-ohne-digitale-hilfsmittel/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 09:16:35 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[agile Entwicklung]]></category>
		<category><![CDATA[Board]]></category>
		<category><![CDATA[Scrum]]></category>
		<category><![CDATA[Scrumboard]]></category>
		<category><![CDATA[Scrumwall]]></category>
		<category><![CDATA[Wall]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1691</guid>
		<description><![CDATA[Heute gibt es wieder einen &#8220;Mitmach&#8221;-Beitrag. Es geht um das Thema Scrum und im Speziellen um die Scrumwall (oder Scrumboard). Auf dieser sind die aktuellen Aufgaben angeheftet und wandern durch die verschiedenen Status hindurch bis sie zur Übersicht abgenommen werden &#8230; <a href="http://www.phpmonkeys.de/2012/01/19/scrumwall-mit-oder-ohne-digitale-hilfsmittel/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Heute gibt es wieder einen &#8220;Mitmach&#8221;-Beitrag. Es geht um das Thema Scrum und im Speziellen um die Scrumwall (oder Scrumboard). Auf dieser sind die aktuellen Aufgaben angeheftet und wandern durch die verschiedenen Status hindurch bis sie zur Übersicht abgenommen werden können. Oftmals wird in der Literatur ein Whiteboard oder ähnliches Instrument beschrieben, das mit Papierkärtchen gefüllt ist. Wie sieht das bei euch aus? Gibt es ein digitales Pendant?<br />
<span id="more-1691"></span><br />
Doch bevor es Kommentare zu dem Thema zu lesen gibt, hier auch die Vorgehensweise die sich bei uns im Team etabliert hat und die bisher gut funktioniert. </p>
<p>Für unser Daily Scrum arbeiten wir mit einer herkömmlichen Scrumwall. Dort befinden sich dann auch die Karten aus Papier. Diese werden entsprechend des Zustandes verschoben und sind mit einer kurzen Beschreibung versehen und mit einer Referenz auf unseren Bugtracker. </p>
<p>Durch den Bugtracker haben wie die Möglichkeit Arbeitszeiten, zusätzliche Informationen, fachliche und technische Anmerkungen an der jeweiligen Aufgabe anzuhängen. Diese Aufgaben werden natürlich nicht als Bug erfasst, sondern haben einen eigenen Typ. Als Tool wird <a href="http://www.atlassian.com/software/jira/overview" target="_blank">Jira</a> benutzt. Wir nutzen die <a href="http://www.atlassian.com/software/greenhopper/overview" target="_blank">Greenhopper Erweiterung</a> nicht, sondern haben für die Aufgaben eigentlich in der digitalen Fassung nur <em>3</em> Zustände. </p>
<ol>
<li>Aufgabe liegt beim Product Owner und ist noch nicht bereit für die Entwicklung</li>
<li>Aufgabe wird von einem Entwickler bearbeitet und ist diesem zugeordnet</li>
<li>Aufgabe liegt beim PO ist aber als geschlossen markiert, d.h. die Aufgabe ist erledigt</li>
</ol>
<p>Ein großer Vorteil des Vorgehens ist für uns, dass man über die Jira-Referenznummern die Aufgaben schneller findet und so auch in weiteren Dokumenten verlinken kann.<br />
Mitarbeiter die nicht vor Ort arbeiten können so auch alle Informationen ihrer Aufgaben im Blick haben und der Verwaltungsoverhead wird möglichst gering gehalten.</p>
<p>Nun kommen wir aber zurück zur eingangs gestellten Frage. Wie sieht das bei euch aus? Benutzt ihr eine spezielle Software und wenn ja, welche? Benutzt ihr nur Papier und Whiteboard?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/01/19/scrumwall-mit-oder-ohne-digitale-hilfsmittel/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>RESTful Webservices mit PHP</title>
		<link>http://www.phpmonkeys.de/2012/01/12/restful-webservices-mit-php/</link>
		<comments>http://www.phpmonkeys.de/2012/01/12/restful-webservices-mit-php/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 08:46:48 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[slim framework]]></category>
		<category><![CDATA[webservice]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1659</guid>
		<description><![CDATA[Webapplikationen bieten oftmals eine Schnittstelle an, über die auch Entwickler den angebotenen Service in ihren Applikationen nutzen können. Diese Webservices wurden gerne durch XML-RPC oder SOAP bereitgestellt. Doch der neue Trend ist REST. Was ist REST? REST steht für REpresentational &#8230; <a href="http://www.phpmonkeys.de/2012/01/12/restful-webservices-mit-php/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Webapplikationen bieten oftmals eine Schnittstelle an, über die auch Entwickler den angebotenen Service in ihren Applikationen nutzen können. Diese Webservices wurden gerne durch XML-RPC oder SOAP bereitgestellt. Doch der neue Trend ist REST.<br />
<span id="more-1659"></span></p>
<h2>Was ist REST?</h2>
<p>REST steht für REpresentational State Transfer und wurde von Thomas Roy Fielding in seiner <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" target="_blank">Dissertation</a> benannt. REST benutzt URLs um Ressourcen bereitzustellen und das Hypertext Transfer Protocol um Manipulationen an diesen Ressourcen durchzuführen. Die einzelnen HTTP-Methoden werden für verschiedene Operationen genutzt dabei entspricht GET Lesen, PUT Update, POST Create und DELETE Löschen.</p>
<h2>REST-Service in PHP &#8211; das Slim-Framework</h2>
<p>Möchte man einen solchen REST-Service erstellen bietet sich das <a href="http://www.slimframework.com/" target="_blank">Slim-Framework</a> an. Die Sourcen können bei <a href="https://github.com/codeguy/Slim" target="_blank">Github</a> gefunden werden. Der Aufbau eines Hello-World-Services ist denkbar einfach.</p>
<pre class="brush: php; title: ; notranslate">
require 'Slim/Slim.php';
$app = new Slim();
$app-&gt;get('/hello/:name', function ($name) {
   echo &quot;Hello $name&quot;;
});
$app-&gt;run();
</pre>
<p>Die interessante Zeile ist <code>$app->get()</code>. Hier wird ein Pfad und ein Parameter mit einer Funktion verknüpft. Das ganze verwendet die GET-Methode von HTTP.</p>
<p>Wenn man einen umfangreicheren Service anbieten will, werden weitere Methoden verwendet wie zum Beispiel PUT, DELETE, POST.</p>
<p>Als Beispiel sei ein Service für die Verwaltung einer Person zu nennen der so aussehen könnte:</p>
<pre class="brush: php; title: ; notranslate">
require 'Slim/Slim.php';
$app = new Slim();
$app-&gt;get('/person/:id', function ($id) {
   // retrieve person
});

$app-&gt;post('/person', function () {
   // create person
});

$app-&gt;put('/person/:id', function ($id) {
   // update data
});

$app-&gt;delete('/person/:id', function ($id) {
   // delete data
});

$app-&gt;run();
</pre>
<p>Das Framework bietet neben der REST-Funktionalität auch noch eine Logging Komponente und alles ist mit Unittest abgedeckt.</p>
<h2>Testen mit Chrome und FF</h2>
<p>Um den REST-Service zu nutzen benötigt man normal einen REST-Client. Für Tests ist es natürlich überaus praktisch, wenn man die einzelnen Funktionen manuell triggern kann. </p>
<p>Hierfür gibt es eine <a href="https://chrome.google.com/webstore/detail/hgmloofddffdnphfgcellkdfbfbjeloo" target="_blank">Chrome Erweiterung</a>, die den Entwickler die Methode, Header Information und Daten (bspw POST) setzen lässt. </p>
<p>Eine <a href="https://addons.mozilla.org/en-US/firefox/addon/restclient/" target="_blank">Firefox Extension</a> gibt es auch, die ich aber bisher nicht getestet habe. </p>
<h2>Webservice Tipp</h2>
<p>Beim Entwerfen eines REST-Webservices sollte man gleich die Versionierung der API bedenken. So sollten Ressourcen dann bspw. über URLS wie <code>/v1/person/1234</code> bereitgestellt werden. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/01/12/restful-webservices-mit-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>GWT &#8211; den CI Build beschleunigen</title>
		<link>http://www.phpmonkeys.de/2012/01/05/gwt-den-ci-build-beschleunigen/</link>
		<comments>http://www.phpmonkeys.de/2012/01/05/gwt-den-ci-build-beschleunigen/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 09:55:03 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Build]]></category>
		<category><![CDATA[CI]]></category>
		<category><![CDATA[GWT]]></category>
		<category><![CDATA[Hudson]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Jenkins]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Speed Up]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1614</guid>
		<description><![CDATA[Um ein CI-System sinnvoll zu nutzen, muss der Build möglichst schnell laufen. Dazu gehören neben dem Unittests auch der GWT Compiler und an beiden Stellen gibt es einige Optimierungsmöglichkeiten die wir heute mal betrachten werden. GWTTestCase auf gwt-unit-test migrieren GWT &#8230; <a href="http://www.phpmonkeys.de/2012/01/05/gwt-den-ci-build-beschleunigen/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Um ein CI-System sinnvoll zu nutzen, muss der Build möglichst schnell laufen. Dazu gehören neben dem Unittests auch der GWT Compiler und an beiden Stellen gibt es einige Optimierungsmöglichkeiten die wir heute mal betrachten werden.<br />
<more></p>
<p><em>GWTTestCase auf gwt-unit-test migrieren</em><br />
GWT bietet <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/junit/client/GWTTestCase.html" target="_blank"><code>GWTTestCase</code></a> um UnitTests zu programmieren. Der Nachteil an dieser Methode ist jedoch, dass so bei einem UnitTest extra ein TomCat Server gestartet werden muss. Dies ist relativ zeitaufwändig und kann durch die Benutzung der <a href="http://code.google.com/p/gwt-test-utils/" target="_blank">gwt-test-utils</a> verbessert werden. Die gwt-test-utils wurden bereits <a href="http://www.phpmonkeys.de/2010/09/08/gwt-unittests-mal-anders/" title="GWT-Unittests mal anders" target="_blank">vorgestellt</a>. Die Funktionsweise ist so, dass der Teil der möglichst dicht am Javascript liegt durch sogenannte Patcher überschrieben wird. Das heißt, dass für die Testdurchführung nur noch Java benutzt werden muss. Kritisch an diesem Verfahren ist, dass man so nicht dem compilierten Code testet. Man sollte aber in GWT soviel Vertrauen haben, dass der GWT-Compiler den Java Code ordnungsgemäß in JavaScript-Code transformiert. Auf der anderen Seite kann man so neben der von Google gepatchten Emma Version auch Cobertura nutzen, um die Testabdeckung zu bestimmen. Insbesondere die Auswertung im Hudson/Jenkins CI finde ich persönlich bei Cobertura übersichtlicher.</p>
<p><em>Junit-Test in einer VM ausführen &#8211; forkmode sinnvoll nutzen</em><br />
JUnit hält <a href="http://ant.apache.org/manual/Tasks/junit.html" target="_blank">3 Optionen</a> bereit wie die Erzeugung neuer VMs verwaltet wird. So kann in einem Batch, einem Test oder für den gesamten Testlauf eine neue VM erzeugt werden. Die Standard-Einstellung ist per Test, was bedeutet, dass jeder Test eine eigene VM nutzt. Diese muss als erzeugt und nach dem Test verworfen werden. Wenn man am Class-Loader keine größeren Manipulationen vornimmt, kann man aber auch mehr Test in einer VM durchführen. So spart man sich insbesondere bei vielen Test die Erzeugung und das Verwerfen von neuen VMs. Aus persönlicher Erfahrung kann ich sagen, dass dies wirklich sehr viel Zeit einsparen kann. So konnte ein Testdurchlauf nur durch diese Option von über 45 Minuten auf weniger als 5 Minuten reduziert werden. </p>
<p><em>SoftPermutations</em><br />
GWT compiliert für jede Sprache und für jeden Browser eine eigene JavaScript-Datei, sodass ein Benutzer nur den relevanten Code herunterladen muss. Lokal compilieren daher viele Entwickler eine spezialisierte Version, die nur in diesem lokalen Umfeld nutzbar sind. Zum Beispiel eine deutsche Version die für den Firefox optimiert ist. Auf dem CI-System ist dies aber zu speziell und man benötigt hier die Versionen für alle Browser. Es gibt aber die Option &#8220;<a href="http://code.google.com/p/google-web-toolkit/wiki/SoftPermutations" target="_blank">collapse-all-properties</a>&#8220;, welche für das CI-Sytem sehr gut geeigent ist. Dadurch wird statt vieler verschiedender JavaScript Dateien eine große Datei compiliert und die Optimierungen durch Factories realisiert. D.h. es wird eine spezialisierte Version benutzt, wenn dies vom Browser her erforderlich ist. So wird das Deferred Binding nun realisiert. Der Vorteil ist, dass auf diese Art die Build-Geschwindigkeit weiter verbessert wird. Von ca 30 Minuten konnten wir den GWT-Compiler so auf wenige Minuten reduzieren.</p>
<p><em>Fazit</em>:<br />
Mit diesen 3 Änderungen ist es möglich einen langlaufenden Build wieder in einen annehmbaren Zeitbereich zu überführen. In einem Projekt von ca 2,5 Stunden auf 15 Minuten.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2012/01/05/gwt-den-ci-build-beschleunigen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Frohe Weihnachten</title>
		<link>http://www.phpmonkeys.de/2011/12/24/frohe-weihnachten/</link>
		<comments>http://www.phpmonkeys.de/2011/12/24/frohe-weihnachten/#comments</comments>
		<pubDate>Sat, 24 Dec 2011 14:55:40 +0000</pubDate>
		<dc:creator>Norbert</dc:creator>
				<category><![CDATA[Allgemein]]></category>

		<guid isPermaLink="false">http://www.phpmonkeys.de/?p=1628</guid>
		<description><![CDATA[Diese Woche gab es den letzten Artikel für dieses Jahr. Im nächsten Jahr geht es dann wieder weiter und darum bleibt mir nur noch zu sagen: Ich wünsche euch allen ein Frohes Fest und ein schönes, erfolgreiches und gutes neues &#8230; <a href="http://www.phpmonkeys.de/2011/12/24/frohe-weihnachten/">Weiterlesen <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Diese Woche gab es den letzten Artikel für dieses Jahr. Im nächsten Jahr geht es dann wieder weiter und darum bleibt mir nur noch zu sagen:</p>
<blockquote><p>Ich wünsche euch allen ein Frohes Fest und ein schönes, erfolgreiches und gutes neues Jahr 2012.</p></blockquote>
<pre>

             *
            /.\
           /..'\
           /'.'\
          /.''.'\
          /.'.'.\
   "'""""/'.''.'.\""'"'"
     jgs ^^^[_]^^^
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.phpmonkeys.de/2011/12/24/frohe-weihnachten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

