<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Brain Flush &#187; java</title>
	<atom:link href="http://brainflush.wordpress.com/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://brainflush.wordpress.com</link>
	<description>Tech And Talk - by Matthias Käppler</description>
	<lastBuildDate>Thu, 17 Dec 2009 14:00:04 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='brainflush.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/03ad76652f8d50d37d498c1a417f6b53?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Brain Flush &#187; java</title>
		<link>http://brainflush.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://brainflush.wordpress.com/osd.xml" title="Brain Flush" />
		<item>
		<title>Better OAuth for Java: Signpost 1.1 comes in flavors!</title>
		<link>http://brainflush.wordpress.com/2009/06/14/better-oauth-for-java-signpost-1-1-comes-in-flavors/</link>
		<comments>http://brainflush.wordpress.com/2009/06/14/better-oauth-for-java-signpost-1-1-comes-in-flavors/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 17:06:59 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[signpost]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=88</guid>
		<description><![CDATA[Signpost, my client-side OAuth library for Java, now comes modularized, so that you can use it with other HTTP libraries than Apache HTTP Components.
By default, Signpost now only supports signing java.net.HttpURLConnection type requests, which makes the core module completely independent of any specific HTTP messaging layer. Instead, additional HTTP libraries are supported via add-on JARs; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=88&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://code.google.com/p/oauth-signpost/">Signpost</a>, my client-side OAuth library for Java, now comes modularized, so that you can use it with other HTTP libraries than Apache HTTP Components.</p>
<p>By default, Signpost now only supports signing java.net.HttpURLConnection type requests, which makes the core module completely independent of any specific HTTP messaging layer. Instead, additional HTTP libraries are supported via add-on JARs; adapters have been created for Jetty HTTP 6 and Apache HTTP Components 4.</p>
<p>More info on the project website: http://code.google.com/p/oauth-signpost</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/88/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/88/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/88/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=88&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2009/06/14/better-oauth-for-java-signpost-1-1-comes-in-flavors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
		<item>
		<title>The Force Unleashed: XML+XPath on Android using dom4j and Jaxen</title>
		<link>http://brainflush.wordpress.com/2009/05/19/the-force-unleashed-xmlxpath-on-android-using-dom4j-and-jaxen/</link>
		<comments>http://brainflush.wordpress.com/2009/05/19/the-force-unleashed-xmlxpath-on-android-using-dom4j-and-jaxen/#comments</comments>
		<pubDate>Tue, 19 May 2009 12:15:21 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Linux & Open Source]]></category>
		<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xpath]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=83</guid>
		<description><![CDATA[*UPDATE* The source code is now on GitHub. Feel free to fork &#8216;n fix.
*UPDATE* I have put up the fixed dom4j JAR for download. The Jaxen JAR in that archive I didn&#8217;t touch, it&#8217;s the same you would download from their website.
I have been very disappointed with Android&#8217;s XML parsing support from day one, it&#8217;s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=83&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>*UPDATE</strong>* The <a href="http://github.com/kaeppler/dom4j-1.6.1-harmony">source code is now on GitHub</a>. Feel free to fork &#8216;n fix.</p>
<p><strong>*UPDATE</strong>* I have put up the <a href="http://infodump.de/dom4j+jaxen-android.zip">fixed dom4j JAR for download</a>. The Jaxen JAR in that archive I didn&#8217;t touch, it&#8217;s the same you would download from their website.</p>
<p>I have been very disappointed with Android&#8217;s XML parsing support from day one, it&#8217;s simply too low level, inconvenient to use, and is lacking important features (I was especially disappointed with the decision to exclude the JAXP XPath support from Android, which has become an integral part of the JSE).</p>
<p>This is not only about cosmetics. Parsing XML documents of only medium complexity already turned out to be error prone and very tedious on Android (white space normalization problems, broken Unicode entity ref expansion, etc.) and we would&#8217;ve had to rewrite stuff which existing Java XML libraries already do in a graceful and stable manner.</p>
<p>Since I have always been a big fan of <a href="http://www.dom4j.org/">dom4j</a>, I fixed an issue with the latest source tree that prevented dom4j&#8217;s QNAME caching to work with Android&#8217;s Java implementation (or more precisely, with Apache Harmony&#8217;s SAX implementation &#8212; the Android Java implementation is based on a pre-release version of <a href="http://harmony.apache.org/">Apache Harmony</a>).</p>
<p>I haven&#8217;t committed that change back to dom4j yet, because development seems to have stalled on that project, but if anyone is interested, I can host the source code and a working JAR somewhere (please drop a short line in the comments section, otherwise I won&#8217;t bother sharing it).</p>
<p>dom4j also works very well in conjunction with <a href="http://jaxen.codehaus.org/">Jaxen</a> (a free XPath implementation)!</p>
<p>Some example code to wet your mouth:</p>
<pre class="brush: java;">
SAXReader reader = new SAXReader(); // dom4j SAXReader
Document document = reader.read(xmlInputStream); // dom4j Document

// select all link nodes with href &quot;http://example.com&quot;
List&lt;Element&gt; linkNodes = document.selectNodes(&quot;//link[@href='http://example.com']&quot;);

// select an attribute value
String val = linkNodes.get(0).attributeValue(&quot;href&quot;);

// select element text and trim it
String value = document.elementTextTrim(&quot;childNode&quot;);
</pre>
<p>etc. pp.</p>
<p>Simple, powerful, straight forward &#8212; and performance is also decent (it&#8217;s pretty slow in debug mode, but reasonably fast otherwise).</p>
<div id="AnswersBalloon" style="width:490px;position:absolute;visibility:hidden;z-index:99999;text-align:left;top:45px;left:305px;">
<div class="AnswersHeader">
<div id="AnswersHandle0" class="AnswersHeaderInner" style="cursor:move;">
<div class="AnswersHeader1"><a style="float:right;"><img style="margin-right:10px;position:relative;cursor:pointer;" src="http://www.answers.com/main/images/close.gif" border="0" alt="Close" align="top" /></a><a id="AnswertipMore" style="float:right;text-decoration:none;visibility:hidden;padding-right:10px;margin-top:9px;cursor:pointer;" target="AnswersQueryWindow"><span class="AnswersHeader3"> Read more &gt;&gt; </span></a><a id="AnswertipOptions" style="float:right;text-decoration:none;padding-right:10px;margin-top:9px;cursor:pointer;"><span class="AnswersHeader3"> Options &gt;&gt; </span></a></div>
<div><a style="float:left;cursor:pointer;" href="http://www.answers.com?initiator=FFANS"><img src="http://www.answers.com/main/images/answers-logo.gif" border="0" alt="Visit Answers.com" align="top" /></a></div>
</div>
<div id="Answers_frame" class="AnswersContentFrame">
<table id="Balloontable2" class="donotmoveme" style="width:480px;float:left;" border="0">
<tbody>
<tr>
<td></td>
</tr>
</tbody>
</table>
</div>
<div id="Answers_footer" class="AnswersFooter"></div>
</div>
</div>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/83/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/83/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/83/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=83&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2009/05/19/the-force-unleashed-xmlxpath-on-android-using-dom4j-and-jaxen/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>

		<media:content url="http://www.answers.com/main/images/close.gif" medium="image">
			<media:title type="html">Close</media:title>
		</media:content>

		<media:content url="http://www.answers.com/main/images/answers-logo.gif" medium="image">
			<media:title type="html">Visit Answers.com</media:title>
		</media:content>
	</item>
		<item>
		<title>Introducing Signpost: Easy OAuth for Java and Apache HttpComponents (Android, too)</title>
		<link>http://brainflush.wordpress.com/2009/05/03/introducing-signpost-easy-oauth-for-java-and-apache-httpcomponents-android-too/</link>
		<comments>http://brainflush.wordpress.com/2009/05/03/introducing-signpost-easy-oauth-for-java-and-apache-httpcomponents-android-too/#comments</comments>
		<pubDate>Sun, 03 May 2009 09:58:06 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=72</guid>
		<description><![CDATA[I would like to announce a project I started, which I hope may be useful to Java (particularly Google Android) application developers who need to communicate with web services that leverage the OAuth protocol for accessing protected resources.
What is Signpost?
Signpost is the easy and intuitive solution for signing HTTP messages in conformance with the OAuth [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=72&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I would like to announce a project I started, which I hope may be useful to Java (particularly Google Android) application developers who need to communicate with web services that leverage the OAuth protocol for accessing protected resources.</p>
<h2>What is Signpost?</h2>
<p><a href="http://code.google.com/p/oauth-signpost/">Signpost</a> is the easy and intuitive solution for signing HTTP messages in conformance with the <a rel="nofollow" href="http://oauth.net/core/1.0">OAuth Core 1.0</a> standard. Signpost has been designed to work in conjunction with the <a rel="nofollow" href="http://hc.apache.org/">Apache HttpComponents</a> library, a proven, well-established HTTP library for the Java programming language.</p>
<p>Signpost is still in beta stage, which means it may contain bugs. The <a href="http://code.google.com/p/oauth-signpost/">project is currently hosted at Google Code</a> and can be downloaded, distributed and used under the terms of the Apache License, version 2.</p>
<h2>Why another OAuth library for Java?</h2>
<p>It was my discontendness with Netflix&#8217;s OAuth implementation which ultimately drove me to develop my own solution. My biggest gripes with it were:</p>
<ul>
<li>Its clumsy, overly complicated API</li>
<li>Its tendency to do more than what&#8217;s actually in the standard (why does it implement an own HTTP layer? OAuth is about message <em>signing</em>, not about message <em>sending</em>)</li>
<li>Its limitations resulting from the last point, particularly:
<ul>
<li>Its ignorance towards RESTful web services (a 201 is treated as an error)</li>
<li>Its inability to process other HTTP verbs than GET (you must subclass in order to POST or PUT a resource)</li>
<li>Its inability to send more complex messages (don&#8217;t even try to send multipart requests)</li>
</ul>
</li>
</ul>
<p>Signpost attempts to avoid these issues as described below (a brief remark: Despite those issues, I highly appreciate Netflix&#8217;s work on the original implementation. In fact, Signpost is to some degree based on code from the reference implementation).</p>
<h2>Goals of Signpost</h2>
<p>Signpost has been designed with several principal goals in mind:</p>
<h3>Simplicity</h3>
<p>Using Signpost is as simple as it could possibly get &#8212; all actions are executed with only a few lines of code. For example, here is how you would sign an HTTP message using Signpost (assuming you have already created the involved <a rel="nofollow" href="http://hc.apache.org/httpcomponents-client/httpclient/apidocs/org/apache/http/client/HttpClient.html">HttpClient</a> and OAuthConsumer objects):</p>
<pre class="brush: java;">
        // create an HTTP request to a protected resource
        HttpGet request = new HttpGet(&quot;http://example.com/protected&quot;);

        // sign the request (consumer is a Signpost OAuthConsumer)
        consumer.sign(request);

        // send the request
        HttpResponse response = httpClient.execute(request);
</pre>
<p>Signpost exposes a minimalistic API designed for two purposes: Signing HTTP messages and requesting tokens from an <a rel="nofollow" href="http://oauth.net/core/1.0#anchor5">OAuth service provider</a>. Everything else is beyond the scope of the OAuth specification, and is thus left to the HTTP messaging layer, where it belongs.</p>
<p>For more exhaustive examples, please refer to <a href="http://code.google.com/p/oauth-signpost/wiki/GettingStarted">GettingStarted</a>.</p>
<h3>Unobtrusiveness</h3>
<p>Signpost tries to be as unobtrusive as possible. Unlike the <a rel="nofollow" href="http://oauth.googlecode.com/svn/code/java/">OAuth reference implementation for Java</a>, Signpost does not wrap the entire HTTP layer and hides its features from the client. Instead, you simply pass an <a rel="nofollow" href="http://hc.apache.org/httpcomponents-core/httpcore/apidocs/org/apache/http/HttpRequest.html">HttpRequest</a> object to it, and Signpost will sign the message using the credentials it was configured with. This means that all the power and flexibility of the Apache HttpComponents<a href="http://code.google.com/p/oauth-signpost/w/edit/HttpComponents">?</a> is still at your fingertips!</p>
<h2>Limitations</h2>
<p>Simplicity doesn&#8217;t come free. Thus, Signpost currently makes certain assumptions to reduce the complexity of both the implementation and the API.</p>
<h3>Deviations from the OAuth standard</h3>
<ul>
<li>Additional service provider parameters for retrieving request tokens are currently unsupported (cf. <a rel="nofollow" href="http://oauth.net/core/1.0#auth_step1">section 6.1</a>)</li>
<li>Message signing using public key encryption (as per <a rel="nofollow" href="http://oauth.net/core/1.0#anchor19">section 9.3</a>) is currently unsupported. Message signing using the PLAINTEXT and HMAC-SHA1 is supported, however.</li>
<li>The OAuth standard demands that OAuth request parameters <em>may</em> be put in the URI query string or in the message payload. Signpost will <em>never</em> do that; instead, all OAuth protocol parameters are written to the HTTP <a rel="nofollow" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.8">Authorization</a> header field. Anything you put there will be overwritten by Signpost.</li>
<li>Signpost does not support writing OAuth protocol params to the <a rel="nofollow" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.47">WWW-Authenticate</a> header field</li>
</ul>
<p>I believe that even with those restrictions in place, Signpost will work for 99% of its users. Trading in some flexibility only relevant for edge cases was a design decision. If that doesn&#8217;t work for your setup, then Signpost is probably not the best choice.</p>
<h3>Thread Safety</h3>
<p>Signpost is not thread safe and probably will never be. Signpost objects are very lightweight, so you are adviced to create an OAuthConsumer and OAuthProvider for every thread in your application that must send signed HTTP requests.</p>
<h2>Google Android</h2>
<p>Signpost works flawlessly in conjunction with <a rel="nofollow" href="http://code.google.com/android">Android</a>, Google&#8217;s software stack for mobile devices. In fact, Signpost has already signed thousands of HTTP requests at this very moment, as it is an integral part of <a rel="nofollow" href="http://www.qype.co.uk/go-mobile">Qype Radar</a>, our geo-sensitive mobile application for Android that finds the best places near you.</p>
<p>Since Android already ships with a recent version of the Apache HttpComponents<a href="http://code.google.com/p/oauth-signpost/w/edit/HttpComponents">?</a>, you merely need to add the <a rel="nofollow" href="http://code.google.com/p/oauth-signpost/downloads/list">Signpost JAR</a> to your Android application, and you&#8217;re all set.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/72/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=72&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2009/05/03/introducing-signpost-easy-oauth-for-java-and-apache-httpcomponents-android-too/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
		<item>
		<title>Android In-Sync: Handling concurrent tasks in Google Android</title>
		<link>http://brainflush.wordpress.com/2009/04/08/android-in-sync-handling-concurrent-tasks-in-google-android/</link>
		<comments>http://brainflush.wordpress.com/2009/04/08/android-in-sync-handling-concurrent-tasks-in-google-android/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 18:34:56 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[asynchronous]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[threading]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=62</guid>
		<description><![CDATA[UPDATE 15/12/2009: While the problem described here still applies to the latest version of Android, I discourage anyone from using the code linked here. I&#8217;ve bundled a better solution with my Droid-Fu library, which is a little more intrusive, but leads to much leaner code for the application developer.
Today I want to talk a little [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=62&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>UPDATE 15/12/2009:</strong> While the problem described here still applies to the latest version of Android, I discourage anyone from using the code linked here. I&#8217;ve bundled a better solution with my <a href="http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/">Droid-Fu</a> library, which is a little more intrusive, but leads to much leaner code for the application developer.</p>
<p>Today I want to talk a little bit about concurrency in Android applications, and the problems it poses on the developer. If you have used Android on your phone before, it&#8217;s likely that you have stumbled upon applications which load data off the internet, or perform other time consuming operations. The problem with time consuming operations is that, well, they consume time, and if they aren&#8217;t perfomed concurrently to Android&#8217;s user interface thread (the main thread), then the UI will lock up &#8212; certainly not a good user experience. So, it&#8217;s pretty obvious that on internet phones like those based on Android, highly concurrent applications are more the rule than the exception.</p>
<p>I guess I don&#8217;t have to mention that developing concurrent applications is everything but simple. Keeping threads that share data in sync is not a trivial task and prone to errors. What makes it even more difficult in Android is the fact that while your application is loading data, it may suddenly be interrupted by an incoming phone call or because the user decided to flip the screen into a different orientation. You may think that your thread will get paused while the activity that created it is brought to the background (or even gets destroyed). That&#8217;s not what happens though: any thread will continue running until it completes, even if your activity or service is not alive anymore. And that&#8217;s where the pain starts.</p>
<h2>Problem Statement</h2>
<p>Consider the following news reader application (just as an example). To keep things simple, the application only supports one operation: Showing the latest news articles on the screen using pagination. When started the first time, the application loads the first 10 articles off the internet in a separate thread and renders a nifty spinner visual to keep the user happy. When the user wants to read the next 10 articles, a button is pressed, the spinner appears again, and the next 10 articles are loaded, etc. pp. We have two separate threads running concurrently in this application: The main UI thread that renders all the article items and the spinner graphic, and the thread that downloads data off the web and posts that data back to the UI thread upon completion, so the UI can update itself accordingly.</p>
<p>Now, what happens if a phone call comes in while we see the spinner graphic? What happens is that Android will pause your application (probably even destroy it) in order to launch the call activity on top of it, but your download thread <em>will continue running in the background</em>. It&#8217;s difficult to tell what is going to happen when that thread tries to post its result to an activity that doesn&#8217;t even exist anymore, but most probably that application will crash (for example when the download result handler in that activity tries to display a toast or dialog, which will be attached to a window that has already been destroyed). If that thread doesn&#8217;t terminate and still holds a reference to the calling activity, it may even produce a memory leak. Long story short, you will definitely want to introduce some mechanism that keeps the communication between activities, services, and any threads they run, in sync.</p>
<h2>Solution</h2>
<p>Lucky for you, it just so happens that I have written a module that does exactly that. Based on <a href="http://brainflush.wordpress.com/2008/08/15/handling-long-running-operations-in-google-android/">my former work</a> on this problem and an <a href="http://ociweb.com/jnb/jnbJan2009.html">excellent article by Eric Burke</a> (who already presented an almost-working solution), I have come up with a Task class that you can use to dispatch long running operations from your activities and services and which also handles all the inconveniences arising from situations like resuming from an interruption (phone calls and the likes).</p>
<p>And here is how you use it:</p>
<pre class="brush: java;">
public class Concurrency extends Activity implements TaskListener&lt;String&gt; {

    private static final int TASK1 = 0;

    private static final int TASK2 = 1;

    private Task&lt;String&gt; task1, task2;

    private Callable&lt;String&gt; callable1 = new Callable&lt;String&gt;() {

        public String call() throws Exception {
            try {
                System.out.println(&quot;task1 starting&quot;);
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                System.out.println(&quot;task1 finished&quot;);
            }
            return &quot;task1 result&quot;;
        };
    };

    private Callable&lt;String&gt; callable2 = new Callable&lt;String&gt;() {

        public String call() throws Exception {
            try {
                System.out.println(&quot;task2 starting&quot;);
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                System.out.println(&quot;task2 finished&quot;);
            }
            return &quot;task2 result&quot;;
        };
    };

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

    @Override
    protected void onPause() {
        super.onPause();

        task1.unregisterCallback();
        task2.unregisterCallback();
    }

    @Override
    protected void onResume() {
        super.onResume();

        task1 = Task.getOrCreate(this, TASK1);
        task2 = Task.getOrCreate(this, TASK2);

        switch (task1.state()) {
        case NOT_STARTED:
            task1.run(this, callable1);
            break;
        case RUNNING:
            System.out.println(&quot;task1 still running&quot;);
            break;
        case COMPLETED:
            System.out.println(&quot;task1 completed in background, result: &quot;
                    + task1.getResult());
            break;
        }

        switch (task2.state()) {
        case NOT_STARTED:
            task2.run(this, callable2);
            break;
        case RUNNING:
            System.out.println(&quot;task2 still running&quot;);
            break;
        case COMPLETED:
            System.out.println(&quot;task2 completed in background, result: &quot;
                    + task2.getResult());
            break;
        }

    }

    @Override
    public void onTaskFinished(Task&lt;String&gt; task) {

        if (task.failed()) {
            System.err.println(&quot;task&quot; + task.getTaskId() + &quot; failed. Reason: &quot;
                    + task.getError().getMessage());
        } else {
            System.out.println(&quot;task&quot; + task.getTaskId() + &quot; finish handler: &quot;
                    + task.getResult());
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Task.cancelAll(this);
        }

        return super.onKeyDown(keyCode, event);
    }
}
</pre>
<p>Let&#8217;s walk through that code bit by bit. First, our activity defines two task objects, task1 and task2, with IDs TASK1 and TASK2. What those tasks are supposed to do is defined using two Callable objects, callable1 and callable2. Everything that happens inside the call() methods of those objects will be executed in a separate thread. We also have to tell those tasks what will happen should they complete. We do this by implementing the TaskListener interface, which currently only defines a single method: onTaskFinished(Task). We can check in that handler whether the task succeeded or not by calling its failed() method. If any exception was thrown during the execution of call(), this method will return true and the exception can be retrieved by calling its getError() method. Otherwise, the return value of getResult() is guranteed to be whatever you return in the callable. The Task class is generic: You instantiate it using the return type of the callable you pass to it. This ensures type safety when working with the result object. The same holds for TaskListener.</p>
<p>A closer look to onResume() reveals that everytime our activity is resumed, those task objects are either already in memory or will be created for us by calling Task.getOrCreate(). If we already started that task during a previous life-cycle of our activity, we can poll its status to check whether it has already completed or if it&#8217;s still running. The former is the case if the thread had terminated while our activity was paused or even completely destroyed; in that case, we can simply pick up whatever result the task came up with in the meantime. We also call Task.unregisterCallback() in onPause() in order to avoid being called back by the task when the activity goes poof (not doing so may result in memory leaks, as described above).</p>
<p>Right now, the activity will pick up any results of a task with a certain ID when being restarted, even when explicitly restarted by the user. If that&#8217;s not what you want, you can make a call to Task.cancelAll() in the key handler for the &#8216;back&#8217; key. That way you can ensure that all tasks (or their results) are discarded when explicitly exiting the activity. You can also cancel a single task using task.cancel(). A canceled task will never post any result or error data back to the caller.</p>
<h2>How it works</h2>
<p>Internally, task state is maintained in a static hash mapping callers to their list of tasks. This assures that tasks are kept in memory as long as the Task class itself (or until they terminate of course). The Task class does all the locking, state updates and callback invocations for us; we can even create a <a href="http://developer.android.com/reference/android/app/ProgressDialog.html">ProgressDialog</a> and assign it to a Task using Task.setProgressDialog(). The dialog will then automatically be displayed when the task starts running, and will close when the task finishes. A task (or more precisely: a list of tasks) is bound to its caller (the calling activity or service) by the caller&#8217;s <a href="http://developer.android.com/reference/android/content/ComponentName.html">ComponentName</a>. That means, you can think of tasks being associated to a calling <em>class</em>, rather than a calling <em>object</em>. The task class will take care of removing tasks that finished and which have been posted back to the caller, but it will preserve all completed (uncanceled) tasks until the caller claims its results, in case the caller wasn&#8217;t reachable while the task was finishing.</p>
<p>You can download the Task module for free <a href="http://infodump.de/task.zip">here</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/62/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=62&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2009/04/08/android-in-sync-handling-concurrent-tasks-in-google-android/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
		<item>
		<title>Talking to Web Servers via HTTP in Android 1.0</title>
		<link>http://brainflush.wordpress.com/2008/10/17/talking-to-web-servers-via-http-in-android-10/</link>
		<comments>http://brainflush.wordpress.com/2008/10/17/talking-to-web-servers-via-http-in-android-10/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 20:08:28 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Mobile Devices]]></category>
		<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=36</guid>
		<description><![CDATA[If you have worked with Google Android prior to the 1.0 release, you probably have noticed that Google has upgraded the Apache HttpClient module in Android 1.0 from 3.x to a recent alpha release of version 4, which is a complete rewrite and brings with it a host of API changes. Unfortunately, the alpha version [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=36&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>If you have worked with <a href="http://code.google.com/android" target="_blank">Google Android</a> prior to the 1.0 release, you probably have noticed that Google has upgraded the <a href="http://hc.apache.org/httpcomponents-client" target="_blank">Apache HttpClient</a> module in Android 1.0 from 3.x to a recent alpha release of version 4, which is a complete rewrite and brings with it a host of API changes. Unfortunately, the alpha version included in Android 1.0 is both terribly documented and lacking an important feature: supporting multipart requests using the multipart/form-data MIME type. Sending GET requests has changed significantly, too. Where you were formerly be able to add request parameters to a <strong>GetMethod</strong> object, you now will have to build a query string on your own and initialize an <strong>HttpGet</strong> object with it.</p>
<p>Here is how HTTP GET works in Android 1.0:</p>
<pre class="brush: java;">
HttpClient httpClient = new DefaultHttpClient();

StringBuilder uriBuilder = new StringBuilder(SERVICE_ENDPOINT);
uriBuilder.append(&quot;?param0=&quot; + param0);
uriBuilder.append(&quot;&amp;param1=&quot; + param1);
uriBuilder.append(&quot;&amp;paramN=&quot; + paramN);

HttpGet request = new HttpGet(uriBuilder.toString());
HttpResponse response = httpClient.execute(request);

int status = response.getStatusLine().getStatusCode();

// we assume that the response body contains the error message
if (status != HttpStatus.SC_OK) {
    ByteArrayOutputStream ostream = new ByteArrayOutputStream();
    response.getEntity().writeTo(ostream);
    Log.e(&quot;HTTP CLIENT&quot;, ostream.toString()));
} else {
    InputStream content = response.getEntity().getContent();
    // &lt;consume response&gt;
    content.close(); // this will also close the connection
}
</pre>
<p>Sending a multipart request first involves some environmental setup, since the required libraries are not bundled with Android 1.0. First, go to the <a href="http://hc.apache.org/downloads.cgi" target="_blank">Apache HttpClient download page</a> and download the distribution called &#8220;Binary with dependencies&#8221;. In that package you&#8217;ll find two libraries: <strong>apache-mime4j-0.4.jar</strong> and <strong>httpmime-4.0-beta1.jar</strong>. Copy these files to e.g. the lib/ folder of your Android project and add them to the build path. You can now use a <strong>MultipartEntity</strong> to send multipart POSTs as such:</p>
<pre class="brush: java;">
HttpClient httpClient = new DefaultHttpClient();

HttpPost request = new HttpPost(SERVICE_ENDPOINT);
MultipartEntity entity = new MultipartEntity();
entity.addPart(&quot;param0&quot;, new StringBody(&quot;value0&quot;));
entity.addPart(&quot;param1&quot;, new StringBody(Double.toString(1.0)));
entity.addPart(&quot;paramN&quot;, new FileBody(new File(&quot;/bar/baz&quot;)));
request.setEntity(entity);

HttpResponse response = httpClient.execute(request);
int status = response.getStatusLine().getStatusCode();

if (status != HttpStatus.SC_OK) {
    // see above  
} else {
    // see above
}
</pre>
<p>And that&#8217;s that. I assume Google has included this early build of HttpClient 4 in Android 1.0 so that they will remain API-stable for the years to come, without being stuck with a legacy HTTP component.</p>
<p>&#8211;</p>
<p><strong>References:</strong><br />
<a href="http://groups.google.com/group/android-developers/browse_frm/thread/e4230ed22c196772" target="_blank">http://groups.google.com/group/android-developers/browse_frm/thread/e4230ed22c196772</a><br />
<a href="http://wiki.apache.org/HttpComponents/HttpCoreTutorial" target="_blank"> http://wiki.apache.org/HttpComponents/HttpCoreTutorial</a><br />
<a href="http://hc.apache.org/httpcomponents-client/examples.html" target="_blank"> http://hc.apache.org/httpcomponents-client/examples.html</a></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/36/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/36/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/36/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=36&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2008/10/17/talking-to-web-servers-via-http-in-android-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
		<item>
		<title>Using cURL for Testing Web Applications</title>
		<link>http://brainflush.wordpress.com/2008/03/18/using-curl-for-testing-web-applications/</link>
		<comments>http://brainflush.wordpress.com/2008/03/18/using-curl-for-testing-web-applications/#comments</comments>
		<pubDate>Tue, 18 Mar 2008 10:05:25 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mime]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[servlets]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/?p=15</guid>
		<description><![CDATA[This may be old news to some, but although I had heard of using cURL for downloading files off the internet from a command line (as a wget alternative), I didn&#8217;t know that it was actually capable of doing much, much more. In fact, cURL is a very good allrounder at doing anything related to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=15&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This may be old news to some, but although I had heard of using <a href="http://curl.haxx.se/" target="_blank">cURL</a> for downloading files off the internet from a command line (as a <a href="http://www.gnu.org/software/wget/" target="_blank">wget</a> alternative), I didn&#8217;t know that it was actually capable of doing much, much more. In fact, cURL is a very good allrounder at doing <em>anything </em>related to transmitting and receiving data using popular protocols such as HTTP(S), (S)FTP, TELNET, LDAP and more. In particular, you can use it to test your Web application with very little effort!</p>
<p>I am currently programming for a Java Servlet based Web application, where I need to assemble HTTP requests on the client side and dissect them on the server side. More precisely, I have a servlet which extracts data from an HTTP multipart request (using <a href="http://commons.apache.org/fileupload/" target="_blank">Apache Commons FileUpload</a>) and hand it over to the logic for further processing. Of course, I have to write lots of code for checking whether requests are valid and so forth. So, in order to test this code, I want to send &#8220;malformed&#8221; requests, by which I mean requests that do not carry data expected by the application in its current state. Instead of setting up a complex test environment or even modifying your client code to send bad data, you can simply use cURL.</p>
<p>cURL uses a simple command line interface; I will show you the most important flags. Let&#8217;s assume we have a simple <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">RESTful</a> Web application which manages books. We could use cURL to retrieve the list of available books like this:</p>
<blockquote><p>curl http://localhost:8080/mybookstore/books -v</p></blockquote>
<p>This will issue an HTTP GET on the specified URL. The -v flag tells cURL to be verbose, which means it will print all sent and received HTTP headers, the payload of the server reply, plus some additional status information to the standard output. The complete output might look something like this:</p>
<blockquote><p>* About to connect() to localhost port 8080 (#0)<br />
*   Trying 127.0.0.1&#8230; connected<br />
* Connected to localhost (127.0.0.1) port 8080 (#0)<br />
&gt; GET /mybookstore/books HTTP/1.1<br />
&gt; User-Agent: curl/7.18.0 (i586-pc-mingw32msvc) libcurl/7.18.0 zlib/1.2.3<br />
&gt; Host: localhost:8080<br />
&gt; Accept: */*<br />
&gt;<br />
&lt; HTTP/1.1 200 OK<br />
&lt; Server: Apache-Coyote/1.1<br />
&lt; Content-Type: application/xml;charset=utf-8<br />
&lt; &#8230;<br />
&lt; &lt;books&gt;&lt;book author=&#8221;David Flanagan&#8221;&gt;Java In A Nutshell&lt;/book&gt;&lt;book author=&#8221;Stephen Hawking&#8221;&gt;A Brief History Of Time&lt;/book&gt;&#8230;&lt;/books&gt;</p></blockquote>
<p>The &gt; symbol indicates data going <em>to </em>the server, while &lt; indicates data coming <em>from </em>the server. If that&#8217;s not verbose enough for you, try using the <tt>--trace-ascii &lt;filename&gt;</tt> argument instead. It will log the client/server conversation to the specified file.</p>
<p>So, what about sending data? It&#8217;s actually just as easy. Suppose we want to store a new book by supplying its title and author:</p>
<blockquote><p>curl  http://localhost:8080/mybookstore/books -F &#8220;title=Wikinomics&#8221; -F &#8220;author=D. Tapscott, A. D. Williams&#8221;</p></blockquote>
<p>What this does is issueing an HTTP POST to the specified address, submitting the given data using the <a href="http://tools.ietf.org/html/rfc2388" target="_blank">multipart/form-data</a> <a href="http://www.mhonarc.org/~ehood/MIME/toc.html" target="_blank">MIME</a> type. Now that was easy! If you don&#8217;t want to type all the input data on the command line, you can also let cURL read data from a file by prefixing the value with @ followed by the file name, which makes perfect sense when transmitting binary data or long text documents. As to the way how cURL transmits the data, you can also use the -d flag, which will result in the data being POST-ed as an application/x-www-form-urlencoded string, or use the same -d flag in combination with -G to issue a GET request instead and sending the data as a URL parameter (query string).</p>
<p>Another noteworthy aspect about cURL is that you can use it to manage cookies. Let&#8217;s assume our book server requires the user to login first, and that the server remembers us by setting a session cookie. Ponder the commands below, where we use cURL first to authenticate with our server, and then add a new book in the same session:</p>
<blockquote><p>curl  http://localhost:8080/mybookstore/login -d &#8220;username=john&#8221; -d &#8220;password=doe&#8221; -c cookies.txt<br />
curl  http://localhost:8080/mybookstore/books -b cookies.txt -F &#8220;title=&#8230;&#8221; &#8230;</p></blockquote>
<p>In the first line, we tell cURL to use the file cookies.txt as its &#8220;cookie jar&#8221;, which means that it will store all cookies set by the server in this file. We can leverage the session data stored in that file (for a Servlet container this would be a JSESSIONID) in consecutive requests in order to remain authenticated, by setting the value of the -b flag to the cookie jar. You can also use key/value pairs as an argument to -b, but using an intermediary file is more convenient.</p>
<p>cURL is <a href="http://en.wikipedia.org/wiki/Free_software" target="_blank">free software</a> and can be downloaded for a broad range of platforms from the <a href="http://curl.haxx.se/download.html" target="_blank">cURL website</a>.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/brainflush.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/brainflush.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=15&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2008/03/18/using-curl-for-testing-web-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
		<item>
		<title>Integrating Direct Web Remoting (DWR) in Mozilla Thunderbird</title>
		<link>http://brainflush.wordpress.com/2008/01/18/integrating-direct-web-remoting-dwr-in-mozilla-thunderbird/</link>
		<comments>http://brainflush.wordpress.com/2008/01/18/integrating-direct-web-remoting-dwr-in-mozilla-thunderbird/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 09:04:27 +0000</pubDate>
		<dc:creator>Matthias Käppler</dc:creator>
				<category><![CDATA[Software Development & Programming]]></category>
		<category><![CDATA[dwr]]></category>
		<category><![CDATA[extension-development]]></category>
		<category><![CDATA[gecko]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[servlets]]></category>
		<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[xul]]></category>

		<guid isPermaLink="false">http://brainflush.wordpress.com/2008/01/18/integrating-direct-web-remoting-dwr-in-mozilla-thunderbird/</guid>
		<description><![CDATA[Direct Web Remoting, or DWR for short, is a Web technology for exposing server-side Java interfaces via a dynamically generated JavaScript API. A specific Servlet will translate incoming JavaScript calls to their Java equivalents which makes integration of applications programmed in client-side JavaScript with Web applications written in server-side Java a no-brainer.
DWR calls are typically [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=8&subd=brainflush&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://www.directwebremoting.org" target="_blank">Direct Web Remoting</a>, or DWR for short, is a Web technology for exposing server-side Java interfaces via a dynamically generated JavaScript API. A specific Servlet will translate incoming JavaScript calls to their Java equivalents which makes integration of applications programmed in client-side JavaScript with Web applications written in server-side Java a no-brainer.</p>
<p>DWR calls are typically dispatched from a JavaScript/JScript program running in a Web browser such as Mozilla Firefox or Microsoft&#8217;s Internet Explorer, but since all Mozilla products are built upon the <a href="http://en.wikipedia.org/wiki/Gecko_%28layout_engine%29" target="_blank">Gecko</a> layout engine and <a href="http://en.wikipedia.org/wiki/XUL" target="_blank">XUL</a> (which are programmed using JavaScript modules), you can leverage DWR to dispatch remote calls from e.g. a Mozilla Thunderbird extension just as easily. Integrating DWR into a XUL based extension is actually pretty straight forward, but there are couple of subtleties to be aware of.</p>
<p>I will hereafter assume that a Web application called &#8216;MyWebApp&#8217; has been deployed on localhost port 8080, that it&#8217;s up and running, that it exposes an interface called &#8216;MyService&#8217; via DWR. Refer to the DWR documentation  if you are unsure how to do that. It is further assumed that the DWR servlet is reached at dwr/ relative to the base URL. All following code examples refer to DWR version 1.1, which unfortunately has already been superseded by version 2.x at the time of this writing. If required at all, changing the code to run with newer versions of DWR should be easy enough however.</p>
<p>In order for your XUL component to be able to access `MyService&#8217;, add the following lines to your XUL file (e.g. myOverlay.xul):</p>
<blockquote>
<pre>&lt;script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/engine.js"/&gt;

&lt;script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/util.js"/&gt;

&lt;script type="application/x-javascript"
    src="http://localhost:8080/MyWebApp/dwr/interface/MyService.js"/&gt;</pre>
</blockquote>
<p>Don&#8217;t go looking for MyService.js in your file system, it&#8217;s not there. DWR will take care of dynamically creating it once your client requests it from the server. You can find both engine.js and util.js in the dwr.jar file which should reside at WEB-INF/lib of your deployed Web application.</p>
<p>Now you&#8217;re already prepared to invoke your service. However, when run outside a Web browser, as is the case with e.g. a Thunderbird extension, there is a catch: DWR won&#8217;t correctly resolve the target URL for your server, because it operates on relative URLs by default. You can fix that problem by modifying the MyService._path variable, which was auto-generated by DWR. Ponder the example program below, which invokes MyService.service() from a JavaScript program running in a Thunderbird extension:</p>
<blockquote>
<pre>function callService() {

    MyService._path = "http://localhost:8080/MyWebApp/dwr";

    MyService.service({
        callback: function(returnData) {
            // perform logic
        },

        errorHandler: function(error) {
            // handle error
        }
    });
}</pre>
</blockquote>
<p>That&#8217;s it basically; of course you may want to add additional call variables or use another invocation style altogether, but you get the idea.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/brainflush.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/brainflush.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brainflush.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brainflush.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/brainflush.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/brainflush.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/brainflush.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/brainflush.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/brainflush.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/brainflush.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/brainflush.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/brainflush.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brainflush.wordpress.com&blog=2284713&post=8&subd=brainflush&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://brainflush.wordpress.com/2008/01/18/integrating-direct-web-remoting-dwr-in-mozilla-thunderbird/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/5cfa38a7e54e6c6a850dc6169a699246?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mkaeppler</media:title>
		</media:content>
	</item>
	</channel>
</rss>