<?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-4341974800055505897</id><updated>2011-11-27T16:07:35.721-08:00</updated><category term='ruby java jruby'/><category term='acm'/><category term='ruby'/><category term='cocoa'/><category term='c++ design'/><category term='android'/><category term='java ejb'/><category term='java'/><category term='python'/><category term='java apache'/><category term='database'/><title type='text'>Eventual Consistency</title><subtitle type='html'>Check your consistent state at the door, we're all full here.  Unless you want to fund a startup, then the drinks are to the left.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>46</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-4124615349884211963</id><published>2009-09-27T04:44:00.000-07:00</published><updated>2009-09-27T04:56:42.937-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Developing in Android without Eclipse</title><content type='html'>Recently I'm back in java land, more specifically android.  The past few months I've exclusively been doing scripting languages using much more primitive editors (textmate, emacs).  Going back to java, I'm finding Eclipse is just getting in my way.   So I decided to try and develop an android app using textmate and found it incredibly easy.   It appears you have everything you need from the command line tools and all the eclipse plugin does is interface with those.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 1, create your project&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;THis couldn't be easier:&lt;br /&gt;&lt;br /&gt;android create project --target 2 --name install_test --path . --activity InstallTest --package com.jonandkerry.install&lt;br /&gt;&lt;br /&gt;Obviously make sure your android sdk is in your path.  NOTE: if you are using SNow leopard you will need to patch your android install.  See here &lt;a href="http://michaelpardo.com/2009/09/ddms-for-android-sdk-1-6-on-snow-leopard/"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 2, build your project&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The android create project tool actually builds you a very simple java skeleton project with an ant build.xml.  You get several targets:&lt;br /&gt;&lt;br /&gt; aidl&lt;br /&gt; android_rules.aidl&lt;br /&gt; android_rules.compile&lt;br /&gt; android_rules.debug&lt;br /&gt; android_rules.debug-sign&lt;br /&gt; android_rules.dex&lt;br /&gt; android_rules.dirs&lt;br /&gt; android_rules.help&lt;br /&gt; android_rules.install&lt;br /&gt; android_rules.no-sign&lt;br /&gt; android_rules.package&lt;br /&gt; android_rules.package-resources&lt;br /&gt; android_rules.release&lt;br /&gt; android_rules.release-package&lt;br /&gt; android_rules.release.check&lt;br /&gt; android_rules.release.nosign&lt;br /&gt; android_rules.resource-src&lt;br /&gt; android_rules.uninstall&lt;br /&gt; android_rules.uninstall.check&lt;br /&gt; android_rules.uninstall.error&lt;br /&gt; compile&lt;br /&gt; debug&lt;br /&gt; debug-sign&lt;br /&gt; dex&lt;br /&gt; dirs&lt;br /&gt; help&lt;br /&gt; install&lt;br /&gt; no-sign&lt;br /&gt; package&lt;br /&gt; package-resources&lt;br /&gt; release&lt;br /&gt; release-package&lt;br /&gt; release.check&lt;br /&gt; release.nosign&lt;br /&gt; resource-src&lt;br /&gt; uninstall&lt;br /&gt; uninstall.check&lt;br /&gt; uninstall.error&lt;br /&gt;Default target: help&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;obviously you see and "ant compile", "ant install", etc. &lt;span style="font-weight:bold;"&gt; Its important to note that ant compile will generate the R.java resource just like eclipse does.  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Step 3, run&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Couldn't be easier.  &lt;br /&gt;&lt;br /&gt;$ ant install&lt;br /&gt;Buildfile: build.xml&lt;br /&gt;    [setup] Project Target: Android 1.6&lt;br /&gt;    [setup] API level: 4&lt;br /&gt;&lt;br /&gt;dirs:&lt;br /&gt;     [echo] Creating output directories if needed...&lt;br /&gt;&lt;br /&gt;resource-src:&lt;br /&gt;     [echo] Generating R.java / Manifest.java from the resources...&lt;br /&gt;     [exec]     (skipping hidden file '/Users/jonathan/Development/personal/install_test/res/.DS_Store')&lt;br /&gt;     [exec]     (skipping hidden file '/Users/jonathan/Development/personal/install_test/res/layout/.DS_Store')&lt;br /&gt;&lt;br /&gt;aidl:&lt;br /&gt;     [echo] Compiling aidl files into Java classes...&lt;br /&gt;&lt;br /&gt;compile:&lt;br /&gt;    [javac] Compiling 1 source file to /Users/jonathan/Development/personal/install_test/bin/classes&lt;br /&gt;&lt;br /&gt;dex:&lt;br /&gt;     [echo] Converting compiled files and external libraries into bin/classes.dex...&lt;br /&gt;&lt;br /&gt;package-resources:&lt;br /&gt;     [echo] Packaging resources&lt;br /&gt; [aaptexec] Creating full resource package...&lt;br /&gt;     [null]     (skipping hidden file '/Users/jonathan/Development/personal/install_test/res/.DS_Store')&lt;br /&gt;     [null]     (skipping hidden file '/Users/jonathan/Development/personal/install_test/res/layout/.DS_Store')&lt;br /&gt;&lt;br /&gt;debug-sign:&lt;br /&gt;&lt;br /&gt;package:&lt;br /&gt;[apkbuilder] Creating install_test-debug-unaligned.apk and signing it with a debug key...&lt;br /&gt;[apkbuilder] Using keystore: /Users/jonathan/.android/debug.keystore&lt;br /&gt;[apkbuilder] /Users/jonathan/Development/personal/install_test/bin/classes.dex =&gt; classes.dex&lt;br /&gt;&lt;br /&gt;debug:&lt;br /&gt;     [echo] Running zip align on final apk...&lt;br /&gt;     [echo] Debug Package: bin/install_test-debug.apk&lt;br /&gt;&lt;br /&gt;install:&lt;br /&gt;     [echo] Installing bin/install_test-debug.apk onto default emulator...&lt;br /&gt;     [exec] 317 KB/s (10728 bytes in 0.032s)&lt;br /&gt;     [exec]  pkg: /data/local/tmp/install_test-debug.apk&lt;br /&gt;     [exec] Success&lt;br /&gt;&lt;br /&gt;BUILD SUCCESSFUL&lt;br /&gt;Total time: 5 seconds&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And there you go.  To be honest, I'd much rather run this stuff from the command line than watch the spinning beach ball in eclipse.  &lt;br /&gt;&lt;br /&gt;For more things you can do, see the official documentation:&lt;br /&gt;&lt;a href="http://developer.android.com/guide/developing/other-ide.html"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And also, there is a textmate plugin that simply runs a few of these tasks:&lt;br /&gt;&lt;a href="http://github.com/geoffb/android-tmbundle"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-4124615349884211963?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/4124615349884211963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=4124615349884211963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4124615349884211963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4124615349884211963'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/09/developing-in-android-without-eclipse.html' title='Developing in Android without Eclipse'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-8841952064312987093</id><published>2009-09-25T13:19:00.000-07:00</published><updated>2009-09-25T13:22:19.123-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Installing packages in Android</title><content type='html'>I've been playing around with Android quite a bit lately.  One really cool thing is you can write a package (package == application) that can install other applications.  Obviously this isn't done silently.  A UI will be presented to the user asking them if they want to install this package and info about it.  &lt;br /&gt;&lt;br /&gt;Its basically done by sending an intent.&lt;br /&gt;&lt;br /&gt;Intent intent = new Intent(Intent.VIEW); &lt;br /&gt;intent.setDataAndType(Uri.parse("The url to your package"), "application/ &lt;br /&gt;vnd.android.package-archive"); &lt;br /&gt;startActivity(intent); &lt;br /&gt;&lt;br /&gt;And there you go.  Obviously of you want to to be notified when its complete you can also do a startActivityWithResponse call.  I see this as being very powerful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-8841952064312987093?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/8841952064312987093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=8841952064312987093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/8841952064312987093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/8841952064312987093'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/09/installing-packages-in-android.html' title='Installing packages in Android'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3820730700083139031</id><published>2009-07-27T02:53:00.000-07:00</published><updated>2009-07-27T02:55:59.566-07:00</updated><title type='text'>Interesting opportunities</title><content type='html'>On Monday Techcrunch released this story:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://shar.es/xYpF"&gt;Justin.tv Opens Its API For Free, Hopes Live Video Will Explode - http://shar.es/xYpF&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I don't have much experience in JustinTV except for the few events I've been to that have used it.  From my understanding its like a YouTube but live video rather than uploaded and downloaded.  I can't help but see the opportunities in this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3820730700083139031?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3820730700083139031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3820730700083139031' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3820730700083139031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3820730700083139031'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/07/interesting-oportunities.html' title='Interesting opportunities'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5899394280319364696</id><published>2009-07-21T01:32:00.000-07:00</published><updated>2009-07-21T01:35:28.318-07:00</updated><title type='text'>Venture Capital Investment Stabilizes, sort of</title><content type='html'>&lt;a href="http://www.techcrunch.com/2009/07/20/venture-capital-dollars-stabilize-in-second-quarter-at-mid-1990s-levels/"&gt;Venture Capital Dollars Stabilize in Second Quarter at Mid-1990s Levels&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The above article shows the first increase in VC deals in a while.  While the internet and clean tech are still floundering it appears VCs are all about biotech and medical devices these days.  I knew I should have paid more attention in biology.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5899394280319364696?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5899394280319364696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5899394280319364696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5899394280319364696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5899394280319364696'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/07/venture-capital-investment-stabilizes.html' title='Venture Capital Investment Stabilizes, sort of'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-206933441593375218</id><published>2009-07-14T11:24:00.001-07:00</published><updated>2009-07-14T11:24:39.101-07:00</updated><title type='text'>Joining technorati</title><content type='html'>Yes I'm joining technorati, ignore this&lt;br /&gt;&lt;br /&gt;xfkq4bzcgs&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-206933441593375218?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/206933441593375218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=206933441593375218' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/206933441593375218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/206933441593375218'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/07/joining-technorati.html' title='Joining technorati'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3992761836485666013</id><published>2009-01-20T07:09:00.000-08:00</published><updated>2009-01-20T07:12:32.046-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java apache'/><title type='text'>Apache Camel TLP at Apache</title><content type='html'>Apache Camel was just upgraded to a top-level project.  If you haven't played around with Camel you really should check it out.  It abstracts any jms messaging bus and gives you a pretty interface to use cookie-cutter enterprise integration patterns.  When looking at some of the patterns alarms go off on how many times I've had to hack them out on my own.  Great tool to have in your pocket.&lt;br /&gt;&lt;br /&gt;http://camel.apache.org/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3992761836485666013?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3992761836485666013/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3992761836485666013' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3992761836485666013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3992761836485666013'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2009/01/apache-camel-tlp-at-apache.html' title='Apache Camel TLP at Apache'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-4480822335325596705</id><published>2008-12-02T19:10:00.000-08:00</published><updated>2009-01-19T12:49:31.962-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Cherrypy + Routes with mod_wsgi</title><content type='html'>If you haven't played around with deploying your python apps using mod_wsgi, I highly recommend it.  It is a very stable way to deploy your application that takes advantage of the good parts of the apache2 runtime. &lt;br /&gt;&lt;br /&gt;Vanilla Cherrypy apps run great as wsgi applications.  However, I did come across a problem when deploying a Cherrypy app with Routes.  Running the application using the cherrypy server worked fine, but deploying it using apache2 + mod_wsgi always gave me the following on every request:&lt;br /&gt;&lt;br /&gt;503 Service Unavailable&lt;br /&gt;&lt;br /&gt;The CherryPy engine has stopped.&lt;br /&gt;&lt;br /&gt;After some looking around the mod_wsgi project (which is well documented I must say) I found the answer here:  http://code.google.com/p/modwsgi/wiki/IntegrationWithCherryPy&lt;br /&gt;&lt;br /&gt;When running a Cherrypy app with the routes dispatcher you need to make sure you call:&lt;br /&gt;&lt;br /&gt;cherrypy.engine.start(blocking=False)&lt;br /&gt;&lt;br /&gt;After mounting your app.  This sets the cherrypy engine state to running.  After doing this everything worked great and I now have beautiful restful routes in my mod_wsgi app.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-4480822335325596705?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/4480822335325596705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=4480822335325596705' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4480822335325596705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4480822335325596705'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/12/cherrypy-routes-with-modwsgi.html' title='Cherrypy + Routes with mod_wsgi'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-2038597064117758334</id><published>2008-11-21T18:15:00.000-08:00</published><updated>2009-01-19T12:49:31.963-08:00</updated><title type='text'>REST with cherrypy</title><content type='html'>I've been doing web services for a while.  And while SOAP definitively has its place, if you control both sites of the web service REST can really make life easier.  Cherrypy with Python Routes pretty much makes this trivial.  Obviously everyone knows how to route gets, but what about the nasty post and put (REST talk for create and update).  NO problem.&lt;br /&gt;&lt;br /&gt;&lt;preformat&gt;&lt;br /&gt;   d = cherrypy.dispatch.RoutesDispatcher()&lt;br /&gt;&lt;br /&gt;   d.connect('create_something', '/something', controller=root.something_controller, action='create_something',conditions=dict(method=['POST']))&lt;br /&gt;&lt;/preformat&gt;&lt;br /&gt;What this is saying is I want a to route all routes that match /something and are of the method "POST" to the controller root.something_controller and the method "create_something".  Thats it.  PUT is just as easy.&lt;br /&gt;&lt;preformat&gt;&lt;br /&gt;   d.connect('create_something', '/something/:id', controller=root.something_controller, action='update_something',conditions=dict(method=['PUT']))&lt;br /&gt;&lt;/preformat&gt;&lt;br /&gt;Same thing as above except the method update_something will get the param id.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-2038597064117758334?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/2038597064117758334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=2038597064117758334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2038597064117758334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2038597064117758334'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/11/rest-with-cherrypy.html' title='REST with cherrypy'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3786383665955536058</id><published>2008-10-05T05:23:00.000-07:00</published><updated>2009-01-19T12:49:31.963-08:00</updated><title type='text'>routes with Cherrypy</title><content type='html'>As I posted earlier, my new favorite web framework is &lt;a href="http://www.cherrypy.org"&gt;cherrypy&lt;/a&gt;.  I love its simplicity and the fact that I'm not wrestling with magic to do exactly what I want to do.  One bug knock against cherry py is its routing mechansim.  By default it uses an object reference routing, so take the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class HelloWorld()&lt;br /&gt;    def index(self):&lt;br /&gt;        return "&lt;h3&gt;Welcome&lt;/h3&gt;"&lt;br /&gt;   &lt;br /&gt;    def say_hello(self):&lt;br /&gt;        return "&lt;h3&gt;Hello World!&lt;/h3&gt;"&lt;br /&gt;&lt;br /&gt;class Root(object):&lt;br /&gt;   &lt;br /&gt;    hello = HelloWorld()&lt;br /&gt;&lt;pre&gt;&lt;span class="p_identifier"&gt;app&lt;/span&gt; &lt;span class="p_operator"&gt;=&lt;/span&gt; &lt;span class="p_identifier"&gt;&lt;span class="searchword0"&gt;cherrypy&lt;/span&gt;&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;tree&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;mount&lt;/span&gt;&lt;span class="p_operator"&gt;(Root()&lt;/span&gt;&lt;span class="p_operator"&gt;,&lt;/span&gt; &lt;span class="p_identifier"&gt;config&lt;/span&gt;&lt;span class="p_operator"&gt;=&lt;/span&gt;&lt;span class="p_identifier"&gt;conf&lt;/span&gt;&lt;span class="p_operator"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="p_identifier"&gt;&lt;span class="searchword0"&gt;cherrypy&lt;/span&gt;&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;quickstart&lt;/span&gt;&lt;span class="p_operator"&gt;(&lt;/span&gt;&lt;span class="p_identifier"&gt;app&lt;/span&gt;&lt;span class="p_operator"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice that our Root object creates a controller as a member var called hello.  By default the way we would have a browser call the "say hello" method is by:&lt;br /&gt;&lt;br /&gt;http://127.0.0.1:8080/hello/say_hello&lt;br /&gt;&lt;br /&gt;This is fine and simple, but as we all know in the world of search engine optimization you have to put as much into your urls as you do your content.   This is why things like swimlanes and routes in frameworks such as rails and Servlets are so important.  Not to fear becase you can do this in cherrypy also. &lt;br /&gt;&lt;br /&gt;Cherrypy pretty much allows you to drop in any request dispatching mechanism you want.  Thats the whole point of cherrypy is it completly stays out of your way so you can build the exact webapp you want.  If you want to use the &lt;a href="http://routes.groovie.org/"&gt;python routes package&lt;/a&gt;, go a ahead.  If you want to write you own, more power to you.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tools.cherrypy.org/wiki/RoutesUrlGeneration"&gt;Here is a tutorial on using routes with cherrypy.  &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Quickly, just by adding the following lines to the code where I start my cherrypy app:&lt;br /&gt;&lt;pre&gt; &lt;span class="p_identifier"&gt;d&lt;/span&gt; &lt;span class="p_operator"&gt;=&lt;/span&gt; &lt;span class="p_identifier"&gt;&lt;span class="searchword0"&gt;cherrypy&lt;/span&gt;&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;dispatch&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;&lt;span class="searchword1"&gt;Routes&lt;/span&gt;Dispatcher&lt;/span&gt;&lt;span class="p_operator"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="p_identifier"&gt;d&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;connect&lt;/span&gt;&lt;span class="p_operator"&gt;(&lt;/span&gt;&lt;span class="p_character"&gt;'blog'&lt;/span&gt;&lt;span class="p_operator"&gt;,&lt;/span&gt; &lt;span class="p_character"&gt;'helloworld/&lt;/span&gt;&lt;span class="p_operator"&gt;,&lt;/span&gt; &lt;span class="p_identifier"&gt;controller&lt;/span&gt;&lt;span class="p_operator"&gt;=Root.hello&lt;/span&gt;&lt;span class="p_operator"&gt;, action="say_hello")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And I now get routes style power!&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/4341974800055505897-3786383665955536058?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3786383665955536058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3786383665955536058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3786383665955536058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3786383665955536058'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/10/routes-with-cherrypy.html' title='routes with Cherrypy'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-4169585128436915974</id><published>2008-10-02T03:41:00.000-07:00</published><updated>2009-01-19T12:49:31.964-08:00</updated><title type='text'>python and sweet cherrypy</title><content type='html'>I've been doing a lot of python sever-side programming lately, and I really like it.  One diamond in the rough I've found is Cherrypy (http://www.cherrypy.com).   Cherrypy is a very lightweight and pythonic web framework that does the bare-minimum needed to get you up and running with a model/view controller framework.  After that its all up to you and it pretty much stays out of your way.&lt;br /&gt;&lt;br /&gt;At its basic cherrypy is really just an application.  They do include an http server that runs pretty well, and you can also run your app as a mod_wsgi or mod_python app.&lt;br /&gt;&lt;br /&gt;Lets write hello world:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="p_word"&gt;import&lt;/span&gt; &lt;span class="p_identifier"&gt;cherrypy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="p_word"&gt;class&lt;/span&gt; &lt;span class="p_classname"&gt;HelloWorld&lt;/span&gt;&lt;span class="p_operator"&gt;(&lt;/span&gt;&lt;span class="p_identifier"&gt;object&lt;/span&gt;&lt;span class="p_operator"&gt;):&lt;/span&gt;&lt;br /&gt;  &lt;span class="p_word"&gt;def&lt;/span&gt; &lt;span class="p_defname"&gt;index&lt;/span&gt;&lt;span class="p_operator"&gt;(&lt;/span&gt;&lt;span class="p_identifier"&gt;self&lt;/span&gt;&lt;span class="p_operator"&gt;):&lt;/span&gt;&lt;br /&gt;      &lt;span class="p_word"&gt;return&lt;/span&gt; &lt;span class="p_string"&gt;"Hello World!"&lt;/span&gt;&lt;br /&gt;  &lt;span class="p_identifier"&gt;index&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;exposed&lt;/span&gt; &lt;span class="p_operator"&gt;=&lt;/span&gt; &lt;span class="p_identifier"&gt;True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="p_identifier"&gt;cherrypy&lt;/span&gt;&lt;span class="p_operator"&gt;.&lt;/span&gt;&lt;span class="p_identifier"&gt;quickstart&lt;/span&gt;&lt;span class="p_operator"&gt;(&lt;/span&gt;&lt;span class="p_identifier"&gt;HelloWorld&lt;/span&gt;&lt;span class="p_operator"&gt;())&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;running this piece of code you see:&lt;br /&gt;&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Listening for SIGHUP.&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Listening for SIGTERM.&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Listening for SIGUSR1.&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Bus STARTING&lt;br /&gt;CherryPy Checker:&lt;br /&gt;The Application mounted at '' has an empty config.&lt;br /&gt;&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Started monitor thread '_TimeoutMonitor'.&lt;br /&gt;[02/Oct/2008:06:55:40] ENGINE Started monitor thread 'Autoreloader'.&lt;br /&gt;[02/Oct/2008:06:55:41] ENGINE Serving on 127.0.0.1:8080&lt;br /&gt;[02/Oct/2008:06:55:41] ENGINE Bus STARTED&lt;br /&gt;&lt;br /&gt;and going to http://127.0.0.1:8080/ you see "hello world". &lt;br /&gt;&lt;br /&gt;Thats pretty much it. &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I know I know, a lot of you are saying "Wait, why would I use this over something like JEE and rails that does all this majic for me?"  There is no shortage of "out of the box" web frameworks that promise a "build your app in hours" magic&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've been using web frameworks going on 9 years, everything from JEE (Jboss), Ruby on Rails, and even Django.  And they are all great.  The probem is they are opinionated.  To try and remove responsibilities from the developer they make decisions for you, for example:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;How they create and commit your db session between requests&lt;/li&gt;&lt;li&gt; How many db sessions you can have.&lt;/li&gt;&lt;li&gt;View rendering technologies&lt;/li&gt;&lt;li&gt;which ORM to use&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;The list goes on and on.  And if you are using one of these frameworks you are enjoing all these "freebies" if you agree to follow the opinion and rules set by the framework.   However, the moment you have to go against one of these "pre-decisions" you can find yourself wrestling with the framework.   Just try to extend RoR to have multiple db sessions.  Or JBoss to use a "share nothing" architecture.  I usually find these issues come out when addressing scaling issues specific to your user behavior.&lt;br /&gt;&lt;br /&gt;With cherrypy's "minimal" architecture you are free to pretty much do what you want, but you have to do it.  You decide how db sessions are opened and closed before and after requests, or how your controllers are stuctured.  Its all up to you.  And the interesting thing is when you start doing  many of the "freebies" your self, you find you you weren't getting as much for free as you thought.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-4169585128436915974?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/4169585128436915974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=4169585128436915974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4169585128436915974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/4169585128436915974'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/10/python-and-sweet-cherrypy.html' title='python and sweet cherrypy'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-285699450197657403</id><published>2008-04-25T20:46:00.000-07:00</published><updated>2009-01-19T12:49:31.964-08:00</updated><title type='text'>closures and you</title><content type='html'>So I'm diving into dynamic programming with Groovy and I love it.  I consider myself an expert Java &amp;amp; C++ programmer, but I'm definitely having to do some re-learning with dynamic languages.  I think its like when you encounter someone who, for some reason or another, really doesn't grasp object oriented methodologies.  Its a way of thinking and designing your software that you really just have to understand.  I think programming in dynamic languages, while very different, follow the same learning process.  And I'm definitely in it. &lt;br /&gt;&lt;br /&gt;So lets start with closures, probably the most verbalized features of dynamic languages. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Obviously the most famous is iterating a list.  Lets say I want to print out every element in a list... obviously I could do the following in straight java.&lt;br /&gt;&lt;br /&gt;Vector list = new Vector();&lt;br /&gt;// add stuff to the list&lt;br /&gt;for ( Object x : list)&lt;br /&gt;    System.out.println(x);&lt;br /&gt;&lt;br /&gt;In groovy I can do:&lt;br /&gt;&lt;br /&gt;def list = ["one","two","three"]&lt;br /&gt;list.each { println ${it}}&lt;br /&gt;&lt;br /&gt;The idea is I actually pass the list a segment of "code" to execute on itself.  But wait, it gets better.&lt;br /&gt;&lt;br /&gt;Lets say I want to create a function that will do something n times... easy in  Groovy:&lt;br /&gt;&lt;br /&gt;def doSometing(number, Closure c) {&lt;br /&gt;    0.upto(number) {c}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// now you can call the method like this:&lt;br /&gt;doSomething (4) { println "Say Hello" }&lt;br /&gt;&lt;br /&gt;Pretty smooth huh?  Obviously the possibilities are endless and, possibly dangerous.  When passing a closure to an object, you basically give it permission do do whatever it wants&lt;br /&gt;&lt;br /&gt;class Hello {&lt;br /&gt;    String name&lt;br /&gt;    String important = "DON'T CHANGE"&lt;br /&gt;&lt;br /&gt;    def Hello (name, Closure c) {&lt;br /&gt;        this.name = name&lt;br /&gt;&lt;br /&gt;       c()&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I can then create a Hello object like this&lt;br /&gt;&lt;br /&gt;def h = new Hello("Jonathan" ) { this.important = "BAD"}&lt;br /&gt;&lt;br /&gt;And the Hello object's important field will be changed, even if I make it private.  Makes it a little difficult to create well-formed and protected libraries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-285699450197657403?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/285699450197657403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=285699450197657403' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/285699450197657403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/285699450197657403'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/04/closures-and-you.html' title='closures and you'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5042730514093042786</id><published>2008-04-17T20:13:00.000-07:00</published><updated>2009-01-19T12:49:31.964-08:00</updated><title type='text'>grails and the nulls that confuse me</title><content type='html'>Recently I've started doing a lot of my work in groovy.  Being an old fart I love my java, but many of the young guys are pushing me to pick up the dynamic languages of the times.  I'm not a fan of Ruby (mostly due to the community, you know who) and while I like Python it just doesn't fit for scalable enterprise systems.&lt;br /&gt;&lt;br /&gt;Then I noticed groovy, and I love it.  I have all the power of java with the syntactical candy of dynamic languages.   And Grails is really awesome (especially the 1.x series).  Its like Ruby on Rails, but made by people who really want to use it in production.  I can write groovy code, and use hibernate, and run on top of a clustered Jetty with terracotta, how cool is that?&lt;br /&gt;&lt;br /&gt;I do have to say, its the little things that get you.  A good example is GORM and exception handling.  In EJB3 or even straight hibernate, when I save an object that doesn't validate I'll get a java.lang.RuntimeException.  Example&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Person p = new Person();&lt;br /&gt;p.setName("something Bad);&lt;br /&gt;entityManager.persst(p);&lt;br /&gt;&lt;br /&gt;If for some reason p isn't able to be saved by the entity manager a runtime exception will be thrown.  Being a seasoned EJB developer I'd use this exception to my advantage and let it trickle out to the container and roll back the managed transaction (I think this is beautiful, but I guess a thing of the past).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Groovy, grails, and even rails does this different.  The way you know an entity is saved is by the return value on the entity.save() method.  Lets use the example above in grails.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def p = new Person(name:"something bad")&lt;br /&gt;p.save()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if for some reason p is unable to be saved we won't be notified by the above code, you actually have to do it like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def p = new Person(name:"something bad")&lt;br /&gt;if ( !p.save()) { p.errors.each(log.error(it))}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What I find fascinating about this example is a statically typed language is actually less code than a dynamic one!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5042730514093042786?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5042730514093042786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5042730514093042786' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5042730514093042786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5042730514093042786'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/04/grails-and-nulls-that-confuse-me.html' title='grails and the nulls that confuse me'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-2890428650675733803</id><published>2008-01-31T18:06:00.000-08:00</published><updated>2009-01-19T12:49:31.965-08:00</updated><title type='text'>Jetty &amp; spring are awesome</title><content type='html'>One reason I love java is it has so many tools out there to solve the problems you need to solve.  I needed to write a server-side app that was way under the scope of jBoss, so I downloaded Jetty and used spring. &lt;br /&gt;&lt;br /&gt;For those who don't know, Jetty is a super fast and light weight servlet container that uses NIO heavily.  For apps that don't need stuff like transactions its perfect.  And pair that up with Spring and you have a super fast &amp;amp; lightweight app that still has very good design.&lt;br /&gt;&lt;br /&gt;So check out &lt;a href="http://www.mortbay.org/"&gt;Jetty&lt;/a&gt; and &lt;a href="http://www.springframework.org"&gt;Spring.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-2890428650675733803?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/2890428650675733803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=2890428650675733803' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2890428650675733803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2890428650675733803'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2008/01/jetty-spring-are-awesome.html' title='Jetty &amp;amp; spring are awesome'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6785736778805359371</id><published>2007-11-17T08:26:00.000-08:00</published><updated>2009-01-19T12:49:31.965-08:00</updated><title type='text'>Call for Action</title><content type='html'>I've worked on a few open source projects and I have nothing bad to say about any of them.  If there is one shortfall in the open source world its that everyone wants to be the hero.  Everyone wants to "start" an open source project.  But far less people are willing to join existing projects and take them those last tedious few steps necessary to truly make them useful.  These steps usually include bug fixing and documentation.  This is why sourceforge has hundreds of thousands of projects that will never be used.&lt;br /&gt;&lt;br /&gt;At RubyConf Charles Nutter issued a "Call for Action" asking people to help take things those last steps, both on documentation of the new Ruby runtime AND bug fixing for JRuby.  So if you are interesting in doing something new, try and help him out.  Its the little things that makes most open source projects great.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://headius.blogspot.com/2007/11/rejectconf-4-calls-to-action-ruby-specs.html"&gt;Charles Nutter's Call to Action Post &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6785736778805359371?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6785736778805359371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6785736778805359371' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6785736778805359371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6785736778805359371'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/11/call-for-action.html' title='Call for Action'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5314182531678009026</id><published>2007-11-16T19:09:00.000-08:00</published><updated>2009-01-19T12:49:31.966-08:00</updated><title type='text'>JRuby and Seam</title><content type='html'>After spending a month or so playing with Ruby and Rails I'm really not happy with Rails.  I build systems that have to scale and Rails has some serious issues when it comes to that.  Its great for simple CRUD apps, but if you need to move outside of that or need to scale its got issues.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I do, however, like JRuby.  I'm also a big fan of jBoss Seam.  It just makes sense to me, use the scalability of EJB3 with state management in web apps.  In JBoss Seam 2.0 you can write your Seam components not only as EJB3, but also in Groovy.  I love EJB3 so that would be my first choice.  But I work with people who really want to use Ruby.  To meet in the middle I've been playing around with integrating JRuby into Seam.  Luckly, Seam is designed well to allow this with some learning curve.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'll post more later, but I've got a proof of concept where I can write my view in JSF, and a Seam-managed component in JRuby, which then uses JPA for persistence. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5314182531678009026?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5314182531678009026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5314182531678009026' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5314182531678009026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5314182531678009026'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/11/jruby-and-seam.html' title='JRuby and Seam'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5845322221340639427</id><published>2007-11-14T18:29:00.000-08:00</published><updated>2009-01-19T12:49:31.966-08:00</updated><title type='text'>Dreams of Fuel Cells</title><content type='html'>I live about an hour from the auto-motive capital of the U.S. (well, the former one at least).  The big 3 and the UAW are pretty much house-hold names in Michigan.  Most people who know me would testify that I'm not a fan of the U.S. auto industry.  From union squabbling to companies who produce non-creative, sub quality products and insist that the reason you should buy them is not because they are better, but because its your patriotic duty.&lt;br /&gt;&lt;br /&gt;Even though I rarely achieve this, I always strive to be a creative, forward thinking engineer.  I believe that sometimes its not always enough to just solve a problem, but solve it in a fantastic way that yourself and others can learn from.  I simply don't see this a lot from the big 3, which is why I drive a Honda.&lt;br /&gt;&lt;br /&gt;Tonight I saw a commercial for the new Honda hydrogen fuel-cell car, and I was captured.  I felt like I was looking at the iPhone of cars.  A company whose industry is as old as some governments refuses to subside into the monotonous productions of U.S. big business and big labor competitors.&lt;br /&gt;&lt;br /&gt;I need to do more reading to fully understand what this car is, but it looks like it will hit the road in the summer of 2008.  While other companies are just trying to stay a float and squabbling about overtime pay for employee uniform changes, Honda is making history.&lt;br /&gt;&lt;br /&gt;http://www.honda.com/fuel-cell/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5845322221340639427?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5845322221340639427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5845322221340639427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5845322221340639427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5845322221340639427'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/11/dreams-of-fuel-cells.html' title='Dreams of Fuel Cells'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3374262159263419059</id><published>2007-11-02T20:47:00.000-07:00</published><updated>2009-01-19T12:49:31.966-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>well-defined api</title><content type='html'>So from being a java/c++ developer for years I've been taught the importance of exposing well-defined save apis.  You expose parts of your api that you think is safe for black-box users to incorporate and abstract/protect the rest.  This is usually done by the visibility, security, and overriding features of the language.&lt;br /&gt;&lt;br /&gt;For instance, if I have a method that I think its unsafe for any class, including sub-classes to call, I'll define it as private. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ruby seems to think this isn't important.  I can do this:&lt;br /&gt;&lt;br /&gt;class Base&lt;br /&gt;    def aMethod&lt;br /&gt;       puts "A private method";&lt;br /&gt;    end&lt;br /&gt;    private :aMethod&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Derived&lt;br /&gt;    public :aMethod&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;In one line the sub class "Derived" was able to change the visibility of the method "aMethod".  A little scary when trying to define things like data structure libraries and application frameworks that depend on the validity of certain methods.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3374262159263419059?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3374262159263419059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3374262159263419059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3374262159263419059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3374262159263419059'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/11/well-defined-api.html' title='well-defined api'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-885471038635801637</id><published>2007-10-29T18:50:00.000-07:00</published><updated>2009-01-19T12:49:31.967-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby java jruby'/><title type='text'>Ruby on.... jetty?</title><content type='html'>So I'm playing around with JRuby, and I think its really cool.  The java community has really come a long way and created some great tools for doing enterprise deployments, why should the ruby community spend time backtracking and re-inventing the wheel?  The JVM has become a proven execution environment  and with an open byte-code standard its trivial to compile to it (well not trivial, but do0-able).&lt;br /&gt;&lt;br /&gt;So with JRuby you can get the syntactial sugar of ruby with the heavy lifting of such java services and JMS, hibernate, and even servlet containers.  Currently Ruby on Rails uses either WeBrick or Mongrel as their web server.  Both are written in ruby and, well, slow.  If there is one thing the java community has done a good job of the past few years its build fast and reliable servlet containers (just look at tomcat and jetty). &lt;br /&gt;&lt;br /&gt;What I'm wondering is how hard would it be to replace mongrel/WeBrick with jetty in a JRuby on Rails app?  Just think of the performance gain with Jetty's NIO engine?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-885471038635801637?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/885471038635801637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=885471038635801637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/885471038635801637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/885471038635801637'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/ruby-on-jetty.html' title='Ruby on.... jetty?'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-467898468754120867</id><published>2007-10-29T11:05:00.000-07:00</published><updated>2009-01-19T12:49:31.967-08:00</updated><title type='text'>sequel to the rescue</title><content type='html'>No sooner than I pushed the "post" button on my last post did I find sequel.   Its a light-weight ORM in Ruby that looks promising.  Does all the association fetching and even has 2nd-level cache support.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/ruby-sequel/"&gt;http://code.google.com/p/ruby-sequel/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-467898468754120867?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/467898468754120867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=467898468754120867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/467898468754120867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/467898468754120867'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/sequel-to-rescue.html' title='sequel to the rescue'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6355237371596008756</id><published>2007-10-29T06:25:00.000-07:00</published><updated>2009-01-19T12:49:31.968-08:00</updated><title type='text'>Active Record, the sludge in Ruby</title><content type='html'>So I've been learning Ruby lately, and being a bug ORM guy I decided to checkout the source for active record and see how it works.  There are some very serious issues here.  Active record uses the dynamic mixin ability of Ruby to do its work, but that same logic kills itself in performance.  To explain myself further I we should compare the active record model with JPA.&lt;br /&gt;&lt;br /&gt;JPA&lt;br /&gt;Java persistence architecture delegates all ORM work to the persistence manager, an external library that manages db entities.  If I want an entity I ask the persistence manager for it, if I want to save, I do it through the persistence manager.  When my app starts up the persistence manager looks at all my entities and my schema and creates the necessary object structure to do its ORM magic.  The mapping/querying logic is done once and used by everyone.&lt;br /&gt;&lt;br /&gt;ActiveRecord&lt;br /&gt;Active record delegates all ORM work to the entity itself.  Entities must know how to query/save themselves and if they are transient or persistent.  They do this by mixing in methods to to the ruby-defined entities at runtime and then, when an instance of an entity is instantiated, created the necessary links to do its ORM stuff.&lt;br /&gt;&lt;br /&gt;The disadvantage of active record is the function of ORM processes is spread throughout however many entities you have.  It becomes hard to do things like locking, transactional caching and even transactional enlistment.  If I have a 100 entities, each entity has to be concerned with cache invalidation and managing their relationships. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Until the ruby community either fixes this in active record, or comes out with a JPA/Hibernate -like ORM they will never be in the spotlight.  If you talk to any ruby-evangelist they always bring up that Twitter uses RoR.  And that is true, but if you read any of their posts to scale Twitter had to remove ActiveRecord from their deployment because it was just too slow.&lt;br /&gt;&lt;br /&gt;So I think Ruby is cool but I really don't like active record.  Anyone interested in porting hibernate to Ruby???&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6355237371596008756?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6355237371596008756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6355237371596008756' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6355237371596008756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6355237371596008756'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/active-record-sludge-in-ruby.html' title='Active Record, the sludge in Ruby'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-1404223390403208496</id><published>2007-10-26T21:08:00.000-07:00</published><updated>2009-01-19T12:49:31.968-08:00</updated><title type='text'>Netbeans and Ruby</title><content type='html'>I was working on a Ruby project I'll be revealing later, and I was looking for an IDE.  I thought I could get by using VI but after a few years of using Java with Eclipse I've been spoiled.  After a little looking I found the Netbeans 6 Beta.  They have Ruby package that is fantastic!  It contains auto-completion, tool tips, and helpers.  Make sure you download the version with the Ruby package installed.&lt;br /&gt;&lt;br /&gt;http://dlc.sun.com/netbeans/download/6.0/milestones/latest/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you are writing Ruby code its well worth the look.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-1404223390403208496?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/1404223390403208496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=1404223390403208496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1404223390403208496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1404223390403208496'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/netbeans-and-ruby.html' title='Netbeans and Ruby'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-7334759129212932533</id><published>2007-10-21T09:39:00.000-07:00</published><updated>2009-01-19T12:49:31.968-08:00</updated><title type='text'>C++ Garbage</title><content type='html'>So I've been having conversations about smart/auto pointers and c++ with some of my friends.  We all love java and other more modern languages that have garbage collection but there are times when you need to move back into C/C++ land, and rightfully so.  I'm not one of those "java/ruby/python is the language to replace all other languages."  I use the best tool for the job.&lt;br /&gt;&lt;br /&gt;So anyways, one of the most painstaking things about C++ is its absence of garbage collection.  Sure, you can always just create things on the stack and pass-by-value but that has its own issue (both in performance and logic).  Smart and auto pointers help but don't always give the performance that java gc does.  One of the nice things about the GC in java is it is not tied to the owning thread.  When an object no longer has any reference to it that thread doesn't block while the object is destroyed.  The garbage collector runs in the background, even in parallel, collecting objects smartly that can be destroyed and only doing the work it thinks it can do without consuming too many resources.  If I suddenly un-reference or move out of scope a million objects the VM won't necessarily destroy all million right then.  It will, over time, destroy them when it thinks it won't hurt performance.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So back to C++.  Using C++ templates it isn't difficult to do reference counting on your objects.  So what we really need to implement is a singleton garbage collector/reference manager that would keep track of all managed objects, and when they are no longer referenced would mark them to be removed, and then remove them when it thinks its best.&lt;br /&gt;&lt;br /&gt;Part 1 Singleton Reference Manager&lt;br /&gt;So first we would need to create a singleton C++ class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;class ReferenceManager&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;   static &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;* Instance();&lt;br /&gt;protected:&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;();&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;(const ReferenceManager&amp;amp;);&lt;br /&gt;   &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;&amp;amp; operator= (const &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;&amp;amp;);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, if you have never done singletons in C++, the way we insure that one and only one gets created/destroyed is using a local static:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager* ReferenceManager::Instance ()&lt;br /&gt;{&lt;br /&gt; static ReferenceManager inst;&lt;br /&gt; return &amp;inst;&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;This way a local static instance is created the first time this method is called, and after that the same instance is used.  Its also important to note that since inst is local static, it will automatically be destroyed when the application terminates.&lt;br /&gt;&lt;br /&gt;References can be obtained like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;ReferenceManager *p1 = ReferenceManager::Instance();&lt;br /&gt;ReferenceManager *p2 = p1-&gt;Instance();&lt;br /&gt;ReferenceManager &amp;amp; ref = * ReferenceManager::Instance();&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Part 2.  Reference Counting:&lt;br /&gt;In my next post I'll create my own smart pointer to do reference counting and communicate its state with this reference manager.   I would do that now but its beautiful outside and the lawn needs mowing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-7334759129212932533?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/7334759129212932533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=7334759129212932533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/7334759129212932533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/7334759129212932533'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/c-garbage.html' title='C++ Garbage'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3998755397256809765</id><published>2007-10-18T07:08:00.000-07:00</published><updated>2009-01-19T12:49:31.969-08:00</updated><title type='text'>Avoid locking with JMS</title><content type='html'>One of the hardest things to do in a high-load system is reporting.  Sometimes the amount of data you have to keep track of is too big. &lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;I have a page that is going to be displayed, and need to :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log every view of the page individually.&lt;/li&gt;&lt;li&gt;Keep a running total of everytime a page is viewed.&lt;/li&gt;&lt;li&gt;Have a max number of times a page can be viewed, and when that has been reached stop showing the page.&lt;/li&gt;&lt;/ol&gt;Now lets assume that we need to keep all these values in a database so we can scale-up our app server.  For requirements 2 &amp;amp; 3 we need to keep an aggregate table with a column that represents a "counter".  Without this table we would have to do an aggregation query on the log table (1) to see how many times this has been viewed, as our data grows this will get slow.&lt;br /&gt;&lt;br /&gt;So we create an aggregate table table that contains the page name and a counter of how many times that page has been displayed.  Every time that page is viewed we insert into the log table and update the counter in the aggregate table. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Locking is a b$$ch&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;There is a fundamental flaw with the above solution, if I get 100 concurrent page views, the database will have all those page views "lock" on that row in the aggregation table, this is so the db can provide ACID.  This will significantly decrease our ability to scale.  You could lower your transaction isolation in your db, but you aggregate value consistency may suffer. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;JMS to the rescue&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;A good solution is to use JMS.  When a page request comes in we still insert a row into the log table, but with the same XA transaction we also publish a message onto a durable JMS destination.  No locking will occur.  Now have a consumer (ether a message-driven-bean or a plain jms message consumer) will consume those messages with a durable subscription and update the aggregate asynchronously.  Who cares if they lock, it will be on a completely different thread thats not affecting the performance of serving the page.&lt;br /&gt;&lt;br /&gt;Obviously its possible to go over your max show variable (race condition that a page is served before the message consumer has a chance to process and update the aggregate) but when you get to high-yield systems you have to start playing payoffs. &lt;br /&gt;&lt;br /&gt;So the moral of the story: JMS can play a big role in high-yield systems with its durability and async processing.  Next time you have a locking issue or find you are doing too many things during a request, try moving those things behind a durable JMS topic, it may save you some time!&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3998755397256809765?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3998755397256809765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3998755397256809765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3998755397256809765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3998755397256809765'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/avoid-locking-with-jms.html' title='Avoid locking with JMS'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6673626722996743254</id><published>2007-10-11T07:04:00.000-07:00</published><updated>2009-01-19T12:49:31.969-08:00</updated><title type='text'>Python and SQLAlchemy</title><content type='html'>So if you read this blog its no secret I'm a fan of Hibernate.  Not because I'm a Java evangelists but really because I have yet to see many of Hibernates features in other ORMs.  Hibernate has gone above and beyond to make an ORM that is not only focused on pojo-based database access but also scalability and durability. &lt;br /&gt;&lt;br /&gt;You can tune hibernate to do association fetching and second-level caching that meets your load needs and reduce the amount of bottleneck your database is.  You can do projection to limit query context.  You can also enlist hibernate in java's JEE global transaction to make it durable and ACID compliant.  Many of the other languages and ORMs seem to focus more on developer convenience than these things. &lt;br /&gt;&lt;br /&gt;In the python world my boss pointed me to &lt;a href="http://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt;.  Its a python ORM that is based highly on the design of Hibernate.  I like what I see, the association mapping and querying is very similar and powerful. &lt;br /&gt;&lt;br /&gt;One thing I see that is missing is the powerful second-level caching concept.  Post people's response to this is "Oh, use memcache."  Well sure but you loose the acidic properties of your database and ORM.  Developers are tasked with first checking in memcache for their entitys, then going to the db, and the same with saving.  Both of which don't partipicate in the database transaction they are working in.  However, after looking at SQLAlchemy a little more I wonder how hard it would be to build transparent transactional enlistment of it with memcache. &lt;br /&gt;&lt;br /&gt;Just think, you decorate your SQLAlchemy object with some sort of marker saying that you want it to participate in second-level caching.  Then, along with setting up your persistence context (DB access, etc) you also setup a memcache resource.  Now when you access and save your SQLAchemy entities it also pushes and pulls them out of memcache behind the scenes and honors the database ACID transactions.  This could do wonders for the scalability of python.&lt;br /&gt;&lt;br /&gt;This smells like an open source project to me!  Comment with ideas and directions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6673626722996743254?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6673626722996743254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6673626722996743254' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6673626722996743254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6673626722996743254'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/python-and-sqlalchemy.html' title='Python and SQLAlchemy'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-668004998307987288</id><published>2007-10-07T19:23:00.000-07:00</published><updated>2009-01-19T12:49:31.969-08:00</updated><title type='text'>JEE isn't just about ORM</title><content type='html'>I had a conversation with a friend about JEE and how they thought it can be overkill. I should preface by saying I do believe there are situations where JEE is overkill, which I won't go into.  His argument is if you don't need to access a database with an ORM then you don't need JEE.&lt;br /&gt;&lt;br /&gt;I strongly disagree with this, mostly because I do this all the time.  I love Hibernate and EJB3 entity beans, but it doesn't work for all schemas.  If you have a highly normalized relational schema where you can take advantage of 2nd-level caching then entity beans is a blessing.  But if you are recording stats and doing more OLAP stuff then you may want to stick with straight JDBC.&lt;br /&gt;&lt;br /&gt;However, JEE works great with JDBC also.  In fact most deployments I've done, including one I'm currently responsible for, use both.  Take the following example&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;public @Stateless class PersonStatsBean implements PersonStats  {&lt;br /&gt;&lt;br /&gt;   @Resource(mappedName="java:/LoginStatsDS")&lt;br /&gt;     DataSource loginStats;&lt;br /&gt;&lt;br /&gt;   @PersistantContent&lt;br /&gt;   EntityManager em;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   public void recordLogin(int person_id) throws JDBCException&lt;br /&gt;   {&lt;br /&gt;       Person person = (Person)em.find(Person.class,person_id);&lt;br /&gt;       Connection con = null;&lt;br /&gt;       try {&lt;br /&gt;           con = loginStats.getConnection();&lt;br /&gt;               PreparedStatement stmt = con.prepareStatement("insert into login_stats(person_id)&lt;br /&gt;                       values (?)");&lt;br /&gt;               stmt.setParameter(person.getId());&lt;br /&gt;               stmt.executeUpdate();&lt;br /&gt;               con.close();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this example I am saving a row that keeps track of every time a user logs into my system.  I have an EJB3 entity called Person that is managed by the entity manager.  But I also inject a a regular JDBC data-source into my bean that keeps track of login stats.  The login_stats table may be a million rows long and denormalized for reporting efficiency so it really doesn't map well to an ORM.  The entity manager and the data source could be pointing to the same or different databases, I don't care.&lt;br /&gt;&lt;br /&gt;The cool thing is even though I'm using entity beans and JDBC, the application server makes sure they are both enlisted in the same XA transaction.  So even though I ask the container for a regular JDBC data-source by the time I get it an XA transaction has already started and is being managed.  I could save/update some EB3 entities and execute some JDBC statements and they will be fully ACID compliant.&lt;br /&gt;&lt;br /&gt;So yes Matilda, you can have your EJB3 and JDBC too.  By using JEE we are not tying ourselves to a predetermined set of abstractions.  If I want an ORM, I get that... If I want to do straight JDBC, I get that also.  And if I want to do both, I can have that too AND they all play by the same ACID rules.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;P.S.  You notice that I have to have this function throw a JDBCException.  I wish JDBC would follow the path of EJB3 persistence and make their Exception hierarchy extend RuntimeException rather than Exception.  But thats just a picky observation, not a framework killer&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-668004998307987288?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/668004998307987288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=668004998307987288' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/668004998307987288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/668004998307987288'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/10/jee-isn-just-about-orm.html' title='JEE isn&amp;#39;t just about ORM'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-8405342131653310979</id><published>2007-09-28T10:31:00.000-07:00</published><updated>2009-01-19T12:49:31.970-08:00</updated><title type='text'>Active record and those darn caps</title><content type='html'>Due to my recent illness I've had a lot of time to myself in doors.  So I've been looking a lot of technologies that have been on my watch list.  When looking at ruby's active record I can't help but like and hate it at the same time. &lt;br /&gt;&lt;br /&gt;One thing Ruby-lovers pride themselves on is "do as little as possible an get as much for free as possible."  Take the following active record example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Person &lt; ActiveRecord::Base &lt;br /&gt;  belongs_to :company &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Company &lt; ActiveRecord::Base &lt;br /&gt;  has_many :people &lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Gavin King, the creator of Hibernate ORM has an interesting comment about this :&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt; &lt;p style="font-style: italic;"&gt; At this point, most developers are thinking &lt;q&gt;um, ok, so how the hell am I supposed to know what attributes a &lt;tt&gt;Company&lt;/tt&gt; has by looking at my code? And how can my IDE auto-complete them?&lt;/q&gt; Of course, the Rails folks have a quick answer to this question &lt;q&gt;Oh, just fire up your database client and look in the database!&lt;/q&gt;. Then, assuming that you know ActiveRecord's automagic capitalization and pluralization rules perfectly, you will be able to guess the names of the attributes of your own &lt;tt&gt;Company&lt;/tt&gt; class, and type them in manually. &lt;/p&gt;  &lt;p&gt;&lt;span style="font-style: italic;"&gt; Somehow, excitement about the Ruby language has warped their perceptions to such an extent that these people actually believe that this is a &lt;/span&gt;&lt;i style="font-style: italic;"&gt;good thing&lt;/i&gt;&lt;span style="font-style: italic;"&gt;!&lt;/span&gt; &lt;/p&gt; &lt;/blockquote&gt;I completely agree.  Ruby plays some magic and when a record is pulled from the database ruby inspects it and adds the needed fields to these "active record" ruby classes.  While this is neat and keeps developers from having to plan out their ORM entities I can't help but see the possible problems with doing this on a very complex schema AND entity model.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-8405342131653310979?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/8405342131653310979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=8405342131653310979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/8405342131653310979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/8405342131653310979'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/09/active-record-and-those-darn-caps.html' title='Active record and those darn caps'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6949252923892593829</id><published>2007-09-27T12:25:00.000-07:00</published><updated>2009-01-19T12:49:31.970-08:00</updated><title type='text'>crap in the fan</title><content type='html'>Obie Fernandez, a Ruby evangelists, created a post saying why java is inferior to anything ruby and ruby on rails.  Of course being me I can't pass this up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jroller.com/obie/entry/top_10_reasons_why_java"&gt;http://www.jroller.com/obie/entry/top_10_reasons_why_java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Obviously even a ruby fan can read this and see that Obie really wanted to do little more than spread FUD and get his panties in a bunch (and I do say panties because anyone who wines like that must be wearing pink-lacy panties over his squirrel-sized package).&lt;br /&gt;&lt;br /&gt;However, his morning-after post showed that he does have some reasoning within him:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jroller.com/obie/entry/what_subtelty_and_suck_ass"&gt;http://www.jroller.com/obie/entry/what_subtelty_and_suck_ass&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've been doing a lot of "battling" lately with ruby evangelists about why I still do a lot of my deployments in JEE.  I think he has a good quote here:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Like Gavin pointed out, you can't do an app with thousands of model classes in Rails. Okay, but I'm really not trying to say that you should try. Right now, I personally have no interest in working on those kinds of monstrosities, but to each his own. "&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I completely agree with this.  Ruby on Rails is great for small, database driven apps that have the functionality of CRUD.  Go beyond that and its simply too much heavy lifting and you need to look into something more heavy-weight, like JEE.  Most ruby developers I talk to don't really want to tackle the large enterprise projects, they want to do what Rails was meant to do, small database driven websites.&lt;br /&gt;&lt;br /&gt;What this is really about is choosing the best tool for the job.  Some projects I would love to do in something like rails.  Other projects I think I would spend more time trying to get around rails to solve the problems and I need a framework that can handle those requirements.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Of course after the above post the java community fired back.  While I'm obviously biased I sort of feel like this one was much more intelligent.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javalobby.org/java/forums/t101687.html"&gt;http://www.javalobby.org/java/forums/t101687.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6949252923892593829?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6949252923892593829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6949252923892593829' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6949252923892593829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6949252923892593829'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/09/crap-in-fan.html' title='crap in the fan'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5255738405241941899</id><published>2007-09-25T19:59:00.000-07:00</published><updated>2009-01-19T12:49:31.971-08:00</updated><title type='text'>JMS.. the fruit rollup of non-transactional resources</title><content type='html'>Everyone knows I love JMS.  Almost all of my deployments take advantage of it and rightly so.  Who couldn't love transactional, durable, scalable asynchronous processing. &lt;br /&gt;&lt;br /&gt;One thing JMS is great for is wrapping resources that aren't JTA so they can "participate" in global transactions.  Notice the quotes because the correct way of doing this would be to write your own JCA connector, but sometimes we don't have 3 months to read the spec. &lt;br /&gt;&lt;br /&gt;A good example is if we want to save some stuff to a database and them write a file.  If we were to do the following sudo-code, assume this is in  a stateless session bean:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;@TransactionalAttribute(REQUIRES_NEW)&lt;br /&gt;public void doSomething()&lt;br /&gt;{&lt;br /&gt;    Person p  = new Person();&lt;br /&gt;    p.setName("Joshua");&lt;br /&gt;    entityManager.persist(p);&lt;br /&gt;&lt;br /&gt;    File f = new File("myStuff");&lt;br /&gt;    // write stuff to the file.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We actually don't know if our transaction succeeded until after this function has been executed.  But wait... we have already written a file... Oops!&lt;br /&gt;&lt;br /&gt;Enter JMS.  Put this file-write code in a message-driven bean and have the above method pump a message to its destination and the message won't get sent unless the transaction completes. &lt;br /&gt;&lt;br /&gt;Now there is one last thing to think about... what if the file write fails.  Well, you have 2 options. &lt;br /&gt;&lt;br /&gt;1) make sure the mdb rolls-back its transaction so the message will flow into a dlq and do your own compensation.&lt;br /&gt;2) just set the destination to not use a dlq.  This means if the message will keep being delivered until it can write a file.  Not really ACID compliant but you won't loose any files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5255738405241941899?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5255738405241941899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5255738405241941899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5255738405241941899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5255738405241941899'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/09/jms-fruit-rollup-of-non-transactional.html' title='JMS.. the fruit rollup of non-transactional resources'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6958887470561601591</id><published>2007-09-24T14:07:00.000-07:00</published><updated>2009-01-19T12:49:31.971-08:00</updated><title type='text'>scripting here I come</title><content type='html'>So I'm ashamed.  I've been putting off learning a new scripting language for way too long.  Commence beating me with a rubber duck now.&lt;br /&gt;&lt;br /&gt;So why do I even need to learn something like this?  I consider myself a pretty good C++ and Java programmer.  On top of that I feel like I can fully embellish the heavy-lifting fruits of JEE when it comes to building robust servers.  And unlike others in the development world I'm just not turned on by syntactical candy like "no accessor methods required."&lt;br /&gt;&lt;br /&gt;The main reason is I do think dynamic scripting languages have a place in my deployments and I like some of the things they are doing in the web-tier world.  While the interface-driven language characteristics makes Java a powerful player in the services/backend world it can sometimes be a bit tedious when pumping out web flows.  So for the time being my services-tier will always be the heavy-weight JEE server.  But I need to learn something smooth to fit on the front.&lt;br /&gt;&lt;br /&gt;So what are my options?  Well the talk on the town is Ruby.   I wrangled with this in my previous posts and I'm simply not a fan.  Lets forget for a second that its so slow it makes Java in the early 90's look good.  My issue is its almost diabetic on syntactical candy.  Who cares if you can do 50 things with 3 command words, I still can't understand it!   And the parenthesis rule drives me crazy.  Either make the developer use them or don't.  Because of this I feel like the Ruby community is full of language evangelists who's only defense of Ruby is&lt;br /&gt;"but its so agile".  Remember, a scripting language is suppose to be easier to read/understand than embedded C.  And personally I think the Rails framework has some serious functional issues.&lt;br /&gt;&lt;br /&gt;Groovy is a Ruby-like language that gets compiled to the JVM.  I like it because they took the best of java and ruby and blended them together.  I'll keep this in my bag of tricks but I'm not sure this is the complete answer.  And lets face it, I can't spend my life in a VM.&lt;br /&gt;&lt;br /&gt;Python is a little different for me.  My co-worker is a big python guy and I've been listening to what he has had to say.  I'm a picture-drawing sudo-code-thinking abstract engineer. If we have a design session and you start throwing byte orders out at me I'll get lost until a dry erase board is brought in.   Python seems to really target people like me with their sudo-syntax approach.  Plus I like some of the more java-like features they have annotations.  Also, compared to Ruby their plugin bank seems to be much more full.  And most of all when I ask  python people why they like it they can actually tell me things about the language they like.&lt;br /&gt;&lt;br /&gt;So Python it is!  My next few posts will be how a Java and JEE lover tames the rabid python.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[UPDATE] First note about python.. the main website is python.org, not python.com.  Lets hope that doesn't show up in the web logs at work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6958887470561601591?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6958887470561601591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6958887470561601591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6958887470561601591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6958887470561601591'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/09/scripting-here-i-come.html' title='scripting here I come'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6171976700539661699</id><published>2007-08-07T07:25:00.000-07:00</published><updated>2009-01-19T12:49:31.971-08:00</updated><title type='text'>Sometimes technology isn't enough</title><content type='html'>I'm an enterprise java developer.  I love writing scalable servers in JEE land, which usually involve a database back-end.  The current server that I'm architecting has been using the Mysql 5.0 database and we have been amazed with the performance.  Database purists have been bugging me to switch to Postgres because of its rich feature set.  I haven't messed with Postgres since college but I have over 8 years experience with MySQL.  Still, I evaluated Postgres and found it to be a very nice database.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So if Postgres is a more mature database with a richer feature set why do so many people still use MySQL?  Easy... community and marketing!  While at Borders book store I found 2 full shelves on MySQL, and only ONE book on Postgres.  If you have the money you can get on the phone to MySQL AS support or even have them come out to your business to train/troubleshoot.  I love open source software and both databases can be considered that, but MySQL has done a very good job at creating a service-oriented company behind their offering while Postgres has tried to stay with the purists. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So my final decision was to stay with MySQL, not because it was the better database, but because if something went wrong I'd have more options on how to get things solved. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6171976700539661699?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6171976700539661699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6171976700539661699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6171976700539661699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6171976700539661699'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/08/sometimes-technology-isn-enough.html' title='Sometimes technology isn&amp;#39;t enough'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-108014887052085254</id><published>2007-06-07T07:03:00.000-07:00</published><updated>2009-01-19T12:49:31.972-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java ejb'/><title type='text'>I love EJB3!!!!</title><content type='html'>So for the last 4 years or so a lot of the development I've done has revolved around J2EE.  This means using things like EJB, JMS, MBeans, and usually other goodies offered buy JBoss.  I've always liked EJBs, especially the way they remove concerns from the developer like threading, locking, synchronization and clustering.  However, I have never liked how hard they are to develop and deploy.  Things are so much easier in EJB3.  Here is a comparison.&lt;br /&gt;&lt;br /&gt;In EJB2.X&lt;br /&gt;&lt;br /&gt;To deploy a stateless EJB in 2.1 you need to write the bean and make sure you extend SessionBean.  Then implement a home, make sure you write the correct method!  The create your local and remove interfaces and place the correct methods you want to expose in both EXACTLY as they are in the bean definition.  Then you need to write 2 very complex xml documents telling the application server how to deploy and manage your bean.  Then package it up into a jar, place it in an ear and deploy.&lt;br /&gt;&lt;br /&gt;Now to access the bean you need to create a InitialContext.  Then do a lookup on the bean and get the home method.  Now use the home method to create an instance of the been itself.  Now you can use it.&lt;br /&gt;&lt;br /&gt;In EJB3&lt;br /&gt;&lt;br /&gt;Write a pojo bean with the business methods you want.  Have it extend a local interface and have it override methods in that.&lt;br /&gt;&lt;br /&gt;Place the @Stateless annotation on your bean telling the app server this is a stateless bean.&lt;br /&gt;Package it up in an ear and deploy.&lt;br /&gt;&lt;br /&gt;To access a bean, if you are in another ejb3 just annotate the member variable with:&lt;br /&gt;&lt;br /&gt;@EJB&lt;br /&gt;MySessionBean bean;&lt;br /&gt;&lt;br /&gt;And when that bean is created it will also create an instance  of your bean and inject it!&lt;br /&gt;&lt;br /&gt;Now you get the power of EJB with the simplicity of writing plain old java! I love it!  For more information you can go to &lt;a href="http://www.blogger.com/www.jboss.org"&gt;JBoss&lt;/a&gt; or get this really great book.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://labs.jboss.com/file-access/default/members/jbossejb3/images/oreillyejb3.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://labs.jboss.com/file-access/default/members/jbossejb3/images/oreillyejb3.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy Coding!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-108014887052085254?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/108014887052085254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=108014887052085254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/108014887052085254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/108014887052085254'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/06/i-love-ejb3.html' title='I love EJB3!!!!'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-1148166771408768618</id><published>2007-03-19T06:42:00.000-07:00</published><updated>2009-01-19T12:49:31.982-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acm'/><title type='text'>ACM World Programming Competition</title><content type='html'>The &lt;a href="http://icpc.baylor.edu/icpc/default.htm"&gt;2007 ACM World programming &lt;/a&gt;competition just wrapped up and they have &lt;a href="http://icpc.baylor.edu/icpc/Finals/2007WorldFinalProblemSet.pdf"&gt;released the problem set&lt;/a&gt; (solve it if you can).  This holds a special place in my heart because at &lt;a href="http://www.ecs.baylor.edu/"&gt;Baylor &lt;/a&gt;I worked for &lt;a href="http://www.ecs.baylor.edu/computer_science/index.php?id=29804"&gt;Dr. Poucher&lt;/a&gt;, who is the chair of the ACM contest.   While most of the competitors at this level are light years ahead of me, its always fun to look around and see what they solved and how they did it.  Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-1148166771408768618?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/1148166771408768618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=1148166771408768618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1148166771408768618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1148166771408768618'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/03/acm-world-programming-competition.html' title='ACM World Programming Competition'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-1069136777414044064</id><published>2007-03-03T21:09:00.000-08:00</published><updated>2009-01-19T12:49:31.983-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++ design'/><title type='text'>Class Factory Design Pattern</title><content type='html'>This week I was writing some C++ code and got to use one of my favorite design patters, the "Class Factory" pattern.  Lets say I have 2 ways to do something, like send a message.  I can either send it in email form or snail mail.  Clients will use my code to send messages but the logic stays the same for which method to use: 1) if I have an internet connection send it using email 2) if no internet, send it using snail mail.&lt;br /&gt;&lt;br /&gt;Obviously in c++ I should create 3 classes, a base Message sender method and 2 subclasses that encapsulate the logic of either sending mail using internet or snail.  But what about the logic for using the correct sending method (code that decides which subclass to create).  I could require my clients to implement that logic that means that all over my software will be if-then statements creating my objects. &lt;br /&gt;&lt;br /&gt;The other option is to create a class factory that encapsulates the logic of which subclass to create.  This is shown below (obviously this is example code)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#ifndef MESSAGESENDER_H_&lt;br /&gt;#define MESSAGESENDER_H_&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class MessageSenderFactory;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class MessageSender&lt;br /&gt;{&lt;br /&gt;    protected:&lt;br /&gt;        MessageSender();&lt;br /&gt;    public:&lt;br /&gt;       &lt;br /&gt;        virtual ~MessageSender();&lt;br /&gt;       &lt;br /&gt;        virtual void sendMessage(char* message) = 0;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class EmailMessageSender : MessageSender&lt;br /&gt;{&lt;br /&gt;    private:&lt;br /&gt;        EmailMessageSender() {};&lt;br /&gt;    public:&lt;br /&gt;   &lt;br /&gt;        friend class MessageSenderFactory;&lt;br /&gt;       &lt;br /&gt;        virtual ~EmailMessageSender() {};&lt;br /&gt;       &lt;br /&gt;        void sendMessage(char * message)  {} ;&lt;br /&gt;   &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class SnailMailMessageSender :  MessageSender&lt;br /&gt;{&lt;br /&gt;    private:&lt;br /&gt;        SnailMailMessageSender() {};&lt;br /&gt;    public:&lt;br /&gt;        friend class MessageSenderFactory;&lt;br /&gt;       &lt;br /&gt;        void sendMessage(char * message) {};&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class MessageSenderFactory&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;    MessageSenderFactory();&lt;br /&gt;   &lt;br /&gt;public:&lt;br /&gt;&lt;br /&gt;    /**&lt;br /&gt;     * Creates the correct message sender.&lt;br /&gt;     * 1) if we have a internet connection, create a email sender&lt;br /&gt;     * 2) else create a snailmail sender.&lt;br /&gt;     */&lt;br /&gt;    static MessageSender* createSender()&lt;br /&gt;    {&lt;br /&gt;        if ( HAS_INTERNET)&lt;br /&gt;            return new EmailMessageSender();&lt;br /&gt;        &lt;br /&gt;        return new SnailMailMessageSender();&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;#endif /*MESSAGESENDER_H_*/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice that I create the constructors in my subclasses private and use the friend construct to only allow the factory to use it.  This forces other code to go through the MessageSenderFactory to get new MessageSender objects, thus forcing them to use my logic.&lt;br /&gt;&lt;br /&gt;Now, all clients have to do to send a message is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  MessageSender * sender  = MessageSenderFactory::createSender();&lt;br /&gt;sender-&gt;sendMessage(message);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Clean and simple.  Enjoy creating class factories!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-1069136777414044064?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/1069136777414044064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=1069136777414044064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1069136777414044064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1069136777414044064'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/03/class-factory-design-pattern.html' title='Class Factory Design Pattern'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-2664904075170706189</id><published>2007-02-26T12:15:00.000-08:00</published><updated>2009-01-19T12:49:31.983-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>ORMs are not just about objects</title><content type='html'>It seems most of my professional career has been built around using java to pull and put stuff in a database of some sort.  Whether we are talking about an eGovernment web interface or a content management system I've done a lot of work with java and databases.   The past few years I have grown to use and love Object Relational Mappings (ORMs), specifically Hibernate.&lt;br /&gt;&lt;br /&gt;ORMs in the software development world are almost a religion, you either love or hate them.  I love them because they take a lot of the "Busy" work out of working with databases.  Plus they allow you to stay in an object oriented world rather than moving from java to JDBC, which is much more functional.&lt;br /&gt;&lt;br /&gt;Usually when I come across someone who is against ORMs they say "Well it doesn't fit with what we are trying to do" or "Its overkill" or "It adds complexity to a simple interface like SQL".  And its true, it can be overkill for some projects and it is another thing to learn and manage.  Some people would feel more comfortable pulling fields out of a result set than working with the Hibernate API.&lt;br /&gt;&lt;br /&gt;However, I think a lot of those people don't fully appreciate what ORMs give you.  Of course the most visible is the java object to sql mapping.  But another HUGE benefit is persistent lifecycle.  I've seen JDBC code that passes a connection through multiple paths, updating a row here, then updating it again, and so on and so on.  From an outsider it becomes almost cryptic what is happening and where.  And if you change your schema at anytime, you may not know the implications until the actual code is run.&lt;br /&gt;&lt;br /&gt;In ORM land lets say I have a User class, that maps to a table some where.  Lets say I do the folowing:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;User user = new User("Jon");&lt;br /&gt;session.save(user);&lt;br /&gt;....&lt;br /&gt;user.setAge(18);&lt;br /&gt;session.saveOrUpdate(user);&lt;br /&gt;...&lt;br /&gt;user.setAge(22);&lt;br /&gt;sesion.update(user);&lt;br /&gt;...&lt;br /&gt;user.setIsMaleGender(true);&lt;br /&gt;session.update(user);&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;session.commit();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now in JDBC land this would end up sending several SQL statements to the database, each being processed, locking rows, etc.  The code who set the users's age as 19 may not know that later some other code has set it to 22 unless they queried the db again in the same session.  If some logic was later performed with the assumption that the age is 19, that could be a problem.&lt;br /&gt;&lt;br /&gt;In Hibernate (or most ORMs) the session would keep track of that user object once it is associated with the session ( after the first session.save()) and keep track of updates and even retrievals.   Periodically throughout the lifetime of the session hibernate my flush the user object to the db or it may wait until the end.  Doesn't matter, however you do know that throughout that session you are not dealing with stale data.&lt;br /&gt;&lt;br /&gt;This is an incredibly efficient, complex and useful function that you get for free just by using an ORM.  As your code gets more complex and is re factored a few times, problems that can arise from using stale data that can be very difficult to track down (I should know, I've done it for a while).&lt;br /&gt;&lt;br /&gt;So whats the moral?  ORM just isn't about objects and abstracting SQL statements.  Its about treating persistent data as actual entities in your program.  If you think an ORM isn't for your app, I challenge you to look again.  The complexity of the added layer may simplify things in other places.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-2664904075170706189?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/2664904075170706189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=2664904075170706189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2664904075170706189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2664904075170706189'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/orms-are-not-just-about-objects.html' title='ORMs are not just about objects'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5185583134411147051</id><published>2007-02-20T11:06:00.000-08:00</published><updated>2009-01-19T12:49:31.984-08:00</updated><title type='text'>Paradigm shift</title><content type='html'>Moving into Objective-C with Cocoa requires a whole paradigm shift when talking about OOP.  Rather than objects having methods, they respond to messages.  And rather than calling methods, you send messages.  The interesting thing is you can send any message you want to an object, the question is they may not respond.  Take the following class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#import &lt;cocoa/cocoa.h&gt;&lt;br /&gt;&lt;br /&gt;@interface MyClass : NSObject&lt;br /&gt;{&lt;br /&gt;    NSString * name;&lt;br /&gt;   &lt;br /&gt;    NSMutableArray *items;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void)setName:(NSString *)aName;&lt;br /&gt;&lt;br /&gt;@end&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Lets assume I've implemented the rest of this.  The following code will compile&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;MyClass * test = [[MyClass alloc] init];&lt;br /&gt;&lt;br /&gt;[test someMethod];&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, notice that there is not a method called "someMethod" in the class MyClass, however I'm still able to "call" it in my source and compile it.  The reason is, I'm not really calling "someMethod", but rather sending a message.  When this runs it throws an exception but thats still very different than other languages I'm use to.  One cool thing is you can ask an object if it would respond to a message before sent.  A model that is very much like inspection in Java.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5185583134411147051?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5185583134411147051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5185583134411147051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5185583134411147051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5185583134411147051'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/paradigm-shift.html' title='Paradigm shift'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3855283068642767148</id><published>2007-02-11T09:39:00.000-08:00</published><updated>2009-01-19T12:49:31.984-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>NSStatusItem</title><content type='html'>I've been playing with Cocoa on my MacBook and I really wanted to create a Status Item on the "System Menu bar."  Translated, I wanted to create a menu on the top-right of the menu bar that was displayed even when another app was brought to the front.   When using Interface Builder I really couldn't see a graphical way to do it.  After some searching I figured it out.  In one of my controllers, I did the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;NSStatusBar *bar = [NSStatusBar systemStatusBar];&lt;br /&gt;       NSStatusItem * theItem = [bar statusItemWithLength:NSVariableStatusItemLength];&lt;br /&gt;       [theItem retain];  &lt;br /&gt;       [theItem setTitle:NSLocalizedString(@"Menu Title", @"")];&lt;br /&gt;       [theItem setHighlightMode:YES];&lt;br /&gt;       [theItem setToolTip:@"Menu ToolTip"];&lt;br /&gt;       [theItem setEnabled:YES];&lt;br /&gt;       [theItem sendActionOn:NSLeftMouseDownMask];&lt;br /&gt;       [theItem setTarget:self];&lt;br /&gt;       [theItem setAction:@selector(showInterface:)];&lt;br /&gt;       [theItem setMenu:nil];&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And boom, I now have a status item called  "Menu Title" on the top right that is always displayed.  Awesome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3855283068642767148?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3855283068642767148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3855283068642767148' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3855283068642767148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3855283068642767148'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/nsstatusitem.html' title='NSStatusItem'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3646518611512821929</id><published>2007-02-09T18:53:00.000-08:00</published><updated>2009-01-19T12:49:31.984-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Love your loops and let them love you</title><content type='html'>I'm not a language freek, but I can appreciate an improviment when I see it.  One of the new features in Java 5 is their new and improved for loop.  Lets say I want to iterator over a Vector of Strings.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Vector&lt;string&gt; list = new Vector&lt;string&gt;();&lt;br /&gt;&lt;/string&gt;&lt;/string&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The old way (pre java 5)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Iterator&lt;string&gt;&lt;&gt; iterator = list.iterator();&lt;br /&gt;      while (iterator.hasNext())&lt;br /&gt;      {&lt;br /&gt;          String s = iterator.next();&lt;br /&gt;          System.out.println(s);&lt;br /&gt;      }&lt;br /&gt;&lt;/string&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the new way (Java 5+)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for (String s : list)&lt;br /&gt;      {&lt;br /&gt;          System.out.println(s);&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;UPDATE: I just noted that my collection generics was removed by blogger's posting thingy.  Weird!  Just so everyone knows, I was using Java 5 generics on the vector to strongly type it with Strings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3646518611512821929?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3646518611512821929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3646518611512821929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3646518611512821929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3646518611512821929'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/love-your-loops-and-let-them-love-you.html' title='Love your loops and let them love you'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-3044389155998042206</id><published>2007-02-07T13:37:00.000-08:00</published><updated>2009-01-19T12:49:31.985-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java 5 Annotations and You</title><content type='html'>I was able to introduce Java 5 annotations to a few people at work today and I think I hit a cord.  I've always had a feeling that most people don't really understand the point of annotations, I know it look me a while.  One of the big uses of annotations is try remove the restriction on defining your structures based on interface implementation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Current Practice:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A good example is the swing api.  Lets say you have a JButton and you want to receive events when that button is pressed.  Current practice is to write an Class that implements EventListener and register your class with the JButton.  You then will receive Event objects and you can inspect them and figure out what event occurred and if they occurred on the button you are interested.    What happens is now in every EventListener you write you are now duplicating the code to inspect events, and route to the specific business logic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Throw in Reflection:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To me this is weird, Java is one of the few languages that has inspection and reflection however it is still common practice to force concrete implementation on the users of our apis.  What would make more sense is to tell a JButton "When this particular action occurs, call this method on this object."    Your controllers then become POJOs with the methods containing specific segments of business logic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;One Step further with Annotations:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now lets take that a step further and add the concept that I just want to give JButton my object and JButton will figure out what methods to call for what events and when, but still not requiring my controller to implement an interface.  This can be done with annotations.  Rather than giving the users of my API a set of interfaces they have to extend, I can just give them a set of annotations they can use to annotation their classes and the API will do the rest behind the scenes.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Example:&lt;/span&gt;&lt;br /&gt;Lets take this annotation.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import java.lang.annotation.ElementType;&lt;br /&gt;import java.lang.annotation.Retention;&lt;br /&gt;import java.lang.annotation.RetentionPolicy;&lt;br /&gt;import java.lang.annotation.Target;&lt;br /&gt;&lt;br /&gt;enum EventType {BUTTON_PUSHED,MOUSE_OVER}&lt;br /&gt;&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;@Target(ElementType.METHOD)&lt;br /&gt;public @interface EventCallback {&lt;br /&gt;&lt;br /&gt;  EventType value();&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here I create an annotation that can decorate a method and takes an enumerated value of either BUTTON_PUSHED or MOUSE_OVER (example actions that could occur on a Button).&lt;br /&gt;&lt;br /&gt;Now, lets say I'm writing my own GUI library, I can write a Button class to inspect any objects registering themselves for this annotation and remember them.  In my Button class the registerActionListener method looks like this now.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public void registerActionListener(Object object)&lt;br /&gt;    {&lt;br /&gt;        Method[] methods = object.getClass().getMethods();&lt;br /&gt;        for (int i=0;i &lt; methods.length;i++)&lt;br /&gt;        {&lt;br /&gt;            if ( methods[i].isAnnotationPresent(EventCallback.class))&lt;br /&gt;            {&lt;br /&gt;                EventCallback annotation = methods[i].getAnnotation(EventCallback.class);&lt;br /&gt;                EventType eventType = annotation.value();&lt;br /&gt;                if ( eventType == EventType.BUTTON_PUSHED)&lt;br /&gt;                {&lt;br /&gt;                    // remember to call this method on this object if the button is pushed&lt;br /&gt;                }&lt;br /&gt;                else if ( eventType == EventType.MOUSE_OVER)&lt;br /&gt;                {&lt;br /&gt;                    // remember to call this method on this object if the the mouse if over&lt;br /&gt;                }&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;Here is where you will really see the advantage.  Our Event Listener (or controller) now looks very clean and simple.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class MyController {&lt;br /&gt;&lt;br /&gt;      MyButton button = new MyButton();&lt;br /&gt;   &lt;br /&gt;      public MyController()&lt;br /&gt;      {&lt;br /&gt;          button.registerActionListener(this);&lt;br /&gt;      }&lt;br /&gt;   &lt;br /&gt;      @EventCallback(EventType.BUTTON_PUSHED)&lt;br /&gt;      public void myButtonWasPressed()&lt;br /&gt;      {&lt;br /&gt;          System.out.println("My Button Was Pushed");&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      @EventCallback(EventType.MOUSE_OVER)&lt;br /&gt;      public void aMouseIsOverMyButton()&lt;br /&gt;      {&lt;br /&gt;          System.out.println("A mouse if over my button");&lt;br /&gt;      }&lt;br /&gt;   &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice that I can now name my callback methods whatever I want.  Also, if I'm not interested in a event type, I don't have to even annotation a method for it.  This means I get the methods I want called for only the events I'm interested in.&lt;br /&gt;&lt;br /&gt;I really think this is the way all Java APIs are going and for a good thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-3044389155998042206?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/3044389155998042206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=3044389155998042206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3044389155998042206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/3044389155998042206'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/java-5-annotations-and-you.html' title='Java 5 Annotations and You'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-2189086768314686845</id><published>2007-02-02T10:48:00.000-08:00</published><updated>2009-01-19T12:49:31.985-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Memory Leak Solved!</title><content type='html'>Thanks to Chris for having more follow through than I do.  Here is his comment on my last post.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;I was curious myself, so I googled "cocoa exception leak", and found this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Exceptions are effectively out-of-band return values; in Cocoa, this means the exception object itself is autoreleased."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Full details here:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;http://chanson.livejournal.com/126035.html&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-2189086768314686845?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/2189086768314686845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=2189086768314686845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2189086768314686845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2189086768314686845'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/memory-leak-solved.html' title='Memory Leak Solved!'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-1248663172085678385</id><published>2007-02-02T05:44:00.000-08:00</published><updated>2009-01-19T12:49:31.985-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Memory Leak??</title><content type='html'>As I've stated in previous posts, I'm trying to learn Cocoa.  I'm amazed that with all my mac experience I really have a very basic knowledge of it.   I've been hitting a lot of tutorials and I have one big question.  I see variations of the following code a lot&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="border: 1px solid rgb(201, 209, 215);" bgcolor="#f1f5f9" cellpadding="6" cellspacing="0" width="100%"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;Cup *cup = [[Cup alloc] init];&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt; &lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;@try {&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;    [cup fill];&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;}&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;@catch (NSException *exception) {&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;    NSLog(@"main: Caught %@: %@", [exception name], [exception  reason]);&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;}&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;@finally {&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;    [cup release];&lt;span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td scope="row"&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Lets assume that [cup fill] throws the exception and its caught here.  Isn't the fact that the exception is never released a memory leak?  I know I'm being picky but I really see this in a lot of tutorials.   I would think that in the catch block I should see [exception release].    Cocoa programmers let me have it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-1248663172085678385?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/1248663172085678385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=1248663172085678385' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1248663172085678385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1248663172085678385'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/02/memory-leak.html' title='Memory Leak??'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-7208071100724521519</id><published>2007-01-31T18:41:00.000-08:00</published><updated>2009-01-19T12:49:31.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Valet is here to serve you</title><content type='html'>Some of my friends started a company called&lt;a href="http://www.94-west.com/"&gt; 94-west.&lt;/a&gt;  Today they are releasing a new product called Valet.  Its an awesome utility for Macs that organizes all your apps, interfaces with Apple's voice command, and has a beautiful heads up display like dashboard.  I love it and of you have a Mac you should check it out also.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://94-west.com/Valet/Valet.html"&gt;Valet Product Site&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-7208071100724521519?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/7208071100724521519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=7208071100724521519' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/7208071100724521519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/7208071100724521519'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/01/valet-is-here-to-serve-you.html' title='Valet is here to serve you'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5849031523137182357</id><published>2007-01-30T11:40:00.000-08:00</published><updated>2009-01-19T12:49:31.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Enterprise Service Bus - Mule</title><content type='html'>I love ESB.  No, thats not a drug, it stands for Enterprise Service Bus and its a Java Enterprise Component.  A lot of development work is taking 2 or more existing things and making them talk together.  Moving into the server side arena, this usualy entails spanning multiple machines, importing data, transforming data, and ensuring that data that needs to be imported is never lost.&lt;br /&gt;&lt;br /&gt;Now, anyone can write a program that watches a folder for new files and parses them when they arrive.  But, add in the following and the problem becomes a little harder:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The server that needs these files may be on a different machine than the folder being watched.&lt;/li&gt;&lt;li&gt;If the server goes down half way through parsing a file, I want to recover when I come back up.  Loosing a file is unacceptable.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;At any point in time I want to be able to monitor files that are being processed.&lt;/li&gt;&lt;li&gt;Depending on how powerful machines are, I want to control how many files are parsed at a time and when.&lt;/li&gt;&lt;li&gt;More than one component may be interested in the data that these files contain.&lt;/li&gt;&lt;li&gt;Maybe I not only want to be able to watch folders, but maybe also FTP site, email accounts, etc.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Now things are much harder.   Just adding in common error handling and recovery can be a pretty difficult task.&lt;br /&gt;&lt;br /&gt;Enter the Enterprise Service Bus (ESB).  This is a java architecture where you configure endpoints (Hot folders, email accounts, ftp accounts, anything), message flows, and connect them all together.  It handles error handling, splicing and duplicating messages, delivery and since it runs in a container threading and resource management is handled for you.&lt;br /&gt;&lt;br /&gt;In ESB talk, the example above would be configure a File endpoint to watch a hot folder, a transform to parse the file into relevant data, and another endpoint that talks to the server using whatever transport mechanism fits best.  If the message is stopped at any point throughout this process (say, because a server is down)  it simply waits until it can move on.  Plus, since you are using a well-known API, the leaning curve is greatly redulced and it can be expanded easily.&lt;br /&gt;&lt;br /&gt;So go learn about the Enterprise Service Bus architecture.  Some good ones are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://mule.codehaus.org/"&gt;Mule&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.servicemix.org/"&gt;ServiceMix&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://labs.jboss.com/portal/jbossesb/?prjlist=false"&gt;JBoss ESB&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;To see some code here is an programmatic example using Mule.  I will configure an "In" folder and an "Out" folder.  When files are dropped in the "In" folder, they are successfully moved through a dummy component (called a pass through component) and to the out folder.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;QuickConfigurationBuilder builder = new QuickConfigurationBuilder();&lt;br /&gt;     // this will create an admin agent&lt;br /&gt;builder.createStartedManager(true, "tcp://localhost:60504");&lt;br /&gt;&lt;br /&gt;// in endpoint&lt;br /&gt;UMOEndpoint inboundEndpoint = new MuleEndpoint("file://c:/MuleTest/In",true);&lt;br /&gt;// out endpoint&lt;br /&gt;UMOEndpoint outboundEndpoint = new MuleEndpoint(file://c:/MuleTest/Out",false);&lt;br /&gt; &lt;br /&gt;     // creating a flow using 2 endpoints and a passthrough component.&lt;br /&gt;builder.registerComponent(PassThroughComponent.class.getName(), "My Test Component",&lt;br /&gt;inboundEndpoint, outboundEndpoint, new HashMap());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And thats it.  By using these few lines we get a file copier with full error handling and recovery.  Plus, you can actually wire multiple Mule ESBs together to route these files from machine to machine to allow scalability and interpolation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mule.codehaus.org/"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5849031523137182357?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5849031523137182357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5849031523137182357' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5849031523137182357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5849031523137182357'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/01/enterprise-service-bus-mule.html' title='Enterprise Service Bus - Mule'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-5267449799937085035</id><published>2007-01-26T12:49:00.000-08:00</published><updated>2009-01-19T12:49:31.987-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java Message Service</title><content type='html'>I was pushing the Java Message Service (JMS) at work today for a few projects.  I think people have a huge misconception about JMS.  By using a broker and having entities communicate using messages, you completely  decouple your delivery, synchronization and communication mechanizm from your business logic.&lt;br /&gt;&lt;br /&gt;If I'm a message producer and I open up a connection to a broker and send a message, my code is no different if that broker is:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; on the same machine&lt;/li&gt;&lt;li&gt;in the same VM&lt;/li&gt;&lt;li&gt;On a machine across the internet&lt;/li&gt;&lt;li&gt;really a cluster of brokers performing load balancing and fail over.&lt;/li&gt;&lt;/ol&gt;This means your code is already scalable even if you don't need it.  Also, it means you don't have to worry about guaranteed delivery, persistence, and recovery.  Its all done for you.  You just write the components that send and receive code.    Plus, with some of the great JMS brokers like ActiveMQ, you have lots of options in transport and optimization.&lt;br /&gt;&lt;br /&gt;Take this example, here we have my producer&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;table border=true&gt; &lt;tr&gt;&lt;td&gt;&lt;br /&gt;/** This is an inVM connection.  This could also be a connection&lt;br /&gt;* to a broker on another machine or a cluster of brokers.  T&lt;br /&gt;* The only thing that would change is this string.&lt;br /&gt;*/&lt;br /&gt;ActiveMQConnectionFactory  factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");&lt;br /&gt;Connection connection = factory.createQueueConnection();&lt;br /&gt;connection.start();&lt;br /&gt;QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);&lt;br /&gt;&lt;br /&gt;// go ahead and create the queue, if it already exists, we will&lt;br /&gt;// just get the one that is there&lt;br /&gt;Queue queue = session.createQueue("MyQueue");&lt;br /&gt;// Creates a message producer to send messages to the queue&lt;br /&gt;MessageProducer producer = session.createProducer(queue);&lt;br /&gt;&lt;br /&gt;// create a generic message, you have several to choose from  &lt;br /&gt;Message message = session.createMessage();&lt;br /&gt;// normally you would want to actually put stuff in the message&lt;br /&gt;  &lt;br /&gt;// send the message&lt;br /&gt;producer.send(message);&lt;br /&gt;  &lt;br /&gt;// send more messages if you want&lt;br /&gt;// cleanup&lt;br /&gt;producer.close();&lt;br /&gt;session.close();&lt;br /&gt;connection.stop();&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And here is my reciever&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;table border=true&gt; &lt;tr&gt;&lt;td&gt;&lt;br /&gt;import javax.jms.JMSException;&lt;br /&gt;import javax.jms.Message;&lt;br /&gt;import javax.jms.MessageConsumer;&lt;br /&gt;import javax.jms.MessageListener;&lt;br /&gt;import javax.jms.Queue;&lt;br /&gt;import javax.jms.QueueConnection;&lt;br /&gt;import javax.jms.QueueConnectionFactory;&lt;br /&gt;import javax.jms.QueueSession;&lt;br /&gt;import org.apache.activemq.ActiveMQConnectionFactory;&lt;br /&gt;&lt;br /&gt;public class MyMessageConsumer implements MessageListener{&lt;br /&gt;&lt;br /&gt; QueueConnectionFactory factory = null;&lt;br /&gt; QueueConnection connection = null;&lt;br /&gt; Queue queue = null;&lt;br /&gt; QueueSession session = null;&lt;br /&gt; MessageConsumer consumer = null;&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * Opens a connection to the broker, creates a queue session and starts&lt;br /&gt;  * consuming messages.  The nice thing about active MQ&lt;br /&gt;  * that if you are using an inVM broker, you don't actually have to start it.&lt;br /&gt;  * It will be created when the first person opens a connection.&lt;br /&gt;  * @throws Exception&lt;br /&gt;  */&lt;br /&gt; public void start() throws Exception&lt;br /&gt; {&lt;br /&gt;  &lt;br /&gt;  /** This is an inVM connection.  This could also be a connection&lt;br /&gt;   * to a broker on another machine or a cluster of brokers.  T&lt;br /&gt;   * The only thing that would change is this string.&lt;br /&gt;   */&lt;br /&gt;  factory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");&lt;br /&gt;  &lt;br /&gt;  connection = factory.createQueueConnection();&lt;br /&gt; &lt;br /&gt;  session = connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);&lt;br /&gt;&lt;br /&gt;  // go ahead and create the queue, if it already exists, we will&lt;br /&gt;  // just get the one that is there&lt;br /&gt;  queue = session.createQueue("MyQueue");&lt;br /&gt;&lt;br /&gt;  // create a cosumer and add ourselves as the message listener.&lt;br /&gt;  // the consumer abstracts threading and all&lt;br /&gt;  consumer = session.createConsumer(queue);&lt;br /&gt;  consumer.setMessageListener(this);&lt;br /&gt;&lt;br /&gt;  // even though we have created a consumer, messages won't be delivered&lt;br /&gt;  // to us until we start the connetion it belongs to.&lt;br /&gt;  connection.start();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void stop() throws Exception&lt;br /&gt; {&lt;br /&gt;  connection.stop();&lt;br /&gt;  connection.close();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; /**&lt;br /&gt;  * Callback methoid from our queue session&lt;br /&gt;  * when a message arrives.&lt;br /&gt;  */&lt;br /&gt; public void onMessage(Message message) {&lt;br /&gt;  &lt;br /&gt;  try {&lt;br /&gt;   System.out.println("Hey!  I got a message");&lt;br /&gt;   // let the broker know we have the message.  If we didn't do this&lt;br /&gt;                      // the broker would assume something bad happened and redeliver.&lt;br /&gt;   message.acknowledge();&lt;br /&gt;  }&lt;br /&gt;  catch (Exception jms)&lt;br /&gt;  {&lt;br /&gt;   jms.printStackTrace();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pretty simple.  My producer opens a connection to the broker and publishes a message to the Queue "MyQueue".   My receiver  creates a consumer on the queue "MyQueue" and sets itself as the message listener.  When it receives a message it prints out a string. &lt;br /&gt;&lt;br /&gt;In this example the broker is in the same vm as the producer and consumer.  To have a broker running on a different machine or to have either the consumer or producer on different machines or to even have a cluster of brokers requires virtually no change to this code.  That means this code is scalable from a single JavaVM to 100 servers clustered.  Talk about planning for the future.  Also note that I in any of my code I don't have to worry about synchronization, threading, and concurrently.  Its all abstracted from my by the broker and the JMS clients.&lt;br /&gt;&lt;br /&gt;So why don't people use Message Driven Architecture more often?  I think a lot of the reason is the learning curve.  It is a new methodology and those are difficult to learn.  But once you do it makes life so much easer.  So go learn JMS, it will  make your life easier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-5267449799937085035?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/5267449799937085035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=5267449799937085035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5267449799937085035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/5267449799937085035'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/01/java-message-service.html' title='Java Message Service'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-1811189056624028025</id><published>2007-01-25T07:37:00.000-08:00</published><updated>2009-01-19T12:49:31.987-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Objective C and Me</title><content type='html'>So part of my new years resolution is to learn more technologies.  I am very strong in Java, ask me to do something and I can rip it out with Eclipse and a JVM.  C++ is my second strong suite.  Even though it doesn't look like professionally I'll be moving out of these technologies for a while, I think its important for me to try new things. &lt;br /&gt;&lt;br /&gt;Last night I was playing with Cocoa and Objective-C.  Apple has heavily adopted these technologies so I wanted to see why they went this direction.   Objective-C is an Object Oriented Language that contains the speed and power seen in C/C++, but also has many of the dynamic features you see in Java and Ruby. &lt;br /&gt;&lt;br /&gt;C++ lovers talk about the power and low-level access you get from the language.  Whether you are interfacing with a piece of hardware or writing a GUI, it can be done directly in C++.  However, you miss out on the dynamic features like Reflection and inspection that Java has.  But in Java you are restricted by the fact that you exist in a Virtual Machine and everything you need to access in the operating system either needs to be done using the Java API, or some JNI layer which gets you back to C++.&lt;br /&gt;&lt;br /&gt;Objective-C fixes this by the way its classes are defined and how you interact with them.  Rather can calling methods, you are really sending them messages and receiving responses.  You can inspect if an object will respond to certain messages and change that at runtime (a little scary).  They have also changed the way inheritance is done by adding sort of a "Role" attribute. &lt;br /&gt;&lt;br /&gt;Another neat thing about Objective-C is that it can link against call C++ APIs natively.  This is huge for anyone who has had to build a Java JNI interface to some C++ code they need to access, it isn't pretty.&lt;br /&gt;&lt;br /&gt;However with all the dynamic stuff in ObjC you do give up some of the stability and security C++ offers.  But with great power also comes great responsibility.  All-in-all I really like it and wish it was used more in my professional world.  I can think of a lot of situations where my C++ programming tasks would be easier with just simple inspection.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-1811189056624028025?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/1811189056624028025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=1811189056624028025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1811189056624028025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/1811189056624028025'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/01/objective-c-and-me.html' title='Objective C and Me'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-6957712681084140675</id><published>2007-01-22T06:24:00.000-08:00</published><updated>2009-01-19T12:49:31.987-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'></title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gcdAZxgiW9Q/RbTLIAqtcdI/AAAAAAAAAAU/WxNkhYAmF7o/s1600-h/0977616630.01._AA240_SCLZZZZZZZ_V34376513_.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_gcdAZxgiW9Q/RbTLIAqtcdI/AAAAAAAAAAU/WxNkhYAmF7o/s320/0977616630.01._AA240_SCLZZZZZZZ_V34376513_.jpg" alt="" id="BLOGGER_PHOTO_ID_5022862822903476690" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gcdAZxgiW9Q/RbTLHwqtccI/AAAAAAAAAAM/7hIJPj3mjxM/s1600-h/0974514055.01._AA240_SCLZZZZZZZ_.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://3.bp.blogspot.com/_gcdAZxgiW9Q/RbTLHwqtccI/AAAAAAAAAAM/7hIJPj3mjxM/s320/0974514055.01._AA240_SCLZZZZZZZ_.jpg" alt="" id="BLOGGER_PHOTO_ID_5022862818608509378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The past few years most of my programming experience has been in Java with C++ on the side.   The past year or so I've had a lot of tech friends telling me I need to checkout Ruby.  Since one of my earlier jobs where I inherited some nasty perl and jsp code I've usually tried to run away from scripting languages.   After downloading ruby and Ruby Eclipse on my MacBook I have to say I'm very impressed.&lt;br /&gt;&lt;br /&gt;Where java is mostly centered around building beautiful frameworks and utilizing inversion of control, Ruby is more about getting it done quickly and let the characteristics of the language handle the readability.   Especially the Ruby on Rails framework, which is by far the easiest web framework have seen yet for database driven applications (notice I said database driven apps and not all web apps).   I'm not saying Ruby replaces Java, but for some things I would seriously look at it.&lt;br /&gt;&lt;br /&gt;Anyways, in an effort to learn more I bought a few books on amazon.  First one is pretty much the Ruby Bible,&lt;span style="font-style: italic;"&gt; The Pragamatic Guide to Ruby&lt;/span&gt;.   The second is the associated book for Rails.  Hopefully after some nights reading I'll have a better understanding of what I can do.  I'm sure there will be more Ruby posts on their way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-6957712681084140675?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/6957712681084140675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=6957712681084140675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6957712681084140675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/6957712681084140675'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2007/01/past-few-years-most-of-my-programming.html' title=''/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_gcdAZxgiW9Q/RbTLIAqtcdI/AAAAAAAAAAU/WxNkhYAmF7o/s72-c/0977616630.01._AA240_SCLZZZZZZZ_V34376513_.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4341974800055505897.post-2708728530989336399</id><published>2006-12-11T11:48:00.000-08:00</published><updated>2009-01-19T12:49:31.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java 6 Released</title><content type='html'>&lt;p&gt;I really haven’t used this blog for tech stuff lately, but I really have to rave about the newly announced Java 6 release.  This is a huge release for the Java community, not only is it the first release fostered from community input, but it contains some huge advances in services that the JVM offers developers.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Once huge thing is scripting.  I’ve used scripting engines such as  &lt;a xhref="http://groovy.codehaus.org"&gt;Groovy&lt;/a&gt; and found them very useful in real-world senarios.  Especially when you need to provide custom functionality to an out-of-the-box software package why not include a custom script rather than creating a special build for a customer.  Now you get all of this for free just by using Java 6, awesome!&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here is the &lt;a xhref="TSS press releasse"&gt;http://www.theserverside.com/news/thread.tss?thread_id=43434&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4341974800055505897-2708728530989336399?l=eventualconsistency.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eventualconsistency.blogspot.com/feeds/2708728530989336399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4341974800055505897&amp;postID=2708728530989336399' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2708728530989336399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4341974800055505897/posts/default/2708728530989336399'/><link rel='alternate' type='text/html' href='http://eventualconsistency.blogspot.com/2006/12/java-6-released.html' title='Java 6 Released'/><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17857868650144570198</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://farm2.static.flickr.com/1419/802449896_861aece5a7_s.jpg'/></author><thr:total>0</thr:total></entry></feed>
