<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9032662264988669481</id><updated>2012-02-02T13:42:46.460-08:00</updated><category term='design patterns'/><category term='continuous integration'/><category term='Java3D'/><category term='stub'/><category term='development'/><category term='programming'/><category term='warble'/><category term='MVP'/><category term='maven'/><category term='tomcat'/><category term='warbler'/><category term='integration technique'/><category term='web services'/><category term='game'/><category term='Java'/><category term='interface'/><category term='TDD'/><category term='agile'/><category term='software'/><category term='continuum'/><category term='animation'/><category term='rails'/><category term='GUI application'/><category term='project management'/><category term='jruby'/><category term='jee'/><category term='spike'/><title type='text'>Emergent Development</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-7171204471584488273</id><published>2012-01-29T16:41:00.000-08:00</published><updated>2012-01-30T06:21:24.764-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='warbler'/><category scheme='http://www.blogger.com/atom/ns#' term='warble'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='jee'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Fun with Rails, JRuby, and JEE</title><content type='html'>&lt;h2&gt;Background&lt;/h2&gt;&lt;p&gt;So a little while ago we were looking at a possible complete rewrite of our customer's web site and we started evaluating what we could do.  My first thought was to do a Rails app.  I've done a few small Rails projects but none for a public site for an actual customer that expects results.  Now our customer's data center only supports .Net and JEE applications so this posed an interesting integration issue.  I had heard that you could get Rails applications to run in a JEE application server using JRuby but I had never done it.  So I took some time to experiment with it and this is what I found...&lt;/p&gt;&lt;h2&gt;First try&lt;/h2&gt;&lt;p&gt;So first off I just installed JRuby.  I'm on Ubuntu 11.10 so I just did what I do for installing anything:&lt;pre&gt;apt-get install jruby&lt;/pre&gt;This got me a JRuby 1.5.1 installed.  I then proceeded to install warbler (a Rails to JEE war file packager). &lt;pre&gt;gem install warbler&lt;/pre&gt;Then I created an empty Rails app to experiment with:&lt;pre&gt;rails new testapp --database mysql&lt;/pre&gt;This created a standard rails app directory.  I then created a simple scaffold just to get something in there that would actually interact with the database.  &lt;pre&gt;rails g scaffold Person string:first_name string:last_name&lt;/pre&gt; I made sure that the databases existed:&lt;pre&gt;mysql -u root mysql -e 'create database testapp...'&lt;/pre&gt;I then migrated the databases:&lt;pre&gt;rake db:migrate RAILS_ENV=production&lt;/pre&gt;I then proceeded to package up the app in a war file by executing the &lt;i&gt;warble&lt;/i&gt; command that the warble gem provides:&lt;pre&gt;warble&lt;/pre&gt;And it churned out a testapp.war file.  I then deployed the war file to my local Tomcat directory, started it up and hit the app with my browser.  All the static content was served up just fine and all the dynamic content that actually touched ruby code did not.  In fact, when trying to reach the dynamic portions, the request timed out.  Not a 500 error message or anything, just nothing.  And nothing showed up in the Tomcat logs either.  Which made trying to guess the issue a nasty nightmare.&lt;/p&gt;&lt;h2&gt;Resulting war file&lt;/h2&gt;&lt;p&gt;So of course I took a look at the generated war file and looked to see what was in there.  And surprisingly enough, it looked much like my Rails directory.  All the public content (static html, style sheet, javascript files) was in the top level so it could be served up by regular requests to the files.  In the WEB-INF folder you get the app, config, gems, and vendor directories with what you would expect in them.  The web.xml is real simple: a few context parameters and a request filter pointing all traffic to a RackFilter:&lt;pre&gt;&lt;br /&gt;&amp;lt;!DOCTYPE web-app PUBLIC&lt;br /&gt;  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"&lt;br /&gt;  "http://java.sun.com/dtd/web-app_2_3.dtd"&amp;gt;&lt;br /&gt;&amp;lt;web-app&amp;gt;&lt;br /&gt;  &amp;lt;context-param&amp;gt&lt;br /&gt;    &amp;lt;param-name&amp;gt;public.root&amp;lt;/param-name&amp;gt;&lt;br /&gt;    &amp;lt;param-value&amp;gt;/&amp;lt;/param-value&amp;gt;&lt;br /&gt;  &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;context-param&amp;gt;&lt;br /&gt;    &amp;lt;param-name&amp;gt;rails.env&amp;lt;/param-name&amp;gt;&lt;br /&gt;    &amp;lt;param-value&amp;gt;production&amp;lt;/param-value&amp;gt;&lt;br /&gt;  &amp;lt;/context-param&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;filter&amp;gt;&lt;br /&gt;    &amp;lt;filter-name&amp;gt;RackFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;    &amp;lt;filter-class&amp;gt;org.jruby.rack.RackFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;  &amp;lt;/filter&amp;gt;&lt;br /&gt;  &amp;lt;filter-mapping&amp;gt;&lt;br /&gt;    &amp;lt;filter-name&gt;RackFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;  &amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;listener&amp;gt;&lt;br /&gt;    &amp;lt;listener-class&amp;gt;org.jruby.rack.rails.RailsServletContextListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;  &amp;lt;/listener&amp;gt;&lt;br /&gt;&amp;lt;/web-app&gt;&lt;br /&gt;&lt;/pre&gt;And of course in the lib directory you get the 3 jar files that do all the black magic: jruby-core-XXX.jar, jruby-rack-XXX.jar, jruby-stdlib-XXX.jar  These files hand off all servlet requests to the Ruby code that's hidden in the WEB-INF folders.  Quite remarkable really.  Simple.  Noninvasive.  Just wish it worked.  &lt;/p&gt;&lt;h2&gt;Logging and debugging&lt;/h2&gt;&lt;p&gt;In general, I like the debugging that you get with Rails.  Development logs are very verbose and you get lots of good information.  However, there's a disconnect between what JRuby/Rails would log (actual errors in the Ruby code) and what Tomcat would log (war deployment issues and lifecycle errors).  After a little googling I found that you can set Rails' logging to go to the STDOUT.  That way Tomcat would pick it up in the regular Tomcat logging.  Great!  So I went into my Rails application and in the config/application.rb I added a line: &lt;pre&gt;config.logger = Logger.new(STDOUT)&lt;/pre&gt;  So I re-warbled (I'm liking that as a verb) and redeployed to Tomcat.  And when I went to access the dynamic portion of the site, I got a stack trace in the log.  Wonderful!  Now I could try to fix something.  Well at the top I noticed something rather odd.  It said that I was using Ruby 1.8.  Well when I got all the Rails stuff working I was working with a RVM install of Ruby 1.9.2.  And I thought my JRuby was new enough that it'd be using 1.9 as well.&lt;/p&gt;&lt;h2&gt;Version confusion&lt;/h2&gt;&lt;p&gt;So I found out that you can get JRuby via RVM as well.  So I installed the latest JRuby from RVM (1.6.5).  And I found out that when you use JRuby with RVM your standard Ruby becomes JRuby.&lt;pre&gt;&lt;br /&gt;rvm use jruby-1.6.5&lt;br /&gt;ruby -v&lt;br /&gt;jruby 1.6.5 (ruby-1.8.7-p330) (2011-10-25 9dcd388) (Java HotSpot(TM) Server VM 1.6.0_22) [linux-i386-java]&lt;br /&gt;&lt;/pre&gt;Note that in parenthesis it shows what Ruby version JRuby will be emulating.  So even the latest JRuby was still going to be running as Ruby 1.8.  After more googling I found that you can specify to use 1.9 mode as an argument to JRuby or you can set an environment variable to always use the 1.9 mode.&lt;pre&gt;&lt;br /&gt;jruby --1.9 -v&lt;br /&gt;jruby 1.6.5 (ruby-1.9.2-p136) (2011-10-25 9dcd388) (Java HotSpot(TM) Server VM 1.6.0_22) [linux-i386-java]&lt;br /&gt;&lt;br /&gt;export JRUBY_OPTS=--1.9&lt;br /&gt;jruby -v&lt;br /&gt;jruby 1.6.5 (ruby-1.9.2-p136) (2011-10-25 9dcd388) (Java HotSpot(TM) Server VM 1.6.0_22) [linux-i386-java]&lt;br /&gt;&lt;/pre&gt;Later I was informed by &lt;a href="http://twitter.com/brianthesmith"&gt;@brianthesmith&lt;/a&gt; via &lt;a href="http://twitter.com/headius"&gt;@headius&lt;/a&gt; that just recently, &lt;a href="https://github.com/jruby/jruby/commit/3163d6ca94ccc8fd33851896614a42c29b2e5ec6"&gt;JRuby master&lt;/a&gt; now uses Ruby 1.9 as the default.  So hopefully this little version issue will go away with the next release.&lt;/p&gt;&lt;p&gt;The next issue I had was kinda a stupid on my part but again I'm not too familiar with the workings of Ruby/JRuby.  When I install a gem using Ruby, either by doing a gem install or a bundler install, it doesn't install as a gem system wide that JRuby would be able to use.  It's only available to that Ruby install.  So JRuby knows nothing of the gems installed in your standard Ruby.  Seems a little obvious now, but at the time it was a bit frustrating.  And, JRuby cannot use native gems.  Meaning that if something uses native code (like a database driver), JRuby will not be able to use it.  For example, in your Rails app you might have ActiveRecord use the &lt;i&gt;mysql2&lt;/i&gt; adapter gem.  In JRuby you would need the &lt;i&gt;activerecord-jdbcmysql-adapter&lt;/i&gt; gem.&lt;/p&gt;&lt;p&gt;Also fun, is that if you execute: &lt;pre&gt;gem install rails&lt;/pre&gt; You will get the latest greatest Rails (3.2 as of writing this).  If you want to use an earlier version, good luck!  You have to change your Gemfile to have an earlier version.  But there are several gems listed in the automatically generated Gemfile that are dependent on a the initial version of Rails.  In fact, there are several gems specified in the Gemfile that you don't need right away.  Such as sass-rails and coffee-rails which are tied to the Rails version.  The standard auto-gen Gemfile looks like this:&lt;pre&gt;&lt;br /&gt;source 'https://rubygems.org'&lt;br /&gt;&lt;br /&gt;gem 'rails', '3.2.1'&lt;br /&gt;&lt;br /&gt;# Bundle edge Rails instead:&lt;br /&gt;# gem 'rails', :git =&gt; 'git://github.com/rails/rails.git'&lt;br /&gt;&lt;br /&gt;gem 'activerecord-jdbcmysql-adapter'&lt;br /&gt;&lt;br /&gt;gem 'jruby-openssl'&lt;br /&gt;&lt;br /&gt;# Gems used only for assets and not required&lt;br /&gt;# in production environments by default.&lt;br /&gt;group :assets do&lt;br /&gt;  gem 'sass-rails',   '~&gt; 3.2.3'&lt;br /&gt;  gem 'coffee-rails', '~&gt; 3.2.1'&lt;br /&gt;&lt;br /&gt;  # See https://github.com/sstephenson/execjs#readme for more supported runtimes&lt;br /&gt;  gem 'therubyrhino'&lt;br /&gt;&lt;br /&gt;  gem 'uglifier', '&gt;= 1.0.3'&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;First off, I noticed that when you execute &lt;i&gt;bundle install&lt;/i&gt; it took forever or timed out.  But if you change the source to point to &lt;i&gt;http://rubygems.org&lt;/i&gt; instead of &lt;i&gt;https://rubygems.org&lt;/i&gt;, or better yet, set the source to &lt;i&gt;:rubygems&lt;/i&gt;, you'll actually be able to do a &lt;i&gt;bundle install&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;Another fun thing is that if you're using JRuby whilst executing &lt;i&gt;rails new appname&lt;/i&gt;, it will give you JDBC database adapters in the Gemfile, but not in the config/database.yml file.  But if you re-warble and create a war file with the non-JDBC adapters, it won't work in your JEE deployment.  Fun.&lt;/p&gt;&lt;p&gt;What I wish the Gemfile defaulted to was this:&lt;pre&gt;&lt;br /&gt;source :rubygems&lt;br /&gt;&lt;br /&gt;gem 'rails', '3.2.1'&lt;br /&gt;gem 'activerecord-jdbcmysql-adapter'&lt;br /&gt;gem 'jruby-openssl'&lt;br /&gt;&lt;/pre&gt;Then add other gems as you need them.  And if you want to use an earlier version of Rails, you could by just specifying a different version (ie. &lt;i&gt;gem 'rails', '3.0.7'&lt;/i&gt;).&lt;/p&gt;&lt;h2&gt;Warble configuration&lt;/h2&gt;&lt;p&gt;Finally, there's some adjustments I needed to make to the warble packager for the specifics of my app.  To configure warble, you need to execute the following at the top directory level of your application:&lt;pre&gt;&lt;br /&gt;warble config&lt;br /&gt;&lt;/pre&gt;This will generate a config/warble.rb file where you can make changes to the warble configuration.&lt;/p&gt;&lt;p&gt;So one change I needed to make was to provide a list of all the gems that the webapp needed when it is deployed.  This will bundle them up in the war file.  It'd be really nice if warble could read through your Gemfile and update this setting itself.  But for now, it's pretty simple to explicitly specify the needed gems.  To do this, go in and uncomment the config.gems line in config/warble.rb:&lt;pre&gt;&lt;br /&gt;config.gems += ["activerecord-jdbcmysql-adapter", "jruby-openssl"]&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;One last configuration in the warble config file that I had to do was to set the JRuby compatibility version:&lt;pre&gt;&lt;br /&gt;config.webxml.jruby.compat.version = "1.9"&lt;br /&gt;&lt;/pre&gt;This will set a context parameter in your web.xml file that will tell JRuby to be in the 1.9 mode.&lt;/p&gt;&lt;h2&gt;Finally it works!&lt;/h2&gt;&lt;p&gt;At this point, I was good to go.  Re-warbled my app to get a new war file then deploy to my Tomcat server.  And everything seemed to function as expected.&lt;/p&gt;&lt;p&gt;It seems that these war files are self-contained such that you don't need JRuby or any gems in a location outside of the server installed on the deployment server.  So any standard JEE server should be able to deploy the JRuby/Rails app without any knowledge of Ruby or JRuby.  That's pretty cool.  So if your datacenter does not support Ruby on their production servers but will support JEE servers, this may be an alternative for you and your team.&lt;/p&gt;&lt;h2&gt;Last thoughts&lt;/h2&gt;&lt;p&gt;Well this was my first experience with JRuby and I gotta admit that these little hiccups were a bit frustrating.  I'm not quite sure how things could be changed to help out complete noobs like me to setup an initial deployment, but I hope that this will help someone who's possibly struggling with the same setup issues.  And if I got something terribly wrong in the above description, please correct me and I'll edit the post.  Thanks!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-7171204471584488273?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/7171204471584488273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2012/01/fun-with-rails-jruby-and-jee.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7171204471584488273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7171204471584488273'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2012/01/fun-with-rails-jruby-and-jee.html' title='Fun with Rails, JRuby, and JEE'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-6016301898109261663</id><published>2009-07-11T04:15:00.000-07:00</published><updated>2009-07-11T05:05:14.174-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java3D'/><category scheme='http://www.blogger.com/atom/ns#' term='animation'/><title type='text'>Animations in Java 3D</title><content type='html'>Wow, I haven't done much on this blog in a while...  I haven't done a whole lot with the game lately but I got it up on github if anyone is interested: &lt;a href="http://github.com/caspian311/boardgame"&gt;http://github.com/caspian311/boardgame&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So I have been messing around a bit with how the pieces move.  The way it use to get done was by using keyframes.  The problem with that there was no way to tell when you had reached the end of the animation to signal something else to happen.  So I finally just switched it over to using Behaviors instead.&lt;br /&gt;&lt;br /&gt;From my understanding all that you need to do is extend the javax.media.j3d.Behavior class, set the scheduling bounds (setSchedulingBounds()), then add it to the scene graph.  Then you to override two methods initialize() and processStimulus(Enumeration stimuli).  &lt;br /&gt;&lt;br /&gt;In the iniatilize method you specify what event, or wake up criterion, will trigger the behavior.  For animations you can make it based on a certain number of frames has gone by or a specified amount of time has gone by or it an AWT even occurred.&lt;br /&gt;&lt;br /&gt;In the processStimulus method you loop through all the stimuli looking for the wake up criterion that you specified.  Then you do whatever you want done (move/rotate/whatever something a bit) then if you want to wake up when the next time a criterion happens you call the wakeupOn() method.&lt;br /&gt;&lt;br /&gt;Ok I'm not great at describing it, let's just see some code...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;public class AnimationBehviour extends Behavior {&lt;br /&gt; private static final float MOVEMENT_SPEED = 0.1f;&lt;br /&gt; private static final int ANIMATION_WAITING = 10;&lt;br /&gt; private final ListenerManager finishedListenerManager &lt;br /&gt;   = new ListenerManager();&lt;br /&gt; private final TransformGroup transformGroup;&lt;br /&gt; private final Vector3f currentLocation;&lt;br /&gt; private final Vector3f moveToLocation;&lt;br /&gt; private boolean atLocation;&lt;br /&gt;&lt;br /&gt; public AnimationBehviour(Bounds bounds, TransformGroup &lt;br /&gt;   transformGroup, Vector3f currentLocation, Vector3f &lt;br /&gt;   moveToLocation) {&lt;br /&gt;  this.transformGroup = transformGroup;&lt;br /&gt;  this.currentLocation = currentLocation;&lt;br /&gt;  this.moveToLocation = moveToLocation;&lt;br /&gt;&lt;br /&gt;  setSchedulingBounds(bounds);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public void initialize() {&lt;br /&gt;  wakeupOn(new WakeupOnElapsedTime(10));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @SuppressWarnings("unchecked")&lt;br /&gt; @Override&lt;br /&gt; public void processStimulus(Enumeration stimuli) {&lt;br /&gt;  while (stimuli.hasMoreElements()) {&lt;br /&gt;   WakeupCriterion criterion = (WakeupCriterion) &lt;br /&gt;         stimuli.nextElement();&lt;br /&gt;   if (criterion instanceof WakeupOnElapsedTime) {&lt;br /&gt;    moveCloser();&lt;br /&gt;&lt;br /&gt;    if (!atLocation) {&lt;br /&gt;     wakeupOn(new WakeupOnElapsedTime(ANIMATION_WAITING));&lt;br /&gt;    } else {&lt;br /&gt;     setEnable(false);&lt;br /&gt;     finishedListenerManager.notifyListeners();&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void moveCloser() {&lt;br /&gt;  Transform3D transformation = new Transform3D();&lt;br /&gt;  transformGroup.getTransform(transformation);&lt;br /&gt;&lt;br /&gt;  if (isFinished(currentLocation)) {&lt;br /&gt;   atLocation = true;&lt;br /&gt;  } else {&lt;br /&gt;   updatePosition(currentLocation, moveToLocation);&lt;br /&gt;   transformation.set(currentLocation);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  transformGroup.setTransform(transformation);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void updatePosition(Vector3f currentPositionVector, &lt;br /&gt;   Vector3f endingPointVector) {&lt;br /&gt;  float[] currentPosition = new float[3];&lt;br /&gt;  currentPositionVector.get(currentPosition);&lt;br /&gt;  float[] endingPoint = new float[3];&lt;br /&gt;  endingPointVector.get(endingPoint);&lt;br /&gt;&lt;br /&gt;  for (int i = 0; i &lt; currentPosition.length; i++) {&lt;br /&gt;   if (currentPosition[i] &lt; endingPoint[i]) {&lt;br /&gt;    currentPosition[i] += MOVEMENT_SPEED;&lt;br /&gt;   } else if (currentPosition[i] &gt; endingPoint[i]) {&lt;br /&gt;    currentPosition[i] -= 0.1f;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  currentPositionVector.set(currentPosition);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private boolean isFinished(Vector3f currentPositionVector) {&lt;br /&gt;  boolean finished = false;&lt;br /&gt;&lt;br /&gt;  if (currentPositionVector.x &lt;= moveToLocation.x + .1&lt;br /&gt;    &amp;&amp; currentPositionVector.x &gt;= moveToLocation.x - .1) {&lt;br /&gt;   if (currentPositionVector.y &lt;= moveToLocation.y + .1&lt;br /&gt;     &amp;&amp; currentPositionVector.y &gt;= moveToLocation.y - .1) {&lt;br /&gt;    if (currentPositionVector.z &lt;= moveToLocation.z + .1&lt;br /&gt;      &amp;&amp; currentPositionVector.z &gt;= moveToLocation.z - .1) {&lt;br /&gt;     finished = true;&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  return finished;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void addAnimationFinishedListener(&lt;br /&gt;   IListener animationFinishedListener) {&lt;br /&gt;  finishedListenerManager.addListener(&lt;br /&gt;      animationFinishedListener);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Also, since you are specifying whether or not to continue on each iteration you can add listeners to when the animation is finished and notify them.  Here's how I call this class.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; public void animateAlongPath(List&lt;Vector3f&gt; path) {&lt;br /&gt;  this.path = path;&lt;br /&gt;  animateNextStep(getNextStep());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void animateNextStep(Vector3f currentLocation) {&lt;br /&gt;  final Vector3f moveToLocation = getNextStep();&lt;br /&gt;  if (moveToLocation != null) {&lt;br /&gt;   AnimationBehviour animationBehaviour = &lt;br /&gt;      new AnimationBehviour(bounds, transformGroup,&lt;br /&gt;     currentLocation, moveToLocation);&lt;br /&gt;   animationBehaviour.addAnimationFinishedListener(&lt;br /&gt;      new IListener() {&lt;br /&gt;    public void fireEvent() {&lt;br /&gt;     parentGroup.removeChild(animationGroup);&lt;br /&gt;     animateNextStep(moveToLocation);&lt;br /&gt;    }&lt;br /&gt;   });&lt;br /&gt;&lt;br /&gt;   animationGroup.addChild(animationBehaviour);&lt;br /&gt;   parentGroup.addChild(animationGroup);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private Vector3f getNextStep() {&lt;br /&gt;  Vector3f nextStep = null;&lt;br /&gt;  if (pathIndex &lt; path.size()) {&lt;br /&gt;   nextStep = path.get(pathIndex);&lt;br /&gt;   pathIndex++;&lt;br /&gt;  }&lt;br /&gt;  return nextStep;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So the piece will walk through the path of locations specified and when the animation is done for a given step it will notify the next step animation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-6016301898109261663?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/6016301898109261663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/07/animations-in-java-3d.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/6016301898109261663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/6016301898109261663'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/07/animations-in-java-3d.html' title='Animations in Java 3D'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-265305285489179644</id><published>2009-05-23T08:35:00.000-07:00</published><updated>2009-05-23T09:12:51.886-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='integration technique'/><category scheme='http://www.blogger.com/atom/ns#' term='project management'/><category scheme='http://www.blogger.com/atom/ns#' term='web services'/><category scheme='http://www.blogger.com/atom/ns#' term='interface'/><category scheme='http://www.blogger.com/atom/ns#' term='stub'/><title type='text'>The Importance of Stubs</title><content type='html'>Wow, I haven't posted in a while.  I'm still crunching away at the game but a few things have popped up at home that have kept me from spending too much time.  Leaky basements and a new puppies tend to do that I guess. &lt;br /&gt;&lt;br /&gt;Nothing new to report with the game, still just hammering away at the game's user stories.  I did switch over from Continuum to Cruisecontrol for my integrated environment.  I've been trying out git-svn with some success and liking it for the most part.&lt;br /&gt;&lt;br /&gt;So to make this post a bit more interesting I decided to rant about something that I've seen in a couple of teams I've worked with both as a developer and as a coach. The issue is that of having dependencies on other teams for artifacts that are critical to my team's product.  This is especially problematic with larger organizations pushing for an "enterprise" solution - which typically translates into multiple development teams working separately for months trying to configure an off-the-shelf, over-priced product and then throwing everything together in an integration nightmare and regression testing for a period that might out last the actual development time.&lt;br /&gt;&lt;br /&gt;Being responsible for a product that you don't fully control all the moving pieces can be frustrating and at times paralyzing.  But I've found a solution that's produced some good results: &lt;b&gt;create a stub of everything that you depend on but don't control&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;For example, if your team is building a web client that consumes services for all of your back-end work, stub out each of the services that you rely on.  Define an interface that your team and the team building the service can agree upon and build a basic implementation. &lt;br /&gt;&lt;br /&gt;If you're relying on a web service that provides search capabilities, get the WSDL and generate a client and service.  Put just enough implementation into the service to make it functional.  Have it return one of ten result sets based on ten different query strings - something simple but functional as far as inputs and outputs.&lt;br /&gt;&lt;br /&gt;Once you have the stub in place, you can write your automated UATs (User Automated Tests) around your application using the stub and ensure that your application is processing the results correctly.  Once your UATs are in place and you have your continuous integration environment, you can swap in their actual services and just kick off the build to verify the integration.  This should make it fairly painless!&lt;br /&gt;&lt;br /&gt;Now obviously the interfaces can change as the project continues but just make sure that when the changes occur, all dependent teams get an updated version of the interface.  Then it's as simple as regenerating the stub service and client code and making a few adjustments here or there.  Then run the UATs again to ensure that you have integrated the changes correctly so that the behavior of your application is still what the user expects.&lt;br /&gt;&lt;br /&gt;I'm convinced that this practice alone will save large development departments millions of dollars of teams wasting their time trying to throw everything together at the last minute.  And it will probably save developers the stress of the integration nightmare.&lt;br /&gt;&lt;br /&gt;End rant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-265305285489179644?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/265305285489179644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/05/importance-of-stubs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/265305285489179644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/265305285489179644'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/05/importance-of-stubs.html' title='The Importance of Stubs'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-4138933485173788276</id><published>2009-03-28T06:05:00.000-07:00</published><updated>2009-03-28T06:45:20.227-07:00</updated><title type='text'>Make things testable</title><content type='html'>So I was going along with my stories and I realized that there's a bunch of stuff that I am not testing.  In general with an MVP pattern, you make the V as slim as possible because it's really hard to test things in the view.  Can do you write a test that says that your "ok" button actually shows up in the lower right corner of the popup dialog?  So you make it really slim so that you just kinda assume that Swing or SWT knows how to render the stuff correctly to the screen and that you are using the API correctly.  So with that in mind, I went about writing my game... which is mostly stuff in the view.  At this point in the game, there's very little non-view stuff going on.  So I'm not testing a whole bunch and that really bothers me.&lt;br /&gt;&lt;br /&gt;So I started re-evaluating whether or not my view could be tested.  I'm writing this using Java3D which is all java so it should be fairly testable.  In the end, to make something show up, you need to add it to your branch graph.  So I started looking at ways to inject stubs for my branch groups into my objects and see what gets populated.  Unfortunately, Java3D does not code to interfaces.  So I made a bunch of adapters around class that implemented interfaces containing the methods I was using.  Next I created a bunch of factories to make sure that I always got the same sort of adapter wrapping object back.  Then I exposed an interface on the factory and injected that into a few generators that would add my game grid and game pieces.  So once I started pulling this out, I realized that very little of my code is actually Java3D code and it it's all really testable.&lt;br /&gt;&lt;br /&gt;So I guess the lesson that I've learned with this and a few other projects I've worked on is to try to get around the API/Framework/Whatever that you're working with by using interfaces (and adapters where needed) so you can test your own code.&lt;br /&gt;&lt;br /&gt;Here's an example from what I did with the BranchGroup...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IBranchGroup {&lt;br /&gt; void compile();&lt;br /&gt;&lt;br /&gt; void addChild(Node node);&lt;br /&gt;&lt;br /&gt; void addChild(IBranchGroup child);&lt;br /&gt;&lt;br /&gt; BranchGroup getInternal();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class BranchGroupAdapter implements IBranchGroup {&lt;br /&gt; private final BranchGroup branchGroup;&lt;br /&gt;&lt;br /&gt; public BranchGroupAdapter(BranchGroup branchGroup) {&lt;br /&gt;  this.branchGroup = branchGroup;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void compile() {&lt;br /&gt;  branchGroup.compile();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void addChild(Node child) {&lt;br /&gt;  branchGroup.addChild(child);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void addChild(IBranchGroup child) {&lt;br /&gt;  branchGroup.addChild(child.getInternal());&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public BranchGroup getInternal() {&lt;br /&gt;  return branchGroup;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public interface IBranchGroupFactory {&lt;br /&gt; IBranchGroup createBranchGroup();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class BranchGroupFactory implements IBranchGroupFactory {&lt;br /&gt; public BranchGroupAdapter createBranchGroup() {&lt;br /&gt;  return new BranchGroupAdapter(new BranchGroup());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class GameLauncher implements IGameLauncher {&lt;br /&gt; public void launchGame(IUniverse universe, IBranchGroupFactory branchGroupFactory,&lt;br /&gt;   IGameEngineFactory gameEngineFactory) {&lt;br /&gt;  IBranchGroup branchGroup = branchGroupFactory.createBranchGroup();&lt;br /&gt;  IGameEngine gameEngine = gameEngineFactory.createGameEngine(branchGroup);&lt;br /&gt;&lt;br /&gt;  ISelecterFactory selecterFactory = new SelecterFactory(universe);&lt;br /&gt;&lt;br /&gt;  gameEngine.createScene(selecterFactory);&lt;br /&gt;  gameEngine.createCamera(universe);&lt;br /&gt;&lt;br /&gt;  branchGroup.compile();&lt;br /&gt;&lt;br /&gt;  universe.addBranchGraph(branchGroup);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-4138933485173788276?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/4138933485173788276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/03/make-things-testable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/4138933485173788276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/4138933485173788276'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/03/make-things-testable.html' title='Make things testable'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-865458139958017169</id><published>2009-03-14T15:08:00.001-07:00</published><updated>2009-03-14T15:09:07.481-07:00</updated><title type='text'>Managing Your Tests</title><content type='html'>So I've been writing some code for a while and knocking out a few stories and the code base is growing, and so are the tests.  The thing that allows you to refactor and to explore better ways of doing something is having good tests that pass.  And by good tests, I mean that there are both unit tests and integration tests on all classes.  Before you write any code, you have to write a test.  If you find a piece of functionality that you can't test, try pulling it apart or isolating the un-testable portion as much as possible.  I like to think of the tests as a safety net for your code.  The tests describe the behavior of my application and so as long as all the tests pass, the code is free to be massaged into whatever I like.&lt;br /&gt;&lt;br /&gt;However, an interesting issue arrises as the tests grow.  The tests begin to exhibit some code smells.  There's probably some code duplication or possibly some tests that test the same behvavior.  Especially with some extensive integration tests.  Eventually, I start to want to refactor my tests.  Which really makes sense because if you don't maintain your tests they will become unusable and you eventually try to get around them.  So refactoring the tests really is a necessity.&lt;br /&gt;&lt;br /&gt;Now the danger here is, how do you know that you didn't break a test?  I write tests for my code so that I can refactor my code but there is no tests for my tests to ensure that I didn't break the tests.  I can run them against the codebase and ensure that they still pass, but it's easy to get false positivies that way.&lt;br /&gt;&lt;br /&gt;I've been running into this at work recently and I'm trying to find a good principle or something that will ensure the stability of the tests through refactoring.  Unit tests are usually fairly easy to refactor.  The tests themselves are straight forward and you see real easily what they're testing.  Integration tests are not so clear, or at least they can be more challenging.  My advice so far has been to make sure that there is good unit tests before you start refactoring the integration tests and only make small changes at a time and as much as possible verify all the changes all the time.&lt;br /&gt;&lt;br /&gt;If anyone has some other comments or suggestions about what to do for refactoring test, please let me know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-865458139958017169?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/865458139958017169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/03/managing-your-tests.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/865458139958017169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/865458139958017169'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/03/managing-your-tests.html' title='Managing Your Tests'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-6143658688207462758</id><published>2009-02-28T10:30:00.000-08:00</published><updated>2009-02-28T14:48:05.015-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='spike'/><title type='text'>What to do when you don't know what to do</title><content type='html'>The last story that I was working on required me to do some animation in Java3D, which I didn't how to do.  So, I did a little Spike to learn a bit more about what was involved with that, and I finally finished up the story.  With this on my mind, I thought I would spend some time talking about Spikes.&lt;br /&gt;&lt;br /&gt;I think Spikes are one of the most misused parts of Agile.  The general understanding of a Spike is that it is a research story.  If you have questions about how to do your User Story, you spend time researching or spiking the questions that you have.  I've seen different teams handle Spikes in different ways.  The worst I have witnessed are spike stories that drag on from iteration to iteration.  After a time, when something is finally delivered, it's not in a state that is usable, but too much time has been spent on it, so it winds up being put into the code base with no tests, no pair programing, etc.  The best use of a Spike is to only use it when you don't know enough to estimate the story, then you spike until you know just enough to do the story.  Any code that you write to answer those questions are considered "spike code" and you throw it out.  &lt;br /&gt;&lt;br /&gt;One really good practice to get into to avoid spike abuse is to always have your Spikes be time-boxed.  You set a limit on the amount of time you will spend researching.  Once that limit has been reached, the team can then review whether or not they need more time or need to possibly take a different route.  If you can't learn enough within a day or so, to estimate, you really should reevaluate if that technology is worth the time.  If an off the shelf product takes a week's worth of time to "spike" so that you know how to use it, maybe a simpler approach that doesn't involve that product is the better approach.&lt;br /&gt;&lt;br /&gt;I've worked with some people that use the term "Spike" to justify taking a long time to writing crumby code that is meant to be used as a prototype.  Truth is, that when they finally get to the point that they can write that code, they know enough to estimate the actual story and then begin working on it.  Time spent on a spike after you have answered your question is no longer time that should be spent on spiking, but time spent working on the story.&lt;br /&gt;&lt;br /&gt;I've also heard the phrase "architectural spike," which boils down to taking entirely too much time to write up a document to give to the team (that they'll probably never read) describing the solution with many charts and diagrams.  And to me, that just goes against the concept of letting your tests drive your code and letting the design emerge from your refactoring.&lt;br /&gt;&lt;br /&gt;So to recap, spikes are suppose to be a time-boxed (maybe a day) research efforts that answer enough questions so that you can estimate a story.  Anything else, should be your standard test driven development based on satisfying acceptance criteria on your user stories.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-6143658688207462758?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/6143658688207462758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/what-to-do-when-you-dont-know-what-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/6143658688207462758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/6143658688207462758'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/what-to-do-when-you-dont-know-what-to.html' title='What to do when you don&apos;t know what to do'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-2162024045975117036</id><published>2009-02-21T15:05:00.001-08:00</published><updated>2009-02-21T16:00:09.166-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Java3D'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'></title><content type='html'>Alright, so I blew through the first two stores that I was attempting:&lt;br /&gt;&lt;br /&gt;1.  User opens the application and sees the game board.  Game board is a chess board (8 x 8 - alternating black and white squares) background is a gray.   Camera is looking at the center from above and toward one side.&lt;br /&gt;&lt;br /&gt;2.  The user has one piece (a blue ball) on the board that is located on one side of the board on one of the center squares.&lt;br /&gt;&lt;br /&gt;And up until now there was really no design to it.  I started coding a class that had the capability of drawing on the 3D canvas and just kept going.  Neither of these stories contain any user interaction yet so I was having a hard time coming up with testable code.&lt;br /&gt;&lt;br /&gt;I eventually saw that there was a bit of logic needed for creating the checkered game board.  So I thought I'd extract out something that would need to know how to do that.  So I started going into an MVP pattern.  I wanted the view to get something that it could use to create the proper rows and columns with the right alternating colors without too much logic.  It wound up looking like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public void constructGrid(GameGridData data) {&lt;br /&gt; for (int x = 0; x &lt; data.getTileData().length; x++) {&lt;br /&gt;  for (int z = 0; z &lt; data.getTileData()[0].length; z++) {&lt;br /&gt;   Tile tile = new Tile(data.getTileData()[x][z]);&lt;br /&gt;   board.addChild(tile);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;i&gt;Tile&lt;/i&gt; class was an abstraction I had done to encapsulate the creation of the geometry and details of creating the individual squares.  The &lt;i&gt;TileData&lt;/i&gt; is a bean that I had to construct to keep the back-end models from knowing anything about the Java3D APIs.  The &lt;i&gt;GameGridData&lt;/i&gt; has the algorithm needed to get all the positions and colors in the right data structure (the &lt;i&gt;TileData&lt;/i&gt; bean) that the view needed.  I have a feeling that GameGridData may morph into an abstract class where subclasses will be specific for Chess boards or terrain looking grids or vast spans of black space.  Once that was all pulled apart, I was able to construct a Model that generated these &lt;i&gt;TileData&lt;/i&gt; beans and a Presenter that could communicate between the two. &lt;br /&gt;&lt;br /&gt;Now what I have is a bunch of smaller classes that don't contain "view code" all of which are very testable!  So that's where the first real signs of a design started to form.  I had a need to be able to test what I was doing and no real good way of isolating the code that needed testing.  So by separating out what was just calls to the framework's API (or my abstractions around the framework) and the logic needed for the correct calls, I was able to write a few tests and get things a bit more agile.&lt;br /&gt;&lt;br /&gt;The third story actually got me into some user interaction:&lt;br /&gt;&lt;br /&gt;3.  The user can select a square on the board and the ball will move to that square.  Movement is shown and not just a sudden change in location.&lt;br /&gt;&lt;br /&gt;Selecting an object in Java3D is a bit more complicated than in Swing.  Picking an object is basically translating a point that your mouse picked on the screen to a ray or cone that extends from the point down into the canvas and then seeing what objects intersect with that ray or cone.  So my abstractions around the actual tiles in the grid by my Tile class paid off when I found out that the API will return the Node or Shape3D object that was in the intersection path.  So I was able to retrieve the same &lt;i&gt;TileData&lt;/i&gt; bean that I used to create the selected Tile object and then notify the presenters that are listening to the view.&lt;br /&gt;&lt;br /&gt;And this is what it wound up looking like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;final PickCanvas pickCanvas = new PickCanvas(canvas3D, board);&lt;br /&gt;pickCanvas.setMode(PickInfo.PICK_GEOMETRY);&lt;br /&gt;pickCanvas.setTolerance(4.0f);&lt;br /&gt;&lt;br /&gt;canvas3D.addMouseListener(new MouseAdapter() {&lt;br /&gt; @Override&lt;br /&gt; public void mouseClicked(MouseEvent mouseEvent) {&lt;br /&gt;  pickCanvas.setShapeLocation(mouseEvent);&lt;br /&gt;  PickInfo pickClosest = pickCanvas.pickClosest();&lt;br /&gt;  if (pickClosest != null) {&lt;br /&gt;   Tile tile = (Tile) pickClosest.getNode();&lt;br /&gt;   selectedTile = tile.getTileData();&lt;br /&gt;   tileSelectedListeners.notifyListeners();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So then I needed a way to move the user's game piece once the position selection took place.  I made some similar refactorings to the code that created the user's piece with a MVP pattern.  And then I let the model from the game grid and the model from the user piece be able to communicate with each other.  And then the piece model notified it's presenter which in turn told the view to move the piece to the correct location.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public UserPieceModel(final IGameGridModel gameGridModel) {&lt;br /&gt; gameGridModel.addPositionSelectedListener(new IListener() {&lt;br /&gt;  public void fireEvent() {&lt;br /&gt;   currentPosition = gameGridModel.getSelectedPosition();&lt;br /&gt;   adjustCurrentPositionForHeight();&lt;br /&gt;   modelListenerManager.notifyListeners();&lt;br /&gt;  }&lt;br /&gt; });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So this story is just about wrapped up.  I currently just have the user's piece suddenly jumping to the new location but the story has some more specific requirements: "Movement is shown and not just a sudden change in location"  I made it that way intentionally because I know nothing of Java3D's animation APIs.  So now I'm just doing a quick spike to determine how to do that and then I'll be able to finish this story up and move on to the next.&lt;br /&gt;&lt;br /&gt;So overall I think things are progressing nicely.  I wasn't liking where this was going at first with a whole bunch of un-testable UI code but now it seems like I've got the start of a design that allows me to test what I'm creating.  And really that's the point of this blog.  I called it &lt;i&gt;Emergent Development&lt;/i&gt; because that's what good software development should be.  You start going and you realize you need something so that you can make it more testable, more loosely coupled, more flexible and so you interject a pattern or two so you can test your stuff and just keep going.  So your design comes from need not from a over thought-out UML diagram that was created long before any real code started.  Design comes as you need it, no sooner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-2162024045975117036?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/2162024045975117036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/alright-so-i-blew-through-first-two.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/2162024045975117036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/2162024045975117036'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/alright-so-i-blew-through-first-two.html' title=''/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-7562057178198083143</id><published>2009-02-14T08:12:00.000-08:00</published><updated>2009-02-14T09:08:23.154-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='MVP'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI application'/><category scheme='http://www.blogger.com/atom/ns#' term='TDD'/><title type='text'>Doing a GUI application using TDD</title><content type='html'>Testing user interfaces is always a pain point when doing TDD GUI apps.  Web development has been able to get around this a bit with automated UAT testing using tools like Selenium or Watir.  But with GUI apps, there's no really good, cheap (as in free) UAT tools (if anyone knows of one, please let me know!!!).&lt;br /&gt;&lt;br /&gt;So when I create a GUI app I use a MVP pattern where the View is really, really thin because it's just impossible to right good tests around it.  In the past with Swing and SWT/RCP application, I've been able to have the view be fairly simple with an exposed getter/setter-ish API on it so that the Presenter can be tested on how it manipulates the View and the Model can have it's own tests for the business rules and that leaves not a whole bunch to test in the View.  You don't really need tests for the implementat of view.getUsername() when all it does is read the text from a text field.&lt;br /&gt;&lt;br /&gt;Here's a sample login MVP of what I'm talking about...&lt;br /&gt;(I didn't compile this so don't complain if it doesn't actually work)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Presenter {&lt;br /&gt;    public MyPresenter(final IView view, final IModel model) {&lt;br /&gt;        view.addLoginListener(new IListener() {&lt;br /&gt;            public void fireEvent() {&lt;br /&gt;                try {&lt;br /&gt;                    model.authenticate(view.getUsername(), &lt;br /&gt;                        view.getPassword());&lt;br /&gt;                } catch (AuthenticationException e) {&lt;br /&gt;                    view.showErrorMessage(e.getMessage());&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        });&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The API exposed on the view is real simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IView {&lt;br /&gt;  void addLoginListener(IListener listener);&lt;br /&gt;  String getUsername();&lt;br /&gt;  String getPassword();&lt;br /&gt;  void showErrorMessage(String errorMessage);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the API on the model is real simple too:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface IModel {&lt;br /&gt;    String authenticate(String username, String password) &lt;br /&gt;        throws AuthenticationException;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So this example makes the presenter very testable.  And it separates out the need to know how the stuff is displayed to the user verses and how the actual authentication needs to happen.  And the model is is left with a single responsibility and a very simple API.  So testing the model is now real easy also.  And the view now has no complicated functionality.&lt;br /&gt;&lt;br /&gt;Even if you wanted to have some fields in the view that enable or disable based on options that the user has selected in other parts of the view, you can create another MVP triad for that and you could have another interface for that the view implements that might have some methods that look like this...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    void enableSubmitButton();&lt;br /&gt;    void disableSubmitButton();&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;So the View doesn't even know what the state of the submit button is.  It just knows how to enable or disable the field.  Again, all the logic can go off to a Model so that it is testable and the Presenter just acts as a mediator between the View and Model interfaces which keeps the Presenter really testable.&lt;br /&gt;&lt;br /&gt;As a general rule of thumb, you write a test for anything that could possibly break.  And at the point of where this view is at, what would you be testing?  That Swing is working?  You shouldn't be testing their code, just yours.&lt;br /&gt;&lt;br /&gt;Now in my game, I'm using Java3D for my "View" so that's going to be a fairly complicated piece that needs to be split as thin as possible to provide testability.  Because really that should be your goal: how can I make this code testable?  If I abstract something out and hide it behind an interface and inject it in, I can test my classes better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-7562057178198083143?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/7562057178198083143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/doing-gui-application-using-tdd.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7562057178198083143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7562057178198083143'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/doing-gui-application-using-tdd.html' title='Doing a GUI application using TDD'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-7273495095022510887</id><published>2009-02-09T15:20:00.001-08:00</published><updated>2009-02-09T15:45:22.540-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='Java3D'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='continuum'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='continuous integration'/><title type='text'>Setuping up the Project</title><content type='html'>Ok, so I &lt;span style="font-size:100%;"&gt;have a rough idea for the end result of my game and I started to write up some user stories.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Main Concept:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;This is a board game where two players have a set of "pieces" that they can move around the board and attack the other player's pieces.  The moves will be turn based: each turn the player gets to move one piece and cause one piece to perform an action.  Actions may attack the other teams pieces which will may result in the termination of the attacked piece.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Ok, I'm hoping that with a little modification the game platform can provide the functionality for both a chess game and a Final Fantasy Tactics (great game by Squaresoft fyi for those who haven't played) style game.&lt;br /&gt;&lt;br /&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt; &lt;span style="font-weight: bold;"&gt;User Stories:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;User opens the application and sees the game board.  Game board is a chess board (8 x 8 - alternating black and white squares) background is a gray.   Camera is looking at the center from above and toward one side.&lt;br /&gt;&lt;br /&gt;The user has one piece (a blue ball) on the board that is located on one side of the board.&lt;br /&gt;&lt;br /&gt;The user can select a square on the board and the ball will move to that square.  Movement is shown and not just a sudden change in location.&lt;br /&gt;&lt;br /&gt;All movements are logged.&lt;br /&gt;&lt;br /&gt;User can have eight balls.  To move one, the user must select the ball to move first, then select where to move the piece.&lt;br /&gt;&lt;br /&gt;The opponent will have 8 pieces also but of a different color.&lt;br /&gt;&lt;br /&gt;User cannot move onto a square that is already occupied.&lt;br /&gt;&lt;br /&gt;After the user moves a piece, the opponent will move one of its pieces in a random direction (no piece can move off of the board).&lt;br /&gt;&lt;br /&gt;Pieces can move up to three square away.&lt;br /&gt;&lt;br /&gt;When a user selects a piece to be moved, the squares that are within range will change color to indicate the possible ending positions for that piece.  Attempts to move to a square that is not showing the indication is ignored.&lt;br /&gt;&lt;br /&gt;User can choose to attack a piece belonging to the opponent if that piece is within 2 squares from the user's piece.  To attack, the user selects the piece that they wish to attack with, then select the opponent's piece that is the target.  The attack is logged.&lt;br /&gt;&lt;br /&gt;Attacks are logged to the same log that the movements were logged.&lt;br /&gt;&lt;br /&gt;Some visual representation of an attack between two pieces is shown.&lt;br /&gt;&lt;br /&gt;Pieces have a sense of "health".  Each piece can take two attacks before it is destroyed.  Destroyed pieces simply disappear from the board.&lt;br /&gt;&lt;br /&gt;Add an indicator for the health of the piece.&lt;br /&gt;&lt;br /&gt;The pieces can be of different types:&lt;br /&gt;- large, can only move 1 spaces but takes 3 hits to destroy&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;    - medium, can move 2 and takes 2 hits to destroy&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;    - small, can move 3 and takes 1 hit to destroy&lt;br /&gt;&lt;br /&gt;Balls bounce in place while they wait their move.&lt;br /&gt;&lt;br /&gt;The smaller the ball, the faster it bounces.&lt;br /&gt;&lt;br /&gt;The pieces can be loaded in from an external model(s) - maybe spaceships.&lt;br /&gt;&lt;br /&gt;When the game starts, the user can choose to play the CPU or play another player.&lt;br /&gt;&lt;br /&gt;Network enabled games.&lt;br /&gt;&lt;br /&gt;The user's stats are kept from game to game: wins, losses.&lt;br /&gt;&lt;br /&gt;When the user starts the game they are asked who they &lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;are&lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt; (username) so as to keep building on their stats.&lt;br /&gt;&lt;br /&gt;The user's pieces' stats are kept: number of opponent pieces destroyed&lt;br /&gt;&lt;br /&gt;Piece rank based on number of opponent pieces destroyed.&lt;br /&gt;&lt;br /&gt;Upgradeable pieces based on number of opponent pieces destroyed.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's a small backlog and it'll grow.  And the stories that are further out are a bit more vague, but they'll become more clear when they start coming to the front.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Starting Development&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the meantime, I decided to setup my continuous integration environment.  I am developing this in Java (the graphics done in Java3D) using Maven for my build and Continuum for my continuous integration.  Java was chosen because I know it the best and I'm a bit more familiar with Java3D than other 3D programming APIs.  Maven was chosen for the use of it's dependency management.  I've written a couple of standalone applications in the past and I've refactored out some useful tools dealing with things like error handling and whatnot.  And with Maven, it's real easy to include the dependency in the pom and not have to worry about it.&lt;br /&gt;&lt;br /&gt;So I got the project all setup with automated builds going and email notifications upon failure.  I really think that this is crucial for any project starting up.  Get your CI environment up and running.  Now I don't have any other developers joining my project at the moment, but non-the-less, it is vital to make sure that whatever you have in your repository is stable (tests pass) at all times.&lt;br /&gt;&lt;br /&gt;Interesting bit on the email notifications... GMail has been gracious enough to allow external smtp access to their servers.  So it made setting up the mail notifications really simple.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And now I'm all ready to start tackling the first story...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-7273495095022510887?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/7273495095022510887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/ok-so-i-have-rough-idea-for-end-result.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7273495095022510887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/7273495095022510887'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/ok-so-i-have-rough-idea-for-end-result.html' title='Setuping up the Project'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032662264988669481.post-877056196122471750</id><published>2009-02-07T10:16:00.001-08:00</published><updated>2009-02-07T10:30:01.105-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Starting to blog...</title><content type='html'>So I've been told that blogs are good to get your ideas down and let others comment and possibly help you out occasionally.  So here's my go at it.  I'm a software engineer by trade and by hobby.  I've been indoctrinated into the Agile software methodologies and I'm starting to put them into practice, not just at work where we're required to, but at home in my little side projects.&lt;br /&gt;&lt;br /&gt;So I also have a hobby of videogaming and that tends to creep its way into my hobby of writing software.  I've had grand schemes of writing the most amazing game that's interesting, replayable, exensible and just generally really fun.  So I've had several failed attempts and I keep them all in my local SVN repo and occassionally dig them out and remember why I stopped that approach.&lt;br /&gt;&lt;br /&gt;I think the reason why I fail most often in my attempts is that I try to do too much.  In Agile terms, my stories are entirely too big.  So I've decided that I need a backlog of stories that I can massage down to what would be doable and then focus on each one and get a sence of accomplishment and direction of where I'm going next.  I've also decided to scale down the scope of my game.  For the moment, it will involve moving pieces around a board and possibly taking your opponents pieces.  Sounds very checkeredy but I figure that if I can start there, I can build uppon it.  Maybe make it multiplayer, then make it networkable, then be able to load in different pieces, then make the board changeable.  Then maybe I can pull out a framework that would allow me to create great extensible game that I know everyone will love and want to play!  ... maybe...&lt;br /&gt;&lt;br /&gt;Ok, first things first.  Gotta get a backlog to work with.  In order to do that, I need a good game concept.  So that will be this weeks task.  Some sort of game concept and the beginning of a backlog.  And next week I'll plan on doing a release planning and start in on the fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9032662264988669481-877056196122471750?l=emergentdevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://emergentdevelopment.blogspot.com/feeds/877056196122471750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/starting-to-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/877056196122471750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032662264988669481/posts/default/877056196122471750'/><link rel='alternate' type='text/html' href='http://emergentdevelopment.blogspot.com/2009/02/starting-to-blog.html' title='Starting to blog...'/><author><name>Matt Todd</name><uri>https://profiles.google.com/114019760492346729255</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-UMaKvXlLkeo/AAAAAAAAAAI/AAAAAAAAARY/87oCaBGCgi8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
