<?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>{5} Setfive - Talking to the World &#187; Java</title>
	<atom:link href="http://shout.setfive.com/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://shout.setfive.com</link>
	<description></description>
	<lastBuildDate>Wed, 18 Jan 2012 21:09:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Getting started with Hadoop, Hive, and Sqoop</title>
		<link>http://shout.setfive.com/2011/09/14/getting-started-with-hadoop-hive-and-sqoop/</link>
		<comments>http://shout.setfive.com/2011/09/14/getting-started-with-hadoop-hive-and-sqoop/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 05:32:15 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[hive]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[sqoop]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=917</guid>
		<description><![CDATA[I apologize for the buzzword heavy title but it was the best I could do. I couldn&#8217;t find a good quick start explaining how to get started with Hive so I thought I&#8217;d share my experiences. Anyway, a client of ours came to us needing to analyze a dataset that was about ~200 million rows [...]]]></description>
			<content:encoded><![CDATA[<p>I apologize for the buzzword heavy title but it was the best I could do. I couldn&#8217;t find a good quick start explaining how to get started with Hive so I thought I&#8217;d share my experiences.</p>
<p>Anyway, a client of ours came to us needing to analyze a dataset that was about ~200 million rows over 6 months and is currently growing at about 10 million rows a week and increasing. From a reporting standpoint, they were looking to run aggregate counts and group bys over the data and then display the results on charts. Additionally, they were also looking to select subsets of the data and use them later &#8211; basically SELECT * FROM table WHERE x AND y AND z.</p>
<p>Obviously, doing the calculations in real time was out of the question so we knew we were looking for a solution that would be easy to use, support the necessary requirements and that would predictably scale with the increasing generation rate of data.</p>
<p>On the surface, MySQL looks like a decent approach but it presents a couple of issues pretty quickly:</p>
<ul>
<li>In order for the SUM, GROUP BY, and COUNT queries to be at all useful the MySQL tables would have to be heavily indexed. Unfortunately, due to the write heavy workload of the app this would mean having to copy data into an indexed MySQL database before running any reports.</li>
<li>Even with indexes, MySQL was pretty awful at selecting subsets of the data from a performance perspective.</li>
<li>And probably the biggest issue with MySQL is that it doesn&#8217;t scale linearly in the sense that if the data is growing at 500 million rows a week you can&#8217;t simply &#8220;throw more hardware&#8221; at it and be done with it.
</ul>
<p>With requirements in hand we hit the Internet and finally arrived at <a href="http://hive.apache.org/" target="_blank">Hive</a> running on top of <a href="http://hadoop.apache.org/" target="_blank">Hadoop</a>. Per <a href="http://en.wikipedia.org/wiki/Apache_Hadoop" target="_blank">Wikipedia</a>, </p>
<p>From our perspective, this stack fits our requirements nicely since it doesn&#8217;t rely on keeping a second &#8220;reporting&#8221; MySQL database available, it will handle both sum/count/group by and selecting subets, and probably most importantly it will allow us at least in the near term to scale with the increasing rate of data generation.</p>
<blockquote><p>
&#8220;Apache Hadoop is a software framework that supports data-intensive distributed applications under a free license. It enables applications to work with thousands of nodes and petabytes of data. Hadoop was inspired by Google&#8217;s MapReduce and Google File System (GFS) papers.&#8221;
</p></blockquote>
<p>To grossly over simplify, Hadoop provides a framework that allows you to break up a data intensive task into discrete pieces, run the pieces in a distributed fashion, and then combine the results giving you the results of the completed task. The quintessential example of a task that can be parallelized in this fashion is sorting a *really* big list since the list can be sorted in pieces and then the results can be combined at the end. See <a href="http://en.wikipedia.org/wiki/Merge_sort" target="_blank">Merge Sort</a></p>
<p>The second piece of the tool chain is Hive. Again via Wikipedia, </p>
<blockquote><p>
&#8220;Apache Hive is a data warehouse infrastructure built on top of Hadoop for providing data summarization, query, and analysis.Apache Hive is a data warehouse infrastructure built on top of Hadoop for providing data summarization, query, and analysis.&#8221;
</p></blockquote>
<p>Basically, Hive is a tool that leverages the Hadoop framework to provide reporting and query capabilities using a syntax similar to SQL.</p>
<p>That just leaves Sqoop, the app with a funny name and no Wikipedia entry. Sqoop was originally developed by <a href="http://www.cloudera.com/" target="_blank">Cloudera</a> and basically serves as an import tool for Hadoop. For my purposes, it allowed me to easily import the data from my MySQL database into Hadoop&#8217;s HDFS so I could use it in Hive.</p>
<p>The rest of this post walks you through setting up Hadoop+Hive and analyzing some MySQL data.</p>
<p>Now that you know the players, lets figure out what we&#8217;re actually trying to do.</p>
<ol>
<li>We want to start a Hadoop cluster to use Hive on.</li>
<li>Load our data from a MySQL database into this Hadoop cluster.</li>
<li>Use Hive to run some reports on this data.</li>
<li>Warehouse the results of this data in MySQL so we can graph it (not that exciting).</li>
</ol>
<p></p>
<h3>Starting the cluster</h3>
<p>
Theres actually one more tool you&#8217;ll need to get this to work &#8211; <a href="http://whirr.apache.org/" target="_blank">Apache Whirr</a>. Whirr is actually really cool, it lets you automatically start cluster services (Hadoop, Voldermont, etc.) at a handful of cloud platforms (AWS, Rackspace, etc.)</p>
<p><strong>NOTE: We exclusively use AWS for our hosting so everything described here is specific to AWS.</strong></p>
<p>Fisrt, download the latest copy of Whirr &#8211; http://www.fightrice.com/mirrors/apache//incubator/whirr/ to your local machine. Whirr should work everywhere but these directions will match up against Linux/OSX the best.</p>
<p>The first thing you&#8217;ll need is a Whirr configuration file describing the cluster you want to build. Create a file called hadoop.properties and paste in the following:</p>
<pre class="php" name="code">
whirr.cluster-name=hadoop
whirr.instance-templates=1 hadoop-namenode+hadoop-jobtracker,2 hadoop-datanode+hadoop-tasktracker
whirr.hadoop-install-function=install_cdh_hadoop
whirr.hadoop-configure-function=configure_cdh_hadoop

whirr.provider=aws-ec2
whirr.identity=[REPLACE THIS WITH YOUR AWS ID]
whirr.credential=[REPLACE THIS WITH YOUR AWS SECRET]

whirr.hardware-id=m1.large
whirr.image-id=us-east-1/ami-68ad5201
whirr.location-id=us-east-1

whirr.private-key-file=~/.ssh/id_rsa
whirr.public-key-file=~/.ssh/id_rsa.pub
</pre>
<p>There isn&#8217;t a ton going on in the file but you&#8217;ll need to switch out the credential lines for your AWS credentials. Also, you&#8217;ll need to double check that the ssh paths are accurate for your account.</p>
<p>The next step, is to actually launch the cluster. To do this run this command &#8211; double check the path to your hadoop.properties file is accurate:</p>
<pre class="php" name="code">
./bin/whirr launch-cluster --config hadoop.properties
</pre>
<p>Just give it a few minutes, you&#8217;ll see a bunch of debug info scrolling across your terminal and hopefully a success message once its done. At this point, you&#8217;ll have a fully built Hadoop cluster with 3 nodes as described in your properties file ( 1 hadoop-namenode+hadoop-jobtracker,2 hadoop-datanode+hadoop-tasktracker ).</p>
<p>You can see all your nodes by checking out your Whirr cluster directory.</p>
<pre class="php" name="code">
cat ~/.whirr/hadoop/instances
</pre>
<p></p>
<h3>Prepping and loading the cluster</h3>
<p></p>
<p>Now that the cluster is up, you&#8217;ll need to prep it and then load your data with Sqoop. </p>
<p>One of the most irritating &#8220;gotchas&#8221; I stumbled across was that Whirr adds the firewall rules necessary for Hadoop to its AWS security group. </p>
<p><strong>Before you do anything, open your EC2 control panel and modify the new Whirr security group (#jcloud-something) so that all of your nodes can connect to each other on port 3306 (MySQL)</strong></p>
<p>The next step is to install mysql-client across the entire cluster since Sqoop uses mysqldump to get at your data. You could manually ssh into every machine but Whirr provides a convenient &#8220;run-script&#8221; command to do just that.</p>
<p>Create a file called &#8220;prepCluster.sh&#8221; and put &#8220;sudo apt-get -q -y install mysql-client&#8221; in it. Then make sure the paths are right and run,</p>
<pre class="php" name="code">
./bin/whirr run-script --script prepCluster.sh --config hadoop.properties
</pre>
<p>Once its done, you&#8217;ll see the aptitude output from all your nodes as they downloaded the MySQL client.</p>
<p>The next step is to install mysql-server, hive, and sqoop on the jobtracker. Doing this is pretty straightforward, look at the .whirr/hadoop/instances file from above and copy the namenode hostname.</p>
<p>Next, ssh in to that machine using your current username as the username. Once you&#8217;re in, just run the following to install everything:</p>
<pre class="php" name="code">
sudo apt-get -q -y install sqoop
sudo apt-get -q -y install hadoop-hive
sudo apt-get -q -y install screen
</pre>
<p><strong>NOTE: You&#8217;ll also need the MySQL ConnectorJ library so that Sqoop can connect to MySQL. Download it <a href="http://dev.mysql.com/downloads/connector/j/" target="_blank">here</a> and place it in &#8220;/usr/lib/sqoop/lib/&#8221;</strong></p>
<p>Once everything is done installing, you&#8217;ll most likely want to move your MySQL data directories from their default location onto the /mnt partition since it&#8217;s much larger. Check out <a href="http://www.ubuntugeek.com/how-to-change-the-mysql-data-default-directory.html" target="_blank">this article</a> for a good walk through. <strong>Don&#8217;t forget to update AppArmour or MySQL won&#8217;t start.</strong> Once MySQL is setup, load the data you want to crunch.</p>
<p>Now, you&#8217;ll need to use Sqoop to load the data from the MySQL database into Hadoop&#8217;s HDFS. While logged into the jobtracker node you can just run the following to do that. You&#8217;ll need to swap out the placeholders in the command and change the u/p.</p>
<pre name="code" class="php">
sqoop-import-all-tables --connect jdbc:mysql://[IP of your jobtracker]/[your db_name] --username root --password root --verbose --hive-import
</pre>
<p>Once it completes, Sqoop will have copied all your MySQL data into Hadoop&#8217;s HDFS file system and initialized Hive for you.</p>
<p></p>
<h3>Crunching the data</h3>
<p></p>
<p>Run &#8220;hive&#8221; on the jobtracker and you&#8217;ll be ready to start crunching your data. </p>
<p>Check out the <a href="https://cwiki.apache.org/confluence/display/Hive/LanguageManual" target="_blank">Hive language manual</a> for more info on exactly what queries you can write.</p>
<p>Once you&#8217;ve narrowed down how to write your queries, you can use Hive&#8217;s &#8220;INSERT OVERWRITE LOCAL DIRECTORY&#8221; command to output the results of your query into a local directory.</p>
<p>Then, the next step would be to TAR up these results and use scp to copy the results back to your local machine to analyze or warehouse.</p>
<p></p>
<h3>Shutting it down</h3>
<p>
The final thing you&#8217;ll need to do is shut down the cluster. Whirr makes it pretty easy:</p>
<pre name="code" class="php">
./bin/whirr destroy-cluster --config hadoop.properties
</pre>
<p>Give it a few minutes and Whirr will shutdown the cluster and clean up the EC2 security group as well.</p>
<p>Anyway, hope this walk through proves useful for someone. As always, feedback, questions, and comments are all more than welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2011/09/14/getting-started-with-hadoop-hive-and-sqoop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running Java apps from the crontab</title>
		<link>http://shout.setfive.com/2011/08/12/running-java-apps-from-the-crontab/</link>
		<comments>http://shout.setfive.com/2011/08/12/running-java-apps-from-the-crontab/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 02:40:04 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[Free Advice]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=872</guid>
		<description><![CDATA[Earlier this week I was completely dumbfounded by a PHP script that launched a Java app that seemed to work fine when it was run from the command line but kept failing when it was run from a cron. The Java app in question was &#8220;ec2-describe-group&#8221; out of the Amazon EC2 API Tools package.  Basically, [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this week I was completely dumbfounded by a PHP script that launched a Java app that seemed to work fine when it was run from the command line but kept failing when it was run from a cron.</p>
<p>The Java app in question was &#8220;ec2-describe-group&#8221; out of the <a href="http://aws.amazon.com/developertools/351" target="_blank">Amazon EC2 API Tools</a> package.  Basically, the ec2-describe-group tool hits the EC2 API and returns information about your account&#8217;s currently configured security groups.</p>
<p>The issue I was having was that when the PHP script was launched from a cron ec2-describe-group would keep returning an empty string, but when the script was launched from the CLI ec2-describe-group behaved normally.</p>
<p>After some poking around, I found <a href="http://stackoverflow.com/questions/4816889/running-a-scheduled-task-written-in-java-on-a-linux-server" target="_blank">this StackOverflow</a> post which points out that most the environment variables your shell has aren&#8217;t available in a cronjob.</p>
<p>With that in mind, I tried adding JAVA_HOME as well as EC2_HOME to my crontab. Doing this is pretty straight forward, just add these two lines above any of your scheduled jobs:</p>
<pre name="code" class="php">
EC2_HOME=/opt/ec2-api-tools-1.3.36506
JAVA_HOME=/etc/java-config-2/current-system-vm
</pre>
<p>Unfortunately, this still didn&#8217;t resolve the issue. On a whim, I decided to check what type of file ec2-describe-group actually is and discovered that its a Bash script not a Java JAR. Looking at the Bash, the file is actually just executing &#8220;EC2_HOME/bin/ec2-cmd DescribeGroups&#8221; but it utilizes other environment variables that my cron didn&#8217;t have.</p>
<p>For simplicity&#8217;s sake, I decided to just switch the PHP script to run ec2-cmd directly and finally everything started working as expected.</p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2011/08/12/running-java-apps-from-the-crontab/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting text from PDFs without pdftotext</title>
		<link>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/</link>
		<comments>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 06:39:26 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[pdftotext]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=179</guid>
		<description><![CDATA[For a recent project, I had to extract the text out of a PDF so that I could save it into a database table. Normally, I would of used the popular pdftotext program but it wasn&#8217;t available in the particular environment I was working in. I contact support and they advised that the XPDF package [...]]]></description>
			<content:encoded><![CDATA[<p>For a recent project, I had to extract the text out of a PDF so that I could save it into a database table.</p>
<p>Normally, I would of used the popular pdftotext program but it wasn&#8217;t available in the particular environment I was working in. I contact support and they advised that the <a href="http://www.foolabs.com/xpdf/">XPDF</a> package has several X windows dependencies and that&#8217;s why they had not installed it. Fair enough.</p>
<p>I poked around a bit and found Apache&#8217;s <a href="http://incubator.apache.org/pdfbox/">PDFBox</a> library. I downloaded the package and looked at the examples. Sure enough there was a program called &#8220;ExtractText&#8221; that did exactly what I wanted.</p>
<p>Using ExtractText is similar to pdftotext &#8211; just pass in the PDF file and the text comes back. Awesome.</p>
<p>Anyway, hats off to <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> who wrote the ExtractText example. I rebuilt the ExtactText.java file as a standalone project and packaged it as a JAR.</p>
<p>I&#8217;ve attached the JAR and Eclipse project if anyone wants a copy of either.</p>
<p><a href="http://shout.setfive.com/wp-content/uploads/2009/06/ExtractTextSF.jar">The JAR</a></p>
<p><a href="http://shout.setfive.com/wp-content/uploads/2009/06/ExtractText.rar">The Eclipse Project</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/06/16/extracting-text-from-pdfs-without-pdftotext/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Android!</title>
		<link>http://shout.setfive.com/2009/02/23/hello-android/</link>
		<comments>http://shout.setfive.com/2009/02/23/hello-android/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 08:31:00 +0000</pubDate>
		<dc:creator>Ashish Datta</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[fun stuff]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://shout.setfive.com/?p=101</guid>
		<description><![CDATA[In the last few weeks the battle and buzz over the smart phone market seems to have seriously intensified. First there was the usual iPhone buzz, news about the Android powered HTC Magic, the Windows Mobile marketplace, and of course the obligatory ridiculousness at Microsoft. I&#8217;d been considering experimenting with a mobile platform for sometime [...]]]></description>
			<content:encoded><![CDATA[<p>In the last few weeks the battle and buzz over the smart phone market seems to have seriously intensified. </p>
<p>First there was the usual iPhone buzz, news about the Android powered <a href="http://reviews.cnet.com/8301-13970_7-10167621-78.html">HTC Magic</a>, the <a href="http://www.washingtonpost.com/wp-dyn/content/article/2009/02/16/AR2009021600899.html">Windows Mobile marketplace</a>, and of course the obligatory <a href="http://news.cnet.com/8301-10805_3-10167321-75.html">ridiculousness</a> at Microsoft.</p>
<p>I&#8217;d been considering experimenting with a mobile platform for sometime and finally decided to take the plunge. I decided to give <a href="http://code.google.com/android/">Android</a> a whirl primarily because I don&#8217;t have easy access to OSX or Visual Studio and my Java is less rusty than my .NET.</p>
<p>Anyway, getting going with Android was deliciously simple &#8211; download the <a href="http://code.google.com/android/download.html">SDK+Emulator</a> and Eclipse plugin and you&#8217;re off.</p>
<p>After the necessary &#8220;Hello World&#8221; application I tried to write something a bit more substantive. Personally, one of the coolest facets of mobile development is the ability for applications to be <a href="http://code.google.com/android/reference/android/location/LocationManager.html">location aware</a> (GPS). Mix this together with some openly available geo tagged data and the result is probably going to be interesting.</p>
<p>With this in mind, the plan became to mash together Android&#8217;s GPS coordinates with <a href="http://www.flickr.com/services/api/flickr.photos.geo.getLocation.html">flickr&#8217;s geotagged</a> photos.</p>
<p>Getting access to Android&#8217;s location service is fairly straightforward. You basically register to receive updates either when the device moves a certain distance or on some time interval:</p>
<pre class="java" name='code'>
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
flickrLocationReciever flReciever = new flickrLocationReciever();
locationManager.requestLocationUpdates( locationManager.getProviders(true).get(0),  5, 10, flReciever);

public class flickrLocationReciever implements LocationListener {
  @Override
   public void onLocationChanged(final Location arg0) {
    // do things
   }
}
</pre>
<p>The biggest &#8220;gotcha&#8221; with this is that you NEED to remember to modify the default Application security settings to allow you to access the device&#8217;s location. In Eclipse, edit AndroidManifest.xml and add &#8220;UsesPermission&#8221; for the following: android.permission.ACCESS_MOCK_LOCATION, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_FINE_LOCATION</p>
<p>So on to part II &#8211; using the device&#8217;s location to pull down Flickr photos. I&#8217;d used the Flickr API before so I knew how to do it but I&#8217;d never used it from Java. I tried loading the JAR for the <a href="http://sourceforge.net/projects/flickrj/">flickrj</a> client library but the <a href="http://en.wikipedia.org/wiki/Dalvik_virtual_machine">Android JVM</a> was having some strange issues with it. I was under the impression you can link to external JARs from Eclipse but I may be wrong (anyone?).</p>
<p>Anyway, the Flickr requests were un-authenticated and pretty straightforward so I decided to use Java&#8217;s URL class. Accessing sockets was another &#8220;gotcha&#8221; &#8211; Android requires your application to have the &#8220;UsesPermission&#8221; android.permission.INTERNET to use sockets. The exception when the permission isn&#8217;t set is notably cryptic &#8211; &#8220;unknown error&#8221;.</p>
<p>I decided to download all the Flickr photos to the device so that the UX would be generally smoother. This introduced threading to the project so that the UI wouldn&#8217;t freeze up while the photos were downloading. Android threads work just like traditional Java threads and the process was generally painless:</p>
<pre class='java' name='code'>
private Handler handler = new Handler()
  {
   public void handleMessage(Message msg) {
   // handle the end of the thread
  }
}

Thread t = new Thread()
   {
     public void run(){
     // do stuff
     // let the handler know we are done
     handler.sendEmptyMessage(1);
     }
}
T.start();
</pre>
<p>With the photos pulled down the final task was displaying them. After poking around the Android documentation I discovered the <a href="http://code.google.com/android/reference/android/widget/Gallery.html">Gallery widget</a>. It basically allows you to display a set of items in a list and specify a &#8220;renderer&#8221; for the gallery. I&#8217;m not sure if there is a default way to make it &#8220;fisheye&#8221; (like on an iPhone) but I rolled a quick n dirty solution for that. I also couldn&#8217;t get it to look really sexy but that&#8217;s also probably possible.</p>
<p>So that&#8217;s about it. Here are some screen shots of the application running in the emulator:<br />

<a href='http://shout.setfive.com/2009/02/23/hello-android/screen1/' title='screen1'><img width="150" height="150" src="http://shout.setfive.com/wp-content/uploads/2009/02/screen1-150x150.jpg" class="attachment-thumbnail" alt="screen1" title="screen1" /></a>
<a href='http://shout.setfive.com/2009/02/23/hello-android/screen2/' title='screen2'><img width="150" height="150" src="http://shout.setfive.com/wp-content/uploads/2009/02/screen2-150x150.jpg" class="attachment-thumbnail" alt="screen2" title="screen2" /></a>
<a href='http://shout.setfive.com/2009/02/23/hello-android/screen3/' title='screen3'><img width="150" height="150" src="http://shout.setfive.com/wp-content/uploads/2009/02/screen3-150x150.jpg" class="attachment-thumbnail" alt="screen3" title="screen3" /></a>
</p>
<p>And without further a due here is the code as an Eclipse project.<br />
<a href='http://shout.setfive.com/wp-content/uploads/2009/02/geoflickr.zip'>geoflickr</a></p>
<p>Anyway, before the bashing starts &#8211; I know I&#8217;m a terrible Java programmer and that this project isn&#8217;t really engineered beautifully. It was just supposed to be a way to get my (and anyone else&#8217;s) feet wet with Android. Any comments/thoughts/improvements are of course welcome! </p>
]]></content:encoded>
			<wfw:commentRss>http://shout.setfive.com/2009/02/23/hello-android/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

