<?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>oudmaijer.com &#124; &#187; Blog</title>
	<atom:link href="http://www.oudmaijer.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.oudmaijer.com</link>
	<description>Oudmaijer IT</description>
	<lastBuildDate>Tue, 10 Jan 2012 21:10:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Nexus installation on Tomcat 7 with JDK7</title>
		<link>http://www.oudmaijer.com/2011/08/30/nexus-installation-on-tomcat-7-with-jdk7/</link>
		<comments>http://www.oudmaijer.com/2011/08/30/nexus-installation-on-tomcat-7-with-jdk7/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 07:14:47 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Java SE]]></category>
		<category><![CDATA[Servers]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=1099</guid>
		<description><![CDATA[I tried to install Nexus 1.9.2.2 OSS on my Tomcat 7.0.20 with the new Oracle JDK 7. This was not a big success. Ok first of all make sure to use the unpacked version of the nexus war or else it wont be able to find the NEXUS_PLEXUS_WORK environment variable. Second, you need to patch [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/08/nexus.png" alt="" title="nexus" width="247" height="50" class="alignright size-full wp-image-1102" />I tried to install Nexus 1.9.2.2 OSS on my Tomcat 7.0.20 with the new Oracle JDK 7. This was not a big success. Ok first of all make sure to use the unpacked version of the nexus war or else it wont be able to find the NEXUS_PLEXUS_WORK environment variable. </p>
<p>Second, you need to patch the unpacked war. Strip out the xstream-1.3 and add the latest snapshot. Also add the latest xmlpull.org API jar to the WEB-INF/lib of the unpacked nexus war.</p>
<p>More info see <a href="https://issues.sonatype.org/browse/NEXUS-4437?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel">this JIRA ticket</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/08/30/nexus-installation-on-tomcat-7-with-jdk7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solving JAX-WS problems on Tomcat 7</title>
		<link>http://www.oudmaijer.com/2011/07/26/solving-noclassdeffounderror-javaxservletservletcontext-and-nosuchmethoderror-javax-xml-ws-webfault-messagename-on-tomcat-7/</link>
		<comments>http://www.oudmaijer.com/2011/07/26/solving-noclassdeffounderror-javaxservletservletcontext-and-nosuchmethoderror-javax-xml-ws-webfault-messagename-on-tomcat-7/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 08:16:53 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[jax-ws]]></category>
		<category><![CDATA[metro]]></category>
		<category><![CDATA[tomcat]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=1091</guid>
		<description><![CDATA[When running JAX-WS applications on Apache Tomcat 7 you might encounter the following exception: To solve this add the webservices-api-x.y.jar to the CATALINA_HOME/endorsed directory. Do NOT add the webservice-rt-x.y.jar to the endorsed directory or you will encounter the following exception:]]></description>
			<content:encoded><![CDATA[<p>When running JAX-WS applications on Apache Tomcat 7 you might encounter the following exception:</p>
<pre class="brush: java; title: ; notranslate">
java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String;
	at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1077)
</pre>
<p>To solve this add the webservices-api-x.y.jar to the CATALINA_HOME/endorsed directory. </p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/07/tomcat7-jaxws-300x182.png" alt="" title="tomcat7-jaxws" width="300" height="182" class="alignnone size-medium wp-image-1095" /></p>
<p>Do NOT add the webservice-rt-x.y.jar to the endorsed directory or you will encounter the following exception:</p>
<pre class="brush: java; title: ; notranslate">
java.lang.NoClassDefFoundError: javax/servlet/ServletContext
	at com.sun.xml.ws.transport.http.servlet.WSServletDelegate.&lt;init&gt;(WSServletDelegate.java:102)
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/07/26/solving-noclassdeffounderror-javaxservletservletcontext-and-nosuchmethoderror-javax-xml-ws-webfault-messagename-on-tomcat-7/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git server on Windows</title>
		<link>http://www.oudmaijer.com/2011/07/19/git-server-on-windows/</link>
		<comments>http://www.oudmaijer.com/2011/07/19/git-server-on-windows/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 08:49:25 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[dvcs]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=1063</guid>
		<description><![CDATA[DVCS Distributed version control systems gained a lot of attention over the last few years. There are many hosting providers that offer free DVCS space on the web. But there are situations that you want to run your own private DVCS server and do not want use a publicly and open DVCS like Gitorious, Github [...]]]></description>
			<content:encoded><![CDATA[<h3>DVCS</h3>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/07/git-logo.png" alt="" title="git-logo" width="150" class="alignright size-full wp-image-1078" /><a href="http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/">Distributed version control systems</a> gained a lot of attention over the last few years. There are many hosting providers that offer free DVCS space on the web. But there are situations that you want to run your own private DVCS server and do not want use a publicly and open DVCS like Gitorious, Github or BitBucket. Of-course you can always buy a <a href="http://gitorious.com/local_install">commercial offering</a> for a private DVCS solution.</p>
<p>The nice thing about a DVCS is that there is not one version, there are multiple &#8216;versions&#8217; of a source tree. But at some point you do want a central location to store your (releases) sources. In this article I will explain how to setup a Git server on a Windows machine using Apache to server Git request over HTTP.</p>
<p>If you want to know more, <a href="http://summit.atlassian.com/archives/code-and-build/dvcs-making-the-move">Atlassian has an excellent presentation on DVCS</a>, recorded at the Atlassian Summit last June. And Linus Torvalds talk on Git is worth your time: http://www.youtube.com/watch?v=4XpnKHJAok8</p>
<h3>msysgit</h3>
<p>You will need to install <a href="http://code.google.com/p/msysgit/">msysgit</a>, I used version <a href="http://code.google.com/p/msysgit/downloads/detail?name=msysGit-fullinstall-1.7.6-preview20110708.exe">msysGit-fullinstall-1.7.6-preview20110708.exe</a>. On my machine I installed msysgit  to D:/dev/msysgit</p>
<h3>Repositories</h3>
<p>Create a directory that contains your Git repositories, for example: D:/dev/repo/git. To get you started, go to the directory and create an empty Git repository. </p>
<pre class="brush: java; title: ; notranslate">
cd D:/dev/repo/git
git init --bare Test.git
</pre>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/07/git-init.png" alt="" title="git-init" width="597" height="335" class="alignnone size-full wp-image-1064" /></p>
<h3>Apache configuration</h3>
<p>In this tutorial I use Apache 2.2.19. You need to setup git-http-backend.exe in order to serve Git through Apache. First copy ..\msysgit\mingw\bin\libiconv-2.dll to ..\msysgit\libexec\git-core or else you will get a 500 error from Apache. To test if your setup works run ..\msysgit\libexec\git-core\git-http-backend.exe</p>
<p>Add the following to your Apache conf\httpd.conf:</p>
<pre class="brush: java; title: ; notranslate">
SetEnv GIT_PROJECT_ROOT D:/dev/repo/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAliasMatch \
        &quot;(?x)^/(.*/(HEAD | \
                        info/refs | \
                        objects/(info/[Apache Git server on Windows^/]+ | \
                                 [0-9a-f]{2}/[0-9a-f]{38} | \
                                 pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
                        git-(upload|receive)-pack))$&quot; \
                        &quot;D:/dev/msysgit/libexec/git-core/git-http-backend.exe/$1&quot;
</pre>
<p>I also made the Apache DocumentRoot point to my Git repos:</p>
<pre class="brush: java; title: ; notranslate">
DocumentRoot &quot;D:/dev/repo/git&quot;

&lt;Directory &quot;D:/dev/repo/git&quot;&gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
&lt;/Directory&gt;
</pre>
<p>The result:</p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/07/git-repos.png" alt="" title="git-repos" width="530" height="298" class="alignnone size-full wp-image-1065" /></p>
<h3> Using the repo</h3>
<p>You can create a local copy of this git repo using the clone command.</p>
<pre class="brush: java; title: ; notranslate">
git clone http://localhost/Test.git
</pre>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/07/git-clone.png" alt="" title="git-clone" width="597" height="307" class="alignnone size-full wp-image-1066" /></p>
<h3>Warning</h3>
<p>Make sure that you setup authentication if you do not want your sources to become publicly available. This can be done using the regular Apache authentication modules.</p>
<h3>Links</h3>
<p>Many thanks to: http://www.jeremyskinner.co.uk/2010/07/31/hosting-a-git-server-under-apache-on-windows/</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/07/19/git-server-on-windows/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Asus EEE Pad Transformer (with dock)</title>
		<link>http://www.oudmaijer.com/2011/06/09/asus-eee-pad-transformer-with-dock/</link>
		<comments>http://www.oudmaijer.com/2011/06/09/asus-eee-pad-transformer-with-dock/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 09:09:17 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Gadgets]]></category>
		<category><![CDATA[Android 3.1]]></category>
		<category><![CDATA[Asus EEE Pad]]></category>
		<category><![CDATA[Transformer]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=1030</guid>
		<description><![CDATA[Yeej! Yesterday I read on a Dutch forum that the Asus EEE Pad transformer with dock arrived in the Netherlands. So immediately I drove to Amsterdam to pick one up And my, my what a fancy device it is! The specs The tablet uses the 1GHz Nvidia Tegra 2 processor, has 1GB RAM, a Gorilla [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS-Eee-Pad-Transformer.jpg"><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS-Eee-Pad-Transformer-300x268.jpg" alt="" title="ASUS-Eee-Pad-Transformer" width="300" height="268" class="alignright size-medium wp-image-1038" /></a>Yeej! Yesterday I read on a Dutch forum that the Asus EEE Pad transformer with dock arrived in the Netherlands. So immediately I drove to Amsterdam to pick one up <img src='http://www.oudmaijer.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  And my, my what a fancy device it is! </p>
<p><strong>The specs</strong></p>
<p>The tablet uses the 1GHz Nvidia Tegra 2 processor, has 1GB RAM, a Gorilla Glass multitouch screen (10.1 inches), 1.2 and 5MP cameras, gyroscope, compass, GPS, HDMI output and so on. </p>
<p><strong>Keyboard dock</strong></p>
<p>The keyboard is little more than a dock with a trackpad and battery (without the dock, the battery life drops to 9.5 hours). With the dock Asus claims a battery life of 16 hours.</p>
<p><a href="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS-Eee-Pad-Transformer-dock.jpg"><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS-Eee-Pad-Transformer-dock-300x194.jpg" alt="" title="ASUS-Eee-Pad-Transformer-dock" width="300" height="194" class="alignnone size-medium wp-image-1039" /></a><a href="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS_EeePad_Transformer_.jpg"><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/ASUS_EeePad_Transformer_-300x203.jpg" alt="" title="ASUS EeePad Transformer" width="300" height="203" class="alignnone size-medium wp-image-1031" /></a></p>
<p>Once the dock is attached Android presents a mouse cursor. This actually works very good, especially when writing emails and doing quick navigation. </p>
<p><strong>Micro + SD</strong></p>
<p>The device itself has a MicroSD expansion slot. The keyboard dock includes a SD slot. I have not tried them yet. One of the main reasons for not buying the 32GB version was the availability of the memory expansion slot. The device will cost you 100 euro more for the 32GB version while 32GB of MicroSD memory only cost a much as 45 euro.</p>
<p><strong>System update</strong></p>
<p>After the initial setup I got a notification that a system update was available. So I installed it an rebooted the device. For some reason it gave me a black screen after the update installation so I had to reset it after the update by pressing the power button. When it started the device again I noticed that Android 3.1 was installed on it, yeah baby!</p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/android-honeycomb-3.1-300x152.png" alt="" title="android-honeycomb-3.1" width="400" class="alignnone size-medium wp-image-1044" /></p>
<p><strong>Multiple Google accounts</strong></p>
<p>What I like already is that it is very easy to setup multiple Google accounts and switch between them in application. Both my wife and I will be using the device.</p>
<p><strong>Agenda</strong></p>
<p>The build in Google Agenda is one of the features I use most often to synchronize appointments between multiple calendar. The Agenda app in Honeycomb has a fresh and clean interface that is wel usable on tablet format. </p>
<p><a href="http://www.oudmaijer.com/wp-content/uploads/2011/06/agenda-honeycomb31.jpg"><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/agenda-honeycomb31-300x180.jpg" alt="" title="agenda-honeycomb31" width="500" class="alignnone size-medium wp-image-1053" /></a></p>
<p><strong>Market</strong></p>
<p>The market app is a bit different in Honeycomb from what I am used to on my Android 2.2 phone. One flaw in the Honeycomb market is that you are not able to rate applications in the market app. </p>
<p>Not all apps are ready for Honeycomb yet. Some apps work but a lot of them need to be updated to work on the 3.x version of Android. I have sent a few crash reports to developers already <img src='http://www.oudmaijer.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>More to come</strong></p>
<p>I have been playing around with it today but it runs very smooth. I will post some impressions later this week or next week.</p>
<p>I&#8217;ll Keep you posted!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/06/09/asus-eee-pad-transformer-with-dock/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Xtreamer Ultra (first impressions)</title>
		<link>http://www.oudmaijer.com/2011/06/07/xtreamer-ultra-first-impressions/</link>
		<comments>http://www.oudmaijer.com/2011/06/07/xtreamer-ultra-first-impressions/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 06:48:56 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Gadgets]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=1007</guid>
		<description><![CDATA[29th of april I ordered an Xtreamer Ultra via the Xtreamer webshop. Customers who ordered this device before the 1st of May received a few extra`s including a remote keyboard and WIFI antenna. Last week the device finally arrived straight out of Hong Kong to my home address in the Netherlands. In this article I [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/Xtreamer-Ultra-300x234.jpg" alt="" title="Xtreamer-Ultra" width="300" height="234" class="alignright size-medium wp-image-1008" /><br />
29th of april I ordered an Xtreamer Ultra via the Xtreamer webshop. Customers who ordered this device before the 1st of May received a few extra`s including a remote keyboard and WIFI antenna.</p>
<p>Last week the device finally arrived straight out of Hong Kong to my home address in the Netherlands. In this article I will share some of my first impressions and fixes to get the device in a usable state.</p>
<p>Since I was not at home on the first delivery attempt, DHL left me a note that they would try to deliver the device the next day but the note also stated I had to pay 67 euro VAT! WTF?! This was the first surprise. The second delivery attempt was also unsuccessful (who the f*ck is at home during the day?!) so I had to pick up the device at the local DHL service point.</p>
<p>Once I finally had the device at home I unpacked it and was a bit surprised by the size. I am used to a WD TV Live which is ultra small, the Xtreamer is Ultra big when comparing it to the WD TV Live. But it does not look to bad.</p>
<p>I inserted the supplied USB stick in a free USB slot and fired up the device using the remote, but no luck. The remote was not doing that much. I seems that there is an issue with the bios of the first batch of Xtreamer Ultra devices and powering up the device using the remote. Fortunately there is already a bios fix for this, <a href="http://forum.xtreamer.net/topic/22845-new-bios-for-xtreamer-ultra-users-boot-from-rc-fix/">check the following link</a>.</p>
<p>So I powered on the device by hand and tried to select XBMC to start, but the splash is so ultra fast that it booted into the Ultra OS, which is a modified version of Ubuntu. The Ultra OS is absolutely not usable when you are using the Xtreamer Ultra as a HTPC. Resolution way to high, and fonts way to small. </p>
<p>So a did a reset and tried to boot XBMC. Thats when I noticed that the supplied keyboard was doing jack sh!t. How little did I know that the mini keyboard contains a USB stick that you have to pull out of the keyboard and put into a free USB slot. After that the keyboard works ok, but I would not recommend it. The keyboard response is not that great.</p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/2-4GHz-Mini-Wireless-Remote-Control-Keyboard-Mouse-Presenter-Combo1.jpg" alt="" title="2-4GHz-Mini-Wireless-Remote-Control-Keyboard-Mouse-Presenter-Combo1" width="250" height="250" class="size-full wp-image-1016" /><img src="http://www.oudmaijer.com/wp-content/uploads/2011/06/2-4GHz-Mini-Wireless-Remote-Control-Keyboard-Mouse-Presenter-Combo2.jpg" alt="" title="2-4GHz-Mini-Wireless-Remote-Control-Keyboard-Mouse-Presenter-Combo2" width="250" height="250" class="size-full wp-image-1017" /></p>
<p>Ok, now I had the keyboard working I selected XBMC to boot but nothing happened. Reboot&#8230; select Boxeee&#8230; nothing happened. WTF?!!!!!!!! At this point I was really pissed off&#8230; what a crappy device this is?!!!!! So I started Googling and I found I was not the only one with problems. </p>
<p>I stumbled upon <a href="http://forum.xtreamer.net/topic/22430-openelec/">an OpenELEC version of XBMC for the Xtreamer Ultra</a> (<a href="http://dl.dropbox.com/u/8224157/OpenELEC-Ultra/versions.html">latest versions can be found here</a>). Right now I am using <a href="http://dl.dropbox.com/u/8224157/OpenELEC-Ultra/OpenELEC-ION.x86_64-devel-20110608-r7188-Ultra.tar">this version (updated to r7188)</a>. OpenELEC is an embedded Linux version for XBMC. You can install it on your USB stick. With this installer you can create a OpenELEC installation. So basically you need 2 USB sticks or one USB stick (with the installer) and a HDD. <a href="http://www.openelec.tv/find-help/documentation/installation">I created an USB stick</a> and fired up the device. Finally some results, XBMC booted ok and I got to play a bit with XBMC on the Xtreamer Ultra, yeah!</p>
<p>First I needed to adjust the <a href="http://wiki.xbmc.org/index.php?title=Video_Calibration">overscan compensation</a> through the Video calibration screen. Once this was correct and I could view the entire image I was ready to watch a movie. But my enthusiasm was not for long, when I started the first movie I had no audio&#8230; I used the Optical audio cable that I had been using for years on my WD TV Live. But no luck. I tried different settings and after two days I gave up. I was ready to send back the device. As a last option I tried a different Optical cable and&#8230;. there was sound!!!!!!!! My XBMC <a href="http://imageshack.us/photo/my-images/836/screenshot028.png/">Audio Output</a> settings:</p>
<ul>
<li>Audio Output: Optical / Coax</li>
<li>Speaker Configuration: 5.1</li>
<li>Boost volume level on downmix: off</li>
<li>Dolby Digital (AC3) capable receiver: on</li>
<li>DTS capable receiver: on</li>
<li>Audio output device: HDA Intel iec958</li>
<li>Passthrough output device: HDA Intel iec958</li>
</ul>
<p>Happy as a child I fired up a movie (The Hit List) and started watching&#8230;.I immediately noticed that there was something wrong with the video&#8230; there was a vertical sync issue with the video, btw: I did not know this existed until I started Googling. Apparently you can enabled vertical sync to be always on in XBMC, this solved the issue for me. You can enable this via System Settings > Video Output and select Vertical blank sync to Always enabled.</p>
<p>This left me to the only remaining piece, the remote that was not working. On a forum I found that after the bios update, removing the batteries from the remote for a minute and putting it back in made the remote working again&#8230; pffff.</p>
<p>So&#8230; now one week after I received my device I finally have it up and running. It caused me a lot of headaches already but it is working now. My short conclusion is that this device is capable of being a HTPC but it is not for mainstream users. It has way too much flaws that only geek (am I one?) can solve.</p>
<p>A few links to other resources:</p>
<ul>
<li><a href="http://forum.xtreamer.net/forum/507-xtreamer-ultra/">http://forum.xtreamer.net/forum/507-xtreamer-ultra/</a></li>
<li><a href="http://openelec.tv">http://openelec.tv</a></li>
<li><a href="http://wiki.xbmc.org/?title=XBMC_Online_Manual">http://wiki.xbmc.org/?title=XBMC_Online_Manual</a></li>
<li><a href="http://www.mini-itx.com/projects/xbmc-ion/">http://www.mini-itx.com/projects/xbmc-ion/</a></li>
<li><a href="http://gathering.tweakers.net/forum/list_messages/1447305">http://gathering.tweakers.net/forum/list_messages/1447305</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/06/07/xtreamer-ultra-first-impressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SABnzbd Windows Service installer script</title>
		<link>http://www.oudmaijer.com/2011/04/04/sabnzbd-windows-service-installer-script/</link>
		<comments>http://www.oudmaijer.com/2011/04/04/sabnzbd-windows-service-installer-script/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 06:58:25 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[sabnzbd]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=994</guid>
		<description><![CDATA[I really like the new SABnzbd 0.6 version, works like a charm. Since they are actively updating it I was doing the service install step manually each time after updating my SABnzbd installation. But more than once I forgot how to register the service and especially that the -f argument needs a path and not [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/04/sabnzbd-logo.png" alt="" title="sabnzbd-logo" width="157" height="45" class="alignright size-full wp-image-998" />I really like the new SABnzbd 0.6 version, works like a charm. Since they are actively updating it I was doing the service install step manually each time after updating my SABnzbd installation. But more than once I forgot how to register the service and especially that the -f argument needs a path and not a exe file as an argument. Thats why I created a script that does this for me.  Want to use the script, create a file called service-installer.cmd, and put the following content in it:</p>
<pre class="brush: plain; title: ; notranslate">
@echo off
%~d0
cd %~dp0 

net stop SABHelper
net stop SABnzbnd 

SABnzbd-helper.exe remove
SABnzbd-service.exe remove 

SABnzbd-service.exe -f %~dp0 install
SABnzbd-helper.exe install 

net start SABnzbd
pause
</pre>
<p>Now run the script, thats all!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/04/04/sabnzbd-windows-service-installer-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving toward standard APIs</title>
		<link>http://www.oudmaijer.com/2011/03/11/moving-towards-standards/</link>
		<comments>http://www.oudmaijer.com/2011/03/11/moving-towards-standards/#comments</comments>
		<pubDate>Fri, 11 Mar 2011 12:56:33 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=983</guid>
		<description><![CDATA[For my current client I am involved in the process of creating a list with allowed, deprecated and blacklisted frameworks and dependencies. I`ve noticed that there are a lot of internal projects that copy dependencies and framework choices from previous projects and are therefore using old and deprecated libraries. We are trying very hard to [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/03/blacklist-150x150.jpg" alt="" title="blacklist" width="150" height="150" class="alignright size-thumbnail wp-image-986" />For my current client I am involved in the process of creating a list with allowed, deprecated and blacklisted frameworks and dependencies. I`ve noticed that there are a lot of internal projects that copy dependencies and framework choices from previous projects and are therefore using old and deprecated libraries. We are trying very hard to get projects to use standard APIs and get rid of the old stuff.</p>
<p>Frameworks like Spring, Google Guice, Seam, etc, are also moving toward standard APIs. Spring 3.0 embraces a lot of standards APIs like <a href="http://jcp.org/en/jsr/detail?id=303">JSR303</a>, <a href="http://jcp.org/en/jsr/detail?id=330">JSR330</a>, <a href="http://jcp.org/en/jsr/detail?id=317">JSR317</a>, which in my opinion is a good thing!</p>
<p><strong>Why move to these new APIs?</strong></p>
<p>It allows developers to focus on one API instead of learning a specific API for each framework. Switch or to other/competing frameworks or upgrading becomes easier. For example, the gap between Spring 3 and Java EE 6 (CDI + EJB3) has become much smaller due to these new standards. A good example were standardisation helps is the JSR 303 Bean Validation API which is supported by both Spring, Hibernate/JPA, JSF, etc.</p>
<p><strong>Springmodules validation</strong></p>
<p>In Spring 3 the JSR 303 Beans Validation API support was introduced which effectively replaces the springmodules validation project. Users of Spring 3 are encouraged to use this new JSR 303 Beans Validation API.</p>
<p><strong>More information</strong></p>
<p>When you want to leverage the standard API in your project, please have a look at the following articles:</p>
<p><a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation">http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation</a><br />
<a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#validation-beanvalidation">http://www.openscope.net/2010/02/08/spring-mvc-3-0-and-jsr-303-aka-javax-validation/</a></p>
<p><strong>Spring Dependency Injection annotations</strong></p>
<p>Spring and Google have been working on a standardisation for Dependency Injection annotations, result: the JSR 330 specification. This is a standard API for doing annotation based dependency injection. Spring supports this API since Spring 3.0 (<a href="http://blog.springsource.com/2009/09/29/spring-framework-3-0-rc1-released/">http://blog.springsource.com/2009/09/29/spring-framework-3-0-rc1-released/</a>).</p>
<p><strong>More information</strong></p>
<p>Have a look at the following articles:</p>
<p><a href="http://code.google.com/p/atinject/">http://code.google.com/p/atinject/</a><br />
<a href="http://ralf.schaeftlein.de/2009/11/19/spring-3-0-rc-2-and-jsr-330-dependency-injection-for-java/">http://ralf.schaeftlein.de/2009/11/19/spring-3-0-rc-2-and-jsr-330-dependency-injection-for-java/</a></p>
<p><strong>Hibernate vs Java Persistence API</strong></p>
<p>The Java Persistence API (JPA) was introduced as part of the Java EE 5 and EJB 3 specification. JPA is in a way the formalisation of Hibernate in a Java Specification (JSR). Since the makers of Hibernate were actively involved in this specification there are numberous of simularities between Hibernate and JPA. </p>
<p><strong>Differences between Hibernate and JPA</strong></p>
<p>JPA defines the standard API for using persistence in Java. You can use Hibernate as a JPA implementation. When using JPA developers can leverage the power of a standardised persistence API and still being able to use Hibernate specific functionality if required. But it opens up possibilities to move to EclipseLink or some other JPA implementation. </p>
<p><strong>Hibernate 3.5 &#8211; JPA 2.0</strong></p>
<p>In Hibernate 3.5 a lot of Hibernate subprojects have been merged back into the Hibernate core. This makes it easier to configure and use JPA in conjunction with Hibernate. The JSR 303 API was not officially included as a requirement for JPA 2.0 but Hibernate integrates nicely with the validation specification. </p>
<p><strong>Conclusion</strong></p>
<p>There are a lot of examples that demonstrate the benefits of using standard JSR APIs whenever possible. I would advice to use standard APIs whenever possible and only use specific framework functionality when the standards do not provide enough functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/03/11/moving-towards-standards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring RestTemplate and Gzip compression (continued)</title>
		<link>http://www.oudmaijer.com/2011/02/23/spring-resttemplate-and-gzip-compression-continued/</link>
		<comments>http://www.oudmaijer.com/2011/02/23/spring-resttemplate-and-gzip-compression-continued/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 19:08:32 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=945</guid>
		<description><![CDATA[Last month I blogged about the lacking gzip support in the Spring Android RestTemplate. Some collegues at my current client were struggeling invoking gzip encoded RESTful services using Spring 3.0 Web MVCs RestTemplate. While searching the web they found my blog post about Spring RestTemplate and the gzip troubles and decided to ask me for [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I <a href="http://www.oudmaijer.com/2011/01/28/gzip-compression-for-spring-android/">blogged about</a> the lacking gzip support in the Spring Android RestTemplate. Some collegues at my current client were struggeling invoking gzip encoded RESTful services using Spring 3.0 Web MVCs RestTemplate. While searching the web they found my blog post about Spring RestTemplate and the gzip troubles and decided to ask me for some help <img src='http://www.oudmaijer.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  In this article I will explain how to unmarshall a gzip encoded response from RESTful service that uses XML messages. </p>
<p><strong>gzip encoded content</strong></p>
<p>When invoking RESTful services from a client you typically specify in the client request, using HTTP request headers, what the Accept type is (JSON or XML) and content encoding you support as a client. The RESTful service inspects the HTTP request headers and returns the requested content (if supported). This proces is called content negotiation. Have a look at a sample request below:</p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/02/request.png" alt="" title="request" width="374" height="277" class="size-full wp-image-953" style="clear:both"/></p>
<p>Not all services support different types of content encoding and/or return types. Sometimes you find yourself in a situation that you have to invoke services that return specific content types or encoding formats, for example compressed content using gzip compression.</p>
<p>In the HTTP Accept-Encoding header you specify the content encoding you are supporting. When invoking services that use gzip encoding you need to specify the <code>Accept-Encoding: gzip,deflate</code> in the request headers. Spring RestTemplate using commons-httpclient does not add this by default and disallows you to invoke services that requires a client supporting gzip encoding, this typically results in a HTTP 400 Bad Request. In this blog I <a href="http://www.oudmaijer.com/2011/01/28/gzip-compression-for-spring-android/">described</a> an option to solve this problem in the RestTemplate, but thats only part of the solution. </p>
<p>Guess what happens when you invoke a RESTful service using Spring Web MVCs RestTemplate and the content body contains gzip encoded content? You are out of luck&#8230; or not? Read on&#8230; <img src='http://www.oudmaijer.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>Gzip Enabled MarshallingHttpMessageConverter</strong></p>
<p>The RESTful service my collegues were invoking returns XML data in the response body. So the return value of the RESTful service is an XML message, this message will be unmarshalled using an XML unmarshaller like JAXB. The way to do this using Spring Web MVCs RestTemplate is by adding a MessageConvertor called MarshallingHttpMessageConverter to your RestTemplate and you are good to go. </p>
<p>The MarshallingHttpMessageConverter takes care of marshalling and unmarshalling messages passing between the client and RESTful service. But if your service returns gzip encoded content this is not enough. Because the text/xml content of the response body is gzip encoded we first need to deflate the content before JAXB2 is able to unmarshall the content. The response below contains response content that is gzip encoded. The tool I used, SoapUI, already deflated the content for me, but when invoking with the RestTemplate you have to do this yourself:</p>
<p><img src="http://www.oudmaijer.com/wp-content/uploads/2011/02/response.png" alt="" title="response" width="292" height="277" class="size-full wp-image-954"  style="clear:both"/></p>
<p>I created a GzipEnabledMarshallingHttpMessageConverter that supports both gzip and non-gzip encoded content. This message convert only works for XML messages that need to be (un)marshalled. For JSON services you need to implement a different solution. In the MessageConverter I perform a check to see if the <code>Content-Encoding</code> actually is gzip encoded, if so, I use a GZipStreamSource to read the Gzip compressed content from the InputStream of the response body.</p>
<p>The implementation below is a combination of the Spring MarshallingHttpMessageConverter and the AbstractXmlMessageConverter. I had to extend the AbstractHttpMessageConverter because the StreamSource is created within this class.</p>
<pre class="brush: java; title: ; notranslate">

package com.oudmaijer.rest.spring.xml.message.converter;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.Unmarshaller;
import org.springframework.oxm.UnmarshallingFailureException;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.util.Assert;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.util.List;
import java.util.zip.GZIPInputStream;

/**
 * Add gzip decompression support for HttpResponse body's that are encoded with gzip.
 * &lt;p/&gt;
 * Implements the AbstractHttpMessageConverter in the same way as
 * the Spring AbstractXmlMessageConverter and adds the MarshallingHttpMessageConverter
 * functionality to it.
 *
 * @param &lt;T&gt;
 */
public class GzipEnabledMarshallingHttpMessageConverter&lt;T&gt; extends AbstractHttpMessageConverter&lt;T&gt; {

    private final TransformerFactory transformerFactory = TransformerFactory.newInstance();
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;

    /**
     * Protected constructor that sets the {@link #setSupportedMediaTypes(java.util.List) supportedMediaTypes}
     * to {@code text/xml} and {@code application/xml}, and {@code application/*-xml}.
     */
    public GzipEnabledMarshallingHttpMessageConverter(Jaxb2Marshaller marshaller, Jaxb2Marshaller unmarshaller) {
        super(new MediaType(&quot;application&quot;, &quot;xml&quot;), new MediaType(&quot;text&quot;, &quot;xml&quot;), new MediaType(&quot;application&quot;, &quot;*+xml&quot;));
        Assert.notNull(marshaller, &quot;marshaller must not be null&quot;);
        Assert.notNull(unmarshaller, &quot;unmarshaller must not be null&quot;);
        this.marshaller = marshaller;
        this.unmarshaller = unmarshaller;
    }

    @Override
    public final T readInternal(Class&lt;? extends T&gt; clazz, HttpInputMessage inputMessage) throws IOException {

        StreamSource streamSource = null;
        boolean gzip = false;
        HttpHeaders headers = inputMessage.getHeaders();
        List&lt;String&gt; contentEncoding = headers.get(&quot;Content-Encoding&quot;);

        if( headers != null &amp;&amp; contentEncoding != null ) {
            for(String contentEncodingString : contentEncoding) {
                if( contentEncodingString != null &amp;&amp; &quot;gzip&quot;.equalsIgnoreCase(contentEncodingString.trim()) ) {
                    gzip = true;
                }
            }
        }

        if( gzip ) {
            streamSource = new GZipStreamSource(inputMessage.getBody());
        } else {
            streamSource = new StreamSource(inputMessage.getBody());
        }

        return (T) readFromSource(clazz, inputMessage.getHeaders(), streamSource);
    }

    @Override
    protected final void writeInternal(T t, HttpOutputMessage outputMessage) throws IOException {
        writeToResult(t, outputMessage.getHeaders(), new StreamResult(outputMessage.getBody()));
    }

    /**
     * Set the {@link Marshaller} to be used by this message converter.
     */
    public void setMarshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }

    /**
     * Set the {@link Unmarshaller} to be used by this message converter.
     */
    public void setUnmarshaller(Unmarshaller unmarshaller) {
        this.unmarshaller = unmarshaller;
    }

    @Override
    public boolean supports(Class&lt;?&gt; clazz) {
        return this.unmarshaller.supports(clazz);
    }

    /**
     *
     * @param clazz
     * @param headers
     * @param source
     * @return
     * @throws IOException
     */
    protected Object readFromSource(Class&lt;?&gt; clazz, HttpHeaders headers, Source source) throws IOException {
        Assert.notNull(this.unmarshaller, &quot;Property 'unmarshaller' is required&quot;);
        try {
            return this.unmarshaller.unmarshal(source);
        } catch (UnmarshallingFailureException ex) {
            throw new HttpMessageNotReadableException(&quot;Could not read [&quot; + clazz + &quot;]&quot;, ex);
        }
    }

    /**
     *
     * @param o
     * @param headers
     * @param result
     * @throws IOException
     */
    protected void writeToResult(Object o, HttpHeaders headers, Result result) throws IOException {
        Assert.notNull(this.marshaller, &quot;Property 'marshaller' is required&quot;);
        try {
            this.marshaller.marshal(o, result);
        } catch (MarshallingFailureException ex) {
            throw new HttpMessageNotWritableException(&quot;Could not write [&quot; + o + &quot;]&quot;, ex);
        }
    }
}
</pre>
<p>The <code>GZipStreamSource</code> comes from an XML library created by Kohsuke Kawaguchi. I made some minor modifications to the code but the credits for this code goes to Kohsuke.</p>
<pre class="brush: java; title: ; notranslate">
package com.oudmaijer.rest.spring.xml.message.converter;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.zip.GZIPInputStream;

import javax.xml.transform.stream.StreamSource;

/**
 * {@link StreamSource} that reads from gzip-compressed XML stream.
 * &lt;p/&gt;
 * THIS SOFTWARE IS IN PUBLIC DOMAIN. NO WARRANTY.
 *
 * @author Kohsuke Kawaguchi (kk@kohsuke.org)
 */
public class GZipStreamSource extends StreamSource {

    /**
     * Creates a {@link StreamSource} from a gzip-compressed XML file.
     */
    public GZipStreamSource(File file) throws IOException {
        this(new FileInputStream(file), file.toURI().toURL().toExternalForm());
    }

    /**
     * Creates a {@link StreamSource} from a gzip-compressed stream.
     */
    public GZipStreamSource(InputStream stream) throws IOException {
        super(new GZIPInputStream(stream));
    }

    /**
     * Creates a {@link StreamSource} from a gzip-compressed stream.
     * &lt;p/&gt;
     * &lt;p&gt;This constructor allows the systemID to be set in addition
     * to the input stream, which allows relative URIs
     * to be processed.&lt;/p&gt;
     */
    public GZipStreamSource(InputStream stream, String systemId) throws IOException {
        super(new GZIPInputStream(stream), systemId);
    }

    /**
     * Creates a {@link StreamSource} from a gzip-compressed stream.
     *
     * @param url
     * @throws IOException
     */
    public GZipStreamSource(String url) throws IOException {
        this(new URL(url).openStream(), url);
    }
}
</pre>
<p><strong>Spring configuration</strong></p>
<p>And finally you have to configure your RestTemplate to use the new MessageConverter.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;bean id=&quot;httpClientFactory&quot; class=&quot;org.springframework.http.client.CommonsClientHttpRequestFactory&quot;&gt;
  &lt;constructor-arg ref=&quot;httpClient&quot;/&gt;
&lt;/bean&gt;
&lt;bean id=&quot;restTemplate&quot; class=&quot;org.springframework.web.client.RestTemplate&quot;&gt;
  &lt;constructor-arg ref=&quot;httpClientFactory&quot;/&gt;
  &lt;property name=&quot;messageConverters&quot;&gt;
    &lt;list&gt;
    &lt;bean class=&quot;com.oudmaijer...GzipEnabledMarshallingHttpMessageConverter&quot;&gt;
      &lt;constructor-arg ref=&quot;jaxbMarshaller&quot;/&gt;
      &lt;constructor-arg ref=&quot;jaxbMarshaller&quot;/&gt;
    &lt;/bean&gt;
    ...
    &lt;/list&gt;
   &lt;/property&gt;
&lt;/bean&gt;
</pre>
<p><strong>Conclusion</strong></p>
<p>Using this MessageConverter you can invoke RESTful services that return gzip encoded content. Lets hope Spring adds it to the default message converters in the future because gzip compressed content is an elegant solution when you need to return large messages from a RESTful service.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/02/23/spring-resttemplate-and-gzip-compression-continued/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring 3.1, whats new and whats coming?</title>
		<link>http://www.oudmaijer.com/2011/02/01/spring-3-1-whats-new-and-whats-coming/</link>
		<comments>http://www.oudmaijer.com/2011/02/01/spring-3-1-whats-new-and-whats-coming/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 08:19:28 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[English]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=942</guid>
		<description><![CDATA[Hightlights of Spring 3.1 Conversation management Environment based profiles (ala ruby/grails) Configuration enhancements See the presentation by Juergen Hoeller http://www.infoq.com/presentations/Spring-3.0-3.1-3.2 More on configuration enhancements in Spring 3.1 http://www.infoq.com/presentations/Configuration-in-Spring-3-1]]></description>
			<content:encoded><![CDATA[<p><strong>Hightlights of Spring 3.1</strong></p>
<ul>
<li>Conversation management</li>
<li>Environment based profiles (ala ruby/grails)</li>
<li>Configuration enhancements</li>
</ul>
<p><strong>See the presentation by Juergen Hoeller</strong></p>
<p><a href="http://www.infoq.com/presentations/Spring-3.0-3.1-3.2">http://www.infoq.com/presentations/Spring-3.0-3.1-3.2</a></p>
<p><strong>More on configuration enhancements in Spring 3.1</strong></p>
<p><a href="http://www.infoq.com/presentations/Configuration-in-Spring-3-1">http://www.infoq.com/presentations/Configuration-in-Spring-3-1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/02/01/spring-3-1-whats-new-and-whats-coming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gzip compression for spring-android RestTemplate</title>
		<link>http://www.oudmaijer.com/2011/01/28/gzip-compression-for-spring-android/</link>
		<comments>http://www.oudmaijer.com/2011/01/28/gzip-compression-for-spring-android/#comments</comments>
		<pubDate>Fri, 28 Jan 2011 11:58:02 +0000</pubDate>
		<dc:creator>soudmaijer</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.oudmaijer.com/?p=930</guid>
		<description><![CDATA[The org.springframework.web.client.RestTemplate lacks support for gzip encoding. The RestTemplate is a class that is provided by the spring-android module for calling RESTfull services. The Accept-Encoding header for gzip is not being added to the request by spring-android. I have added support for gzip to the RestTemplate and I created a patch for it. See the [...]]]></description>
			<content:encoded><![CDATA[<p>The org.springframework.web.client.RestTemplate <a href="https://jira.springframework.org/browse/SPR-7874">lacks support for gzip encoding</a>. The RestTemplate is a class that is provided by the spring-android module for calling RESTfull services. </p>
<p>The Accept-Encoding header for gzip is not being added to the request by spring-android. I have added support for gzip to the RestTemplate and I created a patch for it. See the extended RestTemplate below:</p>
<pre class="brush: java; title: ; notranslate">
package com.oudmaijer.android.rest;

import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
import org.springframework.web.client.*;

import java.io.IOException;
import java.net.URI;

/**
 * Adds support for gzip encoding to the Spring RestTemplate
 */
public class GzipRestTemplate extends RestTemplate {

    /**
     * {@inheritDoc}
     */
    @Override
    protected &lt;T&gt; T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor&lt;T&gt; responseExtractor) throws RestClientException {
        Assert.notNull(url, &quot;'url' must not be null&quot;);
        Assert.notNull(method, &quot;'method' must not be null&quot;);
        ClientHttpResponse response = null;
        try {
            ClientHttpRequest request = createRequest(url, method);
            if( request.getHeaders() != null ) {
                request.getHeaders().add(&quot;Accept-Encoding&quot;, &quot;gzip,deflate&quot;);
            }

            if (requestCallback != null) {
                requestCallback.doWithRequest(request);
            }
            response = request.execute();

            if (!getErrorHandler().hasError(response)) {
                logResponseStatus(method, url, response);
            } else {
                handleResponseError(method, url, response);
            }
            if (responseExtractor != null) {
                return responseExtractor.extractData(response);
            } else {
                return null;
            }
        } catch (IOException ex) {
            throw new ResourceAccessException(&quot;I/O error: &quot; + ex.getMessage(), ex);
        } finally {
            if (response != null) {
                response.close();
            }
        }
    }

    private void handleResponseError(HttpMethod method, URI url, ClientHttpResponse response) throws IOException {
        if (logger.isWarnEnabled()) {
            try {
                logger.warn(
                        method.name() + &quot; request for \&quot;&quot; + url + &quot;\&quot; resulted in &quot; + response.getStatusCode() + &quot; (&quot; +
                                response.getStatusText() + &quot;); invoking error handler&quot;);
            } catch (IOException e) {
                // ignore
            }
        }
        getErrorHandler().handleError(response);
    }

    private void logResponseStatus(HttpMethod method, URI url, ClientHttpResponse response) {
        if (logger.isDebugEnabled()) {
            try {
                logger.debug(
                        method.name() + &quot; request for \&quot;&quot; + url + &quot;\&quot; resulted in &quot; + response.getStatusCode() + &quot; (&quot; +
                                response.getStatusText() + &quot;)&quot;);
            } catch (IOException e) {
                // ignore
            }
        }
    }

}
</pre>
<p>The least unobtrusive way to change the RestTemplate is not to change it. I decided to override the doExecute method because I want the RestTemplate functionality as it is right now. I also had to included the private functions being called by the RestTemplate. I could have used the exchange() function in the RestTemplate but this is to abstract IMO. </p>
<p><strong>How to use</strong></p>
<p>Instead of instantiating the Spring RestTemplate you can now use the GzipRestTemplate. And example of using the RestTemplate for reading JSON responses:</p>
<pre class="brush: java; title: ; notranslate">
...
RestTemplate restTemplate = new GzipRestTemplate();
restTemplate.setRequestFactory(new SimpleClientHttpRequestFactory());

List&lt;HttpMessageConverter&lt;?&gt;&gt; mc = restTemplate.getMessageConverters();
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();

List&lt;MediaType&gt; supportedMediaTypes = new ArrayList&lt;MediaType&gt;();
supportedMediaTypes.add(new MediaType(&quot;text&quot;, &quot;html&quot;));
supportedMediaTypes.add(new MediaType(&quot;application&quot;, &quot;json&quot;));
json.setSupportedMediaTypes(supportedMediaTypes);
mc.add(json);
restTemplate.setMessageConverters(mc);

JsonResult jsonResult = restTemplate.getForObject(url, JsonResult.class);
...
</pre>
<p>And a pom.xml of an application that uses the RestTemplate:</p>
<pre class="brush: xml; title: ; notranslate">
...
&lt;build&gt;
	&lt;sourceDirectory&gt;src&lt;/sourceDirectory&gt;
	&lt;finalName&gt;${project.artifactId}&lt;/finalName&gt;
	&lt;plugins&gt;
		&lt;plugin&gt;
			&lt;groupId&gt;com.jayway.maven.plugins.android.generation2&lt;/groupId&gt;
			&lt;artifactId&gt;maven-android-plugin&lt;/artifactId&gt;
			&lt;version&gt;2.8.3&lt;/version&gt;
			&lt;configuration&gt;
				&lt;sdk&gt;
					&lt;path&gt;/path/to/android-sdk-windows&lt;/path&gt;
					&lt;platform&gt;8&lt;/platform&gt;
				&lt;/sdk&gt;
				&lt;emulator&gt;
					&lt;avd&gt;my_avd&lt;/avd&gt;
				&lt;/emulator&gt;
				&lt;deleteConflictingFiles&gt;true&lt;/deleteConflictingFiles&gt;
				&lt;undeployBeforeDeploy&gt;true&lt;/undeployBeforeDeploy&gt;
			&lt;/configuration&gt;
			&lt;extensions&gt;true&lt;/extensions&gt;
		&lt;/plugin&gt;
		&lt;plugin&gt;
			&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
			&lt;version&gt;2.3.2&lt;/version&gt;
		&lt;/plugin&gt;
	&lt;/plugins&gt;
&lt;/build&gt;
&lt;dependencies&gt;
        ...
	&lt;dependency&gt;
		&lt;groupId&gt;com.google.android&lt;/groupId&gt;
		&lt;artifactId&gt;android&lt;/artifactId&gt;
		&lt;version&gt;2.2.1&lt;/version&gt;
		&lt;scope&gt;provided&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.android&lt;/groupId&gt;
		&lt;artifactId&gt;spring-android-rest-template&lt;/artifactId&gt;
		&lt;version&gt;1.0.0.BUILD-SNAPSHOT&lt;/version&gt;
		&lt;scope&gt;compile&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;commons-httpclient&lt;/groupId&gt;
		&lt;artifactId&gt;commons-httpclient&lt;/artifactId&gt;
		&lt;version&gt;3.1&lt;/version&gt;
		&lt;scope&gt;compile&lt;/scope&gt;
	&lt;/dependency&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;org.codehaus.jackson&lt;/groupId&gt;
		&lt;artifactId&gt;jackson-mapper-asl&lt;/artifactId&gt;
		&lt;version&gt;1.6.2&lt;/version&gt;
		&lt;scope&gt;compile&lt;/scope&gt;
	&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;repositories&gt;
	&lt;!-- For testing against latest Spring snapshots --&gt;
	&lt;repository&gt;
		&lt;id&gt;org.springframework.maven.snapshot&lt;/id&gt;
		&lt;name&gt;Spring Maven Snapshot Repository&lt;/name&gt;
		&lt;url&gt;http://maven.springframework.org/snapshot&lt;/url&gt;
		&lt;releases&gt;&lt;enabled&gt;false&lt;/enabled&gt;&lt;/releases&gt;
		&lt;snapshots&gt;&lt;enabled&gt;true&lt;/enabled&gt;&lt;/snapshots&gt;
	&lt;/repository&gt;
	&lt;!-- For developing against latest Spring milestones --&gt;
	&lt;repository&gt;
		&lt;id&gt;org.springframework.maven.milestone&lt;/id&gt;
		&lt;name&gt;Spring Maven Milestone Repository&lt;/name&gt;
		&lt;url&gt;http://maven.springframework.org/milestone&lt;/url&gt;
		&lt;snapshots&gt;&lt;enabled&gt;false&lt;/enabled&gt;&lt;/snapshots&gt;
	&lt;/repository&gt;
&lt;/repositories&gt;
...
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.oudmaijer.com/2011/01/28/gzip-compression-for-spring-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

