<?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:blogger='http://schemas.google.com/blogger/2008' 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-5709001424201684592</id><updated>2024-10-05T11:59:52.582+10:00</updated><category term=".net"/><category term="Java"/><category term="Windows"/><category term="Performance"/><category term="Security"/><category term="Malware"/><category term="SOLID"/><category term="Apple"/><category term="Automatic Updates"/><category term="Benchmarks"/><category term="Deployment"/><category term="Links"/><category term="Microsoft"/><category term="Mobile"/><category term="iPhone"/><category term="ASP.net"/><category term="App Store"/><category term="Continuous Integration"/><category term="Dacapo"/><category term="Exceptions"/><category term="Exchange Server"/><category term="FAIL"/><category term="Finalizer"/><category term="Garbage Collection"/><category term="IIS"/><category term="IKVM"/><category term="Inner-classes"/><category term="Joel Spolsky"/><category term="MAPI"/><category term="Memory Management"/><category term="Mercurial"/><category term="NSsh"/><category term="Novell"/><category term="OS X"/><category term="Parallel Extensions"/><category term="Review"/><category term="Roomba"/><category term="SNR"/><category term="Smart Pointers"/><category term="Stack Overflow"/><category term="Subversion"/><category term="TWAIN"/><category term="TwainDotNet"/><category term="iRobot"/><title type='text'>Luke Quinane</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-4790005470693353851</id><published>2009-11-04T22:22:00.001+11:00</published><updated>2009-11-04T22:22:09.319+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="App Store"/><category scheme="http://www.blogger.com/atom/ns#" term="Apple"/><category scheme="http://www.blogger.com/atom/ns#" term="Automatic Updates"/><category scheme="http://www.blogger.com/atom/ns#" term="Deployment"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="Malware"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft"/><category scheme="http://www.blogger.com/atom/ns#" term="Mobile"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Windows App Store</title><content type='html'>&lt;p&gt;I&#39;m developing applications for PC and the iPhone at the moment. It looks like the iPhone application will be the first to market for two reasons: it is a simpler application (which always helps), and there is less hassle to get it out the door. The main reason there is less hassle developing an iPhone app (ignore Apple&#39;s approval process) is because most common things are managed for the developer.&lt;/p&gt; &lt;h2&gt;The iPhone App Store&lt;/h2&gt; &lt;p&gt;I can&#39;t say I&#39;m a big fan of owning hardware that you have little or no control over but I do love both my iPhone and my Xbox 360. These controlled environments provide several benefits to the consumer:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;People feel safe using their credit cards to buy software. I don&#39;t think people are very keen to use their credit card at any old place - they don&#39;t want to be ripped off by paying for something that doesn&#39;t arrive and they don&#39;t want their credit card details stolen for other unauthorized uses.  &lt;li&gt;There is no fear of malware. Having all the software up for sale screened by a third party prevents malware from creeping in. Even if it does get in the vendor can release an update to disable it remotely.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;There are also many benefits for the developer:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;No need for a complex installer. This is a huge pain on Windows and Linux (I&#39;m not sure about OSX) and having a simple standard means of deploying the application is great.  &lt;li&gt;Distribution handled. The developer doesn&#39;t need to find or pay for hosting applications even free ones.  &lt;li&gt;Payment handled. The payments from the customer are handled automatically.  &lt;li&gt;Licensing handled. There is no need for a custom activating and licensing mechanism.  &lt;li&gt;Error reports handled. On Windows there is &lt;a href=&quot;http://en.wikipedia.org/wiki/Winqual&quot;&gt;winqual&lt;/a&gt; but it requires a $99 certificate, avoid that cost requires a custom solution.  &lt;li&gt;Single payment. The app store vendor takes a cut of sales so there is no separate cost for a winqual certificate, signing certificate, hosting, etc.&lt;/li&gt;&lt;/ul&gt; &lt;h2&gt;Windows App Store &lt;/h2&gt; &lt;p&gt;An app store for Windows would address several key problems for desktop development:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Remove the need for custom installers.  &lt;li&gt;Automatic updates and a single update notification. It seems like almost everyone does a poor job of updates and on my PC I have separate Adobe, Java, Apple and Google processes checking for updates.  &lt;li&gt;Distribution. No need to find hosting.  &lt;li&gt;Unified &quot;feel&quot; for applications. Consumers would have a single spot they felt safe using their credit card and knowing they weren&#39;t downloading malware. A great example of this on Windows is &lt;a href=&quot;http://en.wikipedia.org/wiki/Steam_(content_delivery)&quot;&gt;Steam&lt;/a&gt;.  &lt;li&gt;Mandated quality standards. This would hopefully move towards removing crapplets on PCs.  &lt;li&gt;A easy &amp;amp; safe way to make payments.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Microsoft already have &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Windows_Marketplace&quot;&gt;Windows Marketplace&lt;/a&gt;&quot; which apparently supports third-party titles however a quick look at the site fails to show any such applications. I think at a minimum they should re-brand whatever app store they make perhaps using Bing. &quot;Bing App Store&quot;?&lt;/p&gt; &lt;p&gt;Perhaps Valve will moving into distributing applications as well as games...&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/4790005470693353851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/4790005470693353851' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4790005470693353851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4790005470693353851'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/11/windows-app-store.html' title='Windows App Store'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-815415264985256667</id><published>2009-09-30T23:20:00.001+10:00</published><updated>2009-10-01T08:30:28.634+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Automatic Updates"/><category scheme="http://www.blogger.com/atom/ns#" term="Malware"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><title type='text'>Secure Updates?</title><content type='html'>&lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Currently I&#39;m looking into secure automatic updates for a .net program I&#39;m developing. I&#39;ve asked on stackoverflow for people to review my approach to the update process &lt;a href=&quot;http://stackoverflow.com/questions/1419800/auto-update-is-this-secure&quot;&gt;here&lt;/a&gt;. In the process I&#39;ve come across some interesting articles on automated updates and I thought I&#39;d review how other applications go about it.&lt;/p&gt; &lt;h1&gt;Java&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;Downloads &lt;a title=&quot;http://java.sun.com/update/1.6.0/map-1.6.0.xml&quot; href=&quot;http://java.sun.com/update/1.6.0/map-1.6.0.xml&quot;&gt;http://java.sun.com/update/1.6.0/map-1.6.0.xml&lt;/a&gt; which has details of various updates:&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;java-update-map version=&quot;1.0&quot;&amp;gt;&lt;br /&gt;   &amp;lt;mapping&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.6.0-rc-b98&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://javadl-esd.sun.com/update/1.6.0/au-descriptor-1.6.0_15-b71.xml&amp;lt;/url&amp;gt;&lt;br /&gt;   &amp;lt;/mapping&amp;gt;&lt;br /&gt;   &amp;lt;mapping&amp;gt;&lt;br /&gt;      &amp;lt;version&amp;gt;1.6.0&amp;lt;/version&amp;gt;&lt;br /&gt;      &amp;lt;url&amp;gt;http://javadl-esd.sun.com/update/1.6.0/au-descriptor-1.6.0_15-b71.xml&amp;lt;/url&amp;gt;&lt;br /&gt;   &amp;lt;/mapping&amp;gt;&lt;br /&gt;&lt;br /&gt;   ...&lt;br /&gt;&lt;br /&gt;&amp;lt;/java-update-map&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Then downloads the specific file given in the &#39;url&#39; element (e.g: &lt;a title=&quot;http://javadl-esd.sun.com/update/1.6.0/au-descriptor-1.6.0_15-b71.xml&quot; href=&quot;http://javadl-esd.sun.com/update/1.6.0/au-descriptor-1.6.0_15-b71.xml&quot;&gt;http://javadl-esd.sun.com/update/1.6.0/au-descriptor-1.6.0_15-b71.xml&lt;/a&gt;):&lt;/li&gt;&lt;/ul&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;java-update&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;information version=&quot;1.0&quot; xml:lang=&quot;en&quot;&amp;gt;&lt;br /&gt;    &amp;lt;caption&amp;gt;Java Update - Update Available&amp;lt;/caption&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Java Update Available&amp;lt;/title&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;Java 6 Update 15 is ready to install. Click the Install button to update Java now.  If you wish to update Java later, click the Later button. To get a FREE copy of OpenOffice.org, the global standard in free, Microsoft compatible office productivity software, just click the More Information link below.&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;moreinfo&amp;gt;http://java.com/infourl&amp;lt;/moreinfo&amp;gt;&lt;br /&gt;    &amp;lt;AlertTitle&amp;gt;Java Update Available&amp;lt;/AlertTitle&amp;gt;&lt;br /&gt;    &amp;lt;AlertText&amp;gt;A new version of Java is ready to be installed.&amp;lt;/AlertText&amp;gt;&lt;br /&gt;    &amp;lt;moreinfotxt&amp;gt;More information...&amp;lt;/moreinfotxt&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;http://javadl-alt.sun.com/u/ESD6/JSCDL/jre/6u15-b71/jre/jre-6u15-windows-i586-iftw.exe&amp;lt;/url&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.6.0_15-b03&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;post-status&amp;gt;https://sjremetrics.java.com/b/ss//6&amp;lt;/post-status&amp;gt;&lt;br /&gt;    &amp;lt;cntry-lookup&amp;gt;http://jal.sun.com/webapps/installstat/CountryLookup&amp;lt;/cntry-lookup&amp;gt;&lt;br /&gt;    &amp;lt;predownload&amp;gt;&amp;lt;/predownload&amp;gt;&lt;br /&gt;    &amp;lt;options&amp;gt;/installmethod=jau SP1OFF=1 SP2OFF=1 SP3OFF=1 SP5OFF=1 SP6OFF=1 SP7OFF=1 SP8OFF=1 SP10OFF=1 MSDIR=ms4 NEWMSTB=1 SPWEB=http://javadl-esd.sun.com/update/1.6.0/sp-1.6.0_15-b71&amp;lt;/options&amp;gt;&lt;br /&gt;    &amp;lt;urlinfo&amp;gt;6068ce6c957932593d20059bebab0dfc8b056ac3&amp;lt;/urlinfo&amp;gt;&lt;br /&gt;  &amp;lt;/information&amp;gt;&lt;br /&gt;&lt;br /&gt;  ...&lt;br /&gt;&lt;br /&gt;&amp;lt;/java-update&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;It does download a file from VeriSign which may be a check for the downloaded binary, e.g. &lt;a title=&quot;http://ocsp.verisign.net/MFEwTzBNMEswSTAJBgUrDgMCGgUABBRODEXefhs%2FUZFum2o8YfzOFwceMwQUkz5j3yJ0BOBkhDHd2yOfDq%2B2TZMCEA89qsgV9niZmSI6gIO0S%2FU%3D&quot; href=&quot;http://ocsp.verisign.net/MFEwTzBNMEswSTAJBgUrDgMCGgUABBRODEXefhs%2FUZFum2o8YfzOFwceMwQUkz5j3yJ0BOBkhDHd2yOfDq%2B2TZMCEA89qsgV9niZmSI6gIO0S%2FU%3D&quot;&gt;http://ocsp.verisign.net/MFEwTzBNMEswSTAJBgUrDgMCGgUABBRODEXefhs%2FUZFum2o8YfzOFwceMwQUkz5j3yJ0BOBkhDHd2yOfDq%2B2TZMCEA89qsgV9niZmSI6gIO0S%2FU%3D&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;Paint.net&lt;/h1&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Downloads &lt;a title=&quot;http://getpaint.net/updates/versions.5.600.x86.en.txt&quot; href=&quot;http://getpaint.net/updates/versions.5.600.x86.en.txt&quot;&gt;http://getpaint.net/updates/versions.5.600.x86.en.txt&lt;/a&gt; which looks like this:&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;; 3.xx manifest&lt;br /&gt;&lt;br /&gt;DownloadPageUrl=http://www.getpaint.net/download.html&lt;br /&gt;&lt;br /&gt;StableVersions=3.36.3158.38068&lt;br /&gt;BetaVersions=3.50.3550.40197&lt;br /&gt;&lt;br /&gt;3.36.3158.38068_Name=Paint.NET v3.36&lt;br /&gt;3.36.3158.38068_NetFxVersion=2.0.50727&lt;br /&gt;3.36.3158.38068_InfoUrl=http://www.getpaint.net/roadmap.html#v3_0&lt;br /&gt;3.36.3158.38068_ZipUrlList=http://www.getpaint.net/updates/zip/Paint.NET.3.36.zip&lt;br /&gt;3.36.3158.38068_FullZipUrlList=http://www.getpaint.net/updates/zip/Paint.NET.3.36.zip&lt;br /&gt;&lt;br /&gt;3.50.3550.40197_Name=Paint.NET v3.5 Beta 1 (Build 3550)&lt;br /&gt;3.50.3550.40197_NetFxVersion=3.5.1&lt;br /&gt;3.50.3550.40197_InfoUrl=http://paintdotnet.forumer.com/viewtopic.php?f=46&amp;amp;t=31684&lt;br /&gt;3.50.3550.40197_ZipUrlList=http://www.getpaint.net/files/zip/preview/Paint.NET.3.5.Beta.3550.Update.zip,http://www.dotpdn.com/files/Paint.NET.3.5.Beta.3550.Update.zip&lt;br /&gt;3.50.3550.40197_FullZipUrlList=http://www.getpaint.net/files/zip/preview/Paint.NET.3.5.Beta.3550.Install.zip,http://www.dotpdn.com/files/Paint.NET.3.5.Beta.3550.Install.zip&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;s&gt;This manifest file and the associated binaries don&#39;t appear to be signed in any way&lt;/s&gt;. &lt;strong&gt;Update:&lt;/strong&gt; Rick Brewster has commented to say that the downloaded binary is signed and the signature &lt;em&gt;is verified&lt;/em&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;Skype&lt;/h1&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Checks for updates by querying: &lt;a title=&quot;&lt;br /&gt;http://204.9.163.158/ui/0/4.0.0.227./en/getnewestversion?ver=4.0.0.227&amp;amp;uhash=143c299d62b6baac1f30936f72dd4683f&quot; href=&quot;http://204.9.163.158/ui/0/4.0.0.227./en/getnewestversion?ver=4.0.0.227&amp;amp;uhash=143c299d62b6baac1f30936f72dd4683f&quot;&gt;http://204.9.163.158/ui/0/4.0.0.227./en/getnewestversion?ver=4.0.0.227&amp;amp;uhash=143c299d62b6baac1f30936f72dd4683f&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;4.1.0.166&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Downloads the update file: &lt;a title=&quot;http://163-158.static.quiettouch.com/ui/0/4.0.0.227./en/upgrade &quot; href=&quot;http://163-158.static.quiettouch.com/ui/0/4.0.0.227./en/upgrade &quot;&gt;http://163-158.static.quiettouch.com/ui/0/4.0.0.227./en/upgrade &lt;/a&gt;&lt;br /&gt;&lt;li&gt;Unless the downloaded binary&#39;s signature is checked this would be vulnerable to a man in the middle attack.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;Other&lt;/h1&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;iTunes posts a big blob of data back to Apple on startup checking for updates - I didn&#39;t look into this much. &lt;br /&gt;&lt;li&gt;Google Chrome also posts back information when checking for updates. My version of Chrome was up to date so I didn&#39;t see the update process in action. &lt;br /&gt;&lt;li&gt;Firefox was already in the process of downloading a new version so I had already missed the file download negotiation.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h1&gt;Summary&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;It seems like everyone is doing automatic updates differently (no surprises there). It also looks like there is plenty of scope for man in the middle and spoofing attacks if the downloaded binaries aren&#39;t signed or don&#39;t have their signatures. It doesn&#39;t seem like many people are checking their manifest files before downloading binaries which could lead to Safari style &quot;carpet bombing&quot; where malicious binaries are downloaded onto the system.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/815415264985256667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/815415264985256667' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/815415264985256667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/815415264985256667'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/09/secure-updates.html' title='Secure Updates?'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-3808892944974330243</id><published>2009-09-29T13:56:00.001+10:00</published><updated>2009-09-29T13:56:25.983+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iRobot"/><category scheme="http://www.blogger.com/atom/ns#" term="Review"/><category scheme="http://www.blogger.com/atom/ns#" term="Roomba"/><title type='text'>Roomba Review</title><content type='html'>&lt;p&gt;Last Christmas we got a &lt;a href=&quot;http://en.wikipedia.org/wiki/Roomba&quot;&gt;Roomba&lt;/a&gt; 530 (you can see a similar model &lt;a href=&quot;http://en.wikipedia.org/wiki/File:Roomba3g.jpg&quot;&gt;here&lt;/a&gt;). A Roomba is a robotic vacuum cleaner, however, it mostly collects rubbish (dirt, garbage, hair, etc) using it&#39;s system of brushes. Since it is battery powered it doesn&#39;t have a very strong vacuum action. Having had Roomba in our house for almost a year I thought I give a quick review of it&#39;s pros and cons.&lt;/p&gt; &lt;p&gt;Firstly before I go into the details of the actual Roomba unit there are a few important background details:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I live in a small unit that has all hardwood floors. &lt;/li&gt; &lt;li&gt;I also have two cats who generate a &lt;em&gt;lot&lt;/em&gt; of cat hair. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This combination is almost perfect for an automated cleaner: small amounts of dust and cat hair need cleaning every few days, there is no carpet to soak up dirt.&lt;/p&gt; &lt;h1&gt;Pros&lt;/h1&gt; &lt;p&gt;&lt;strong&gt;Roomba is awesome!!!11&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It is quite cool to have an automated robot to go and clean your floors while you sit back and watch. And it is very mesmerising at first the way Roomba negotiates chair legs, people and other obstacles. Its a cliché but I do wonder if the next generation will even know what a &quot;manual&quot; vacuum cleaner is.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Roomba is small&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;In a small unit space is important, Roomba takes up a fraction of the space of a traditional vacuum cleaner.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Roomba cleans where you can&#39;t&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To paraphrase the iRobot promotional video, &#39;Roomba cleans under stuff&#39;. I am constantly surprised at how much gunk it is able to find underneath furniture like our couch (out of sight out of mind I guess).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fire and forget&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can put Roomba on and go out; it will happily clean and re-dock itself once its done. However it practice you need to clear the floor of cables, etc. Otherwise you will come back to find Roomba has eaten the cord of your curtains and is hopelessly stuck.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Quiet&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Roomba is noisy, but compared to a regular vacuum cleaner it is very quiet. My cats would run away when we started to put together the old vacuum cleaner but with Roomba they are happy to hang around and watch it with disdain.&lt;/p&gt; &lt;h1&gt;Cons&lt;/h1&gt; &lt;p&gt;&lt;strong&gt;Maintenance, maintenance, maintenance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The main problem with Roomba is that while it cleans your house without much supervision you need to clean it. After every clean you need to empty its pathetically small bin and after most cleans you need to clean the main brushes. Every three or four cleans I have to also remove hair from it&#39;s wheels and in the bearings of the main brushes. Occasionally you have to unscrew the &#39;flicking&#39; brush to remove some long string that its eaten. Finally after about 8 months I notices that Roomba was no longer driving around in a straight line and I had to clean its sensors with a cotton bud.&lt;/p&gt; &lt;table border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot; width=&quot;100%&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;50&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7igrDi188usC7RRHV1BlimT97REIpYymJQQgroaD7_yIsyxh0mHh2RMljxOCHidjbd1EAx6cu2MM7p_YekQltawEMTAJUG2q_pJjU9QETO6q2fbtXrK9wGvCNAN06J1Bz6sS6ihL3pn0/s1600-h/Roomba%20037%5B6%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4VGz45bMyI9QQVbhnncwZjReRyZTL1wTTNvRAPztRHt_tYH1hXLUJjBT9JyP032hFlqeDZnhO_Z67M74Eh371r1-4GGLDEUBikMcgQOEUF6WBfy_2RxkocaFSudSIz67tLlvfKBg-nqI/?imgmax=800&quot; width=&quot;300&quot; height=&quot;225&quot;&gt;&lt;/a&gt;&amp;nbsp;&lt;br&gt;Hair on the brushes&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;50&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUzw0Yakqu_8-kBUYNP4PFAmb94hvX_gQVLCAmbAojNeG0T9Hl06ENcpwbIjGgFy64O_TI0lGJvAGAwND4ytuPVLHYfY7diOQrObSS83flS0PiFTs0UftRr-WFG5JJtMwJ1G7xVrckDKU/s1600-h/Roomba%20038%5B4%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwx89mWZbrV970vG8MCW4f9QVTrVwjTTbI8qeU49vwbWIO5qdTj0j6xQOpYEQcT1UQ813KYUzVT0T7yrbhTyuY0dEvuG4_BaVE9Pcltxh9PvrF7XFAGBCwESzueKQ5UMITgfM3IvOoU_o/?imgmax=800&quot; width=&quot;300&quot; height=&quot;225&quot;&gt;&lt;/a&gt;&lt;br&gt;Hair in the bearings&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;50&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQlV7oT2a5SPv3cYwkN14zTtSS8s20fz-qP9YL9lbs4QcrZJ5cl_ouWZmFhFxCUA4imPOohmDZWsH5HOssFpUbQ9Z12_y4RHeeu39PPgG_GXBxF66GzefNT3Ff1RjaXtjVZ4UPbxPf8B8/s1600-h/Roomba%20039%5B4%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSZwaLN1LQcmA_N2g5ItZQw-CXfFeCtw8N-Z0iPRzy8iDdTMmbwMJE5IP3Hz5wTWZFOyWj200-VO6Im1rvo0brOX4amlPiKDbekUwEV-XuMSRa5Vmoc4kVuSNoz23LI7LEsU7UIC4YYYs/?imgmax=800&quot; width=&quot;300&quot; height=&quot;225&quot;&gt;&lt;/a&gt; &lt;br&gt;Hair cleaned off the brushes&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;50&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG9m9XKEDUqoeHix6DZKjcMNsUhtS-sTRxa0ladQWaZKx4c2RnchKK-ywBhsnyYr5se-_pqMX8gssTaI_Q-aNGdC5QTXfNITOSqNbBYg7o0W6y8UtPC67HjW_9GWfWBzTl05_0WPSLfJo/s1600-h/IMG_0323%5B4%5D.jpg&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt2qrEdvkuGFSdg_gnFU4on_YHm_bos9jEIHdin-4GjcnOYxesz3KVvdXXfHfy7d_jJvoOml7wIdiZrYr92iKxr21m2b6i-4qPs4vpKGmc2ENhwMwv6jLu8B_MJtT-kTkTiUM6B7poBzw/?imgmax=800&quot; width=&quot;300&quot; height=&quot;225&quot;&gt;&lt;/a&gt; &lt;br&gt;Gunk from the sensors&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&lt;strong&gt;Fire and forget?&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Fire and forget is sometimes like fire and get stuck: unless you prepare your floor removing any big particles (or are insanely neat) Roomba will eat a rubber band, pen, string, cable or similar and get is main brushes stuck. Usually I put Roomba on and then start to clear things that it might get caught on.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dark furniture&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Roomba uses several sensors to work out if it is going to bump into things before it actually triggers its big bumper. Unfortunately these sensors don&#39;t pick up dark furniture very well and as a result Roomba bangs into things (quite loudly). Short of putting reflector strips at Roomba height you can always move the furniture or just ignore it. &lt;/p&gt; &lt;h1&gt;Summary&lt;/h1&gt; &lt;p&gt;Roomba is awesome and I love it but it does require maintenance. Having seen it in action I feel that it works best on hard floors but it seemed to work well on carpet when I tried it at my parent&#39;s place. The main advantages are being able to put it on and leave it and also that it cleans under furniture. It does have some annoying quirks but nothing that has bothers me too much.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/3808892944974330243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/3808892944974330243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/3808892944974330243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/3808892944974330243'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/09/roomba-review.html' title='Roomba Review'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4VGz45bMyI9QQVbhnncwZjReRyZTL1wTTNvRAPztRHt_tYH1hXLUJjBT9JyP032hFlqeDZnhO_Z67M74Eh371r1-4GGLDEUBikMcgQOEUF6WBfy_2RxkocaFSudSIz67tLlvfKBg-nqI/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-9104336308368251314</id><published>2009-09-25T23:06:00.001+10:00</published><updated>2009-09-25T23:06:01.083+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Continuous Integration"/><category scheme="http://www.blogger.com/atom/ns#" term="FAIL"/><title type='text'>Epic Meltdown</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-rjLr4I7_3PP7YSI_kUu5MWV18G_9-yLP-B1xZeWOpR6yq43DelG1hQa77gTtlUC6iHjeA3V9gHEbVlleFJX32d-PDSvYI91G-cqurtXt0AuJ1_5VNrktXKG9Hlmsooq6elhp9HnCF-c/s1600-h/epic%20meltdown%5B5%5D.png&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px&quot; border=&quot;0&quot; alt=&quot;CC.net builds all broken :-(&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-h41y0t8XAuaIHYxryYhb6YU5kKww2Ig7nWIZvHCj8SWD5tnqGhOxdOI3UwWECIXgy3UY1njPYJMcKgzNlKf20675Juwha3RjQKMFNnww3zQtN_oLT6t-D-Ty0jKurNVOuoMSz-FPa0/?imgmax=800&quot; width=&quot;816&quot; height=&quot;341&quot;&gt;&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/9104336308368251314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/9104336308368251314' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/9104336308368251314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/9104336308368251314'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/09/epic-meltdown.html' title='Epic Meltdown'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-h41y0t8XAuaIHYxryYhb6YU5kKww2Ig7nWIZvHCj8SWD5tnqGhOxdOI3UwWECIXgy3UY1njPYJMcKgzNlKf20675Juwha3RjQKMFNnww3zQtN_oLT6t-D-Ty0jKurNVOuoMSz-FPa0/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-3474119380898542933</id><published>2009-08-24T22:40:00.001+10:00</published><updated>2009-08-24T22:40:37.036+10:00</updated><title type='text'>August Links</title><content type='html'>&lt;h1&gt;Utility&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot; http://www.convertcase.net/&quot;&gt;Online text case converter&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;VM Ware&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://www.codeproject.com/KB/library/VMWareTasks.aspx&quot;&gt;Automating VMWare Tasks in C# with the VIX API&lt;/a&gt;&lt;/li&gt; &lt;p&gt;&lt;a href=&quot;http://vmwaretasks.codeplex.com/&quot;&gt; &lt;li&gt;VMWareTasks: C# VixCOM&lt;/li&gt;&lt;/ul&gt;&lt;/a&gt; &lt;h1&gt;&lt;a href=&quot;http://vmwaretasks.codeplex.com/&quot;&gt;&lt;/a&gt;Misc&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a title=&quot;http://www.spiralspace.com/Depot/Projects/Disassembler/disassembler_ia32.aspx&quot; href=&quot;http://www.spiralspace.com/Depot/Projects/Disassembler/disassembler_ia32.aspx&quot;&gt;How to write a disassembler&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/3474119380898542933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/3474119380898542933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/3474119380898542933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/3474119380898542933'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/08/august-links.html' title='August Links'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-543176285648880243</id><published>2009-08-18T13:44:00.001+10:00</published><updated>2009-08-18T13:44:05.028+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Apple"/><category scheme="http://www.blogger.com/atom/ns#" term="iPhone"/><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft"/><category scheme="http://www.blogger.com/atom/ns#" term="Novell"/><title type='text'>iPhone Reaching Critial Mass</title><content type='html'>&lt;p&gt;It seems to me that the iPhone is beginning to reach critical mass. And by critical mass I mean that the iPhone is reaching the status of the &lt;a href=&quot;http://en.wikipedia.org/wiki/IPod&quot;&gt;iPod&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Nokia_5110&quot;&gt;Nokia 5110&lt;/a&gt;: &lt;em&gt;everyone&lt;/em&gt; has one. Part of my reasoning is that everyone I know seems to be talking about their iPhone or planning to get one. (Of course my sample size is very small and probably biased, but hey).&lt;/p&gt; &lt;p&gt;Travelling to work and back home everyday it seems like heaps of people already have them. Since it is becoming more popular is also seems to becoming less flashy and pretentious. Admittedly I live and work in inner Sydney so the sample set may be biased again.&lt;/p&gt; &lt;p&gt;And what alternative is there? In the same way that PC makers are struggling to design and build PCs that match Apple&#39;s sleek designs no one seems to be making a viable iPhone competitor. Also the AppStore is a very attractive place to put an application since consumers are quite comfortable using it to purchase software. Which in turn means all the developers are looking at developing for the iPhone.&lt;/p&gt; &lt;p&gt;It all adds up to one thing: critical mass and unfortunately lock-in. And the scary thing is that everyone seems comfortable that Apple won&#39;t abuse its position and become an &lt;a href=&quot;http://www.techcrunch.com/2009/07/27/apple-is-growing-rotten-to-the-core-and-its-likely-atts-fault/&quot;&gt;evil monopoly&lt;/a&gt;.&lt;/p&gt; &lt;h1&gt;Microsoft&lt;/h1&gt; &lt;p&gt;Since it seems like Microsoft has lost the lead in the mobile space I think the only way out of the Apple-opoly is to bring their awesome set of developer tools to the iPhone. The lure of Visual Studio and C# / VB.net shouldn&#39;t be under estimated. If developers could easily make cross platform applications that ran on both the iPhone and Windows Mobile/Blackberry/Android it would be a big step towards breaking that lock-in.&lt;/p&gt; &lt;p&gt;Who&#39;s working towards bringing the C# and the CLR to the iPhone? &lt;a href=&quot;http://www.mono-project.com/MonoTouch&quot;&gt;Novell&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It seems like a strange move but I&#39;m very keen to try it out...&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/543176285648880243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/543176285648880243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/543176285648880243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/543176285648880243'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/08/iphone-reaching-critial-mass.html' title='iPhone Reaching Critial Mass'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-4572371555282381449</id><published>2009-06-20T22:02:00.001+10:00</published><updated>2009-06-20T22:02:01.380+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Mercurial"/><category scheme="http://www.blogger.com/atom/ns#" term="Subversion"/><category scheme="http://www.blogger.com/atom/ns#" term="TWAIN"/><category scheme="http://www.blogger.com/atom/ns#" term="TwainDotNet"/><title type='text'>TWAIN Dot Net</title><content type='html'>&lt;p&gt;I just released the first version of &lt;a href=&quot;http://code.google.com/p/twaindotnet/&quot;&gt;TwainDotNet&lt;/a&gt;, a &lt;a href=&quot;http://en.wikipedia.org/wiki/TWAIN&quot;&gt;TWAIN&lt;/a&gt; library for the .net framework. It is an open source, MIT licensed work built on top of Thomas Scheidegger&#39;s article from The Code Project: &lt;a href=&quot;http://www.codeproject.com/KB/dotnet/twaindotnet.aspx&quot;&gt;.NET TWAIN image scanner&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I had two main reasons for starting the project on code.google.com. Firstly code attached to an article provides no way for people to collaborate. There is no issue tracking, not place to feed back changes, etc. Secondly, I wanted to change the code to work with WPF and feed those changes back to everyone else!&lt;/p&gt; &lt;p&gt;So anyway the code is now up there and an initial binary available for download. I&#39;ve picked the MIT license since it seems to fit the spirit of Thomas&#39;s original public domain dedication but with limitation of liability. And hopefully now there will be a bit more collaboration! :)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;On a side note I&#39;ve tried out Mercurial for the first time. The python based TortoiseHg is not quite as polished at TortoiseSvn but it is still very easy to use. I will seriously be thinking about moving my other Subversion projects over to Mercurial at a point in the future...&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/4572371555282381449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/4572371555282381449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4572371555282381449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4572371555282381449'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/06/twain-dot-net.html' title='TWAIN Dot Net'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-8012937686480181352</id><published>2009-06-01T19:10:00.001+10:00</published><updated>2009-06-01T19:10:10.599+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Exchange Server"/><category scheme="http://www.blogger.com/atom/ns#" term="MAPI"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Exchange Wedding Anniversary?</title><content type='html'>&lt;p&gt;I saw this in the Microsoft &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc433490.aspx&quot;&gt;&quot;Exchange Server Protocols Master Property List Specification&quot;&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;2.932 PidTagWeddingAnniversary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Canonical name:&lt;/strong&gt; PidTagWeddingAnniversary  &lt;p&gt;&lt;strong&gt;Property ID:&lt;/strong&gt; 0x3A41  &lt;p&gt;&lt;strong&gt;Data type:&lt;/strong&gt; PtypTime, 0x0040  &lt;p&gt;&lt;strong&gt;Area:&lt;/strong&gt; MapiMailUser  &lt;p&gt;&lt;strong&gt;References:&lt;/strong&gt; [MS-OXOABK], [MS-OXOCNTC]  &lt;p&gt;&lt;strong&gt;Alternate names:&lt;/strong&gt; PR_WEDDING_ANNIVERSARY&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Its quite funny how much detail you can put onto a contact in Exchange!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/8012937686480181352/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/8012937686480181352' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8012937686480181352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8012937686480181352'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/06/exchange-wedding-anniversary.html' title='Exchange Wedding Anniversary?'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-6965231917230557355</id><published>2009-06-01T18:59:00.001+10:00</published><updated>2009-06-01T18:59:00.696+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="ASP.net"/><category scheme="http://www.blogger.com/atom/ns#" term="Deployment"/><category scheme="http://www.blogger.com/atom/ns#" term="IIS"/><category scheme="http://www.blogger.com/atom/ns#" term="Links"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>June Links - ASP.net Deployment &amp;amp; Misc</title><content type='html'>&lt;h1&gt;ASP.net&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://serverfault.com/questions/1954/windows-web-server-checklist&quot;&gt;Window web server checklist&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/319009/asp-net-basic-checklist-for-putting-a-site-into-production&quot;&gt;ASP.net production checklist&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/62816/what-could-be-good-ways-to-deploy-asp-net-web-applications&quot;&gt;Good ways to deploy ASP.net web apps&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/72394/what-should-a-developer-know-before-building-a-public-web-site&quot;&gt;What should developers know before building a public web site&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.codinghorror.com/blog/archives/001167.html&quot;&gt;Protecting your cookies&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;HTML Sanitisation&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://refactormycode.com/codes/333-sanitize-html&quot;&gt;Jeff Atwood&#39;s HTML sanitisation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://refactormycode.com/codes/360-balance-html-tags#refactor_14126&quot;&gt;and his balance HTML tags&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/6965231917230557355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/6965231917230557355' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/6965231917230557355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/6965231917230557355'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/06/june-links-aspnet-deployment-misc.html' title='June Links - ASP.net Deployment &amp;amp; Misc'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-8322886161792755835</id><published>2009-05-22T23:59:00.001+10:00</published><updated>2009-05-23T00:00:14.657+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="NSsh"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>NSsh Progress</title><content type='html'>&lt;p&gt;I&#39;ve made some more progress with &lt;a href=&quot;http://nssh.codeplex.com/&quot;&gt;NSsh&lt;/a&gt; recently. Password based authentication is now basically complete. The next hurdle is getting public key authentication working - which is not only extremely useful but required by the SSH specification.&lt;/p&gt; &lt;p&gt;Surprisingly the main hurdle is not the task of validating the key that the user sends over for authentication (there are plenty of open source examples for that). Instead the Windows API is causing problems, specifically creating a process for the user.&lt;/p&gt; &lt;p&gt;To create a process for a user a &lt;em&gt;token&lt;/em&gt; is required. This token can easily be created using Windows API calls that take a password. However without a password the alternatives are less attractive. If the machine is on a domain it is possible to perform Kerberos authentication using a &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/td3046fc.aspx&quot;&gt;constructor&lt;/a&gt; on the WindowsIdentity class. But, the only other alternative is to use the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa374780.aspx&quot;&gt;CreateToken&lt;/a&gt; / &lt;a href=&quot;http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Token/NtCreateToken.html&quot;&gt;NtCreateToken&lt;/a&gt; functions. As &lt;a href=&quot;http://stackoverflow.com/questions/559719/windows-impersonation-from-c/574656#574656&quot;&gt;one person&lt;/a&gt; puts it:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&quot;It&#39;s possible, although it requires you to do a lot of code.&quot;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Hmmm, that doesn&#39;t sound good.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/8322886161792755835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/8322886161792755835' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8322886161792755835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8322886161792755835'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/05/nssh-progress.html' title='NSsh Progress'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-2175317723590955398</id><published>2009-05-22T23:42:00.001+10:00</published><updated>2009-05-22T23:42:41.496+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Export Processing</title><content type='html'>&lt;p&gt;Here is a screen shot of &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx&quot;&gt;Process Explorer&#39;s&lt;/a&gt; system information dialog while my export processing code is running. The glitches in the IO graph are the write-cache thread flushing its data in the background. Anyway I think it looks nice :-)&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEspg9MQj0tvDKCHDzVbL8_Z8xV5-UPWkdvQ2doeav24Y10YD5ikB0BO0oO-gLEub3bJOvuFAo69HhLucOzuRjPpDDw1ME_UuhKuhFk9pcifSyqHnN1ZEc52ycYjyqsI-78kIqRqxxzns/s1600-h/export%5B6%5D.png&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;378&quot; alt=&quot;export&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdGYbXgdHoWNRez8YzhvCDWevLPJ8a4Bg3AJvoAsme0oEiAq57bVXuUYyO_wgN1Oij9mV8TDyTyDnwTHq09HGCWOZjbl-aRATO76UITkpgyN9eGcV8M6hWNVLMc4YMZ0z-F_kP53orpcU/?imgmax=800&quot; width=&quot;460&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/2175317723590955398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/2175317723590955398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2175317723590955398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2175317723590955398'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/05/export-processing.html' title='Export Processing'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdGYbXgdHoWNRez8YzhvCDWevLPJ8a4Bg3AJvoAsme0oEiAq57bVXuUYyO_wgN1Oij9mV8TDyTyDnwTHq09HGCWOZjbl-aRATO76UITkpgyN9eGcV8M6hWNVLMc4YMZ0z-F_kP53orpcU/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-7628778921500046811</id><published>2009-04-14T21:03:00.001+10:00</published><updated>2009-04-14T21:06:36.066+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Garbage Collection"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Memory Management"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><category scheme="http://www.blogger.com/atom/ns#" term="Smart Pointers"/><title type='text'>Smart Pointers != Managed Automatic Memory Management</title><content type='html'>&lt;p&gt;I posted an &lt;a href=&quot;http://stackoverflow.com/questions/228620/garbage-collection-in-c-why/228765#228765&quot;&gt;answer&lt;/a&gt; on a stackoverflow question about C++ and garbage collection. My answer wasn&#39;t ideal and caused a bit of discussion in the comments so I thought I would just sum things up here.&lt;/p&gt; &lt;h1&gt;Manual (Traditional) Memory Management&lt;/h1&gt; &lt;p&gt;Manual memory management places the onus of memory management on the programmer. It is the style of memory management available to C and C++ developers. Here are some of the attributes of manual memory management:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Slow free-list allocation. To allocate memory in this style of memory management the runtime library consults a free list to find a free block. When allocating lots of blocks this can be slower than bump-pointer allocation.&lt;/li&gt; &lt;li&gt;No locality benefits. Blocks allocated sequentially won&#39;t usually be allocated next to each other. Later when some blocks are freed the remaining blocks a fixed in place and can&#39;t be moved.&lt;/li&gt; &lt;li&gt;Data is harder to share between modules. Module writers must manually decide who is responsible for freeing data and when it can be freed.&lt;/li&gt; &lt;li&gt;Invalid and dangling pointers are possible. Blocks can be freed multiple times. Every allocation must be checked. Etc, etc, etc..&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;Automatic Dynamic Memory Management&lt;/h1&gt; &lt;p&gt;This is usually referred to as garbage collection and is the type of memory management used in Java, C#, Python, Ruby, etc, etc. Here are some memory management strategies possible with automatic GC:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fast bump pointer allocation. Objects can be allocated using a bump pointer and then promoted to a free-list manage space only if they live. Alternatively a copying or compacting GC may always allocate with a bump pointer.&lt;/li&gt; &lt;li&gt;Locality benefits. Since objects can be moved and references updated objects can be allocated and later moved to improve locality. This results in better CPU cache usage.&lt;/li&gt; &lt;li&gt;No pointer problems, easy to share data between modules, etc, etc.&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;Smart Pointers&lt;/h1&gt; &lt;p&gt;Some people argue that the answer to the problems of manual memory management is using &lt;a href=&quot;http://en.wikipedia.org/wiki/Smart_pointer&quot;&gt;smart pointers&lt;/a&gt;. They are certainly better than using nothing however they only provide the most primitive implementation of reference counting:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Unbounded cost on decrement. If the root of a large data structure is decremented to zero there is an unbounded cost to free all the data. &lt;em&gt;(I personally find this property amusing since this problem is often an argument against&lt;/em&gt; &lt;em&gt;GC)&lt;/em&gt;&lt;/li&gt; &lt;li&gt;Manual cycle collection. To prevent cyclic data structures from leaking memory the programmer must manually break any potential structures by replacing part of the cycle with a weak smart pointer. This is simply another source of potential defects.&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;First Class Reference Counting&lt;/h1&gt; &lt;p&gt;Reference counting garbage collection has several advantages over smart pointers (beyond the base GC advantages).&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Changes to an object reference count are ignored for stack and register references. Instead when a GC is triggered these objects are retained by collecting a root set.&lt;/li&gt; &lt;li&gt;Changes to the reference count can be deferred and processed in batches. This results in &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=390011.808261&quot;&gt;higher throughput&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;It is possible to &lt;a href=&quot;http://portal.acm.org/citation.cfm?id=1111596.1111597&quot;&gt;coalesce&lt;/a&gt; changes to the reference count. This makes it possible to ignore most changes to an objects reference count improving RC performance for frequently mutated references.&lt;/li&gt; &lt;li&gt;Incremental cycle detection cost. It is possible to process cycle detection tasks in bounded chunks at GC time.&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;Summary&lt;/h1&gt; &lt;p&gt;Automatic memory management has several technical advantages over manual memory management. When you factor in the reduced cost of development and maintenance when using garbage collection you should be in front.&lt;/p&gt; &lt;p&gt;For details of a high performance reference counting GC implementation look at &lt;a href=&quot;http://cs.anu.edu.au/~Steve.Blackburn/pubs/papers/urc-oopsla-2003.pdf&quot;&gt;this paper&lt;/a&gt;.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/7628778921500046811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/7628778921500046811' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/7628778921500046811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/7628778921500046811'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/04/smart-pointers-managed-automatic-memory.html' title='Smart Pointers != Managed Automatic Memory Management'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-209421505164235061</id><published>2009-03-25T21:08:00.001+11:00</published><updated>2009-03-25T21:08:57.636+11:00</updated><title type='text'>Net Censorship in Australia</title><content type='html'>&lt;p&gt;Current the planned Australian Internet filter&amp;nbsp; and the Australian Communications and Media Authority (ACMA) are causing quite a bit of controversy. The ACMA&#39;s Internet blacklist was leaked and there were some disturbing entries on the list. Among the entries were a Queensland dentist&#39;s website, a tour operator, and after disclosing the contents, wikileaks has been added to the list.&lt;/p&gt; &lt;h1&gt;Transparency&lt;/h1&gt; &lt;p&gt;There are two problems with the current blacklist as it stands. Firstly, a site that links to a blacklisted or illicit site is also blacklisted. The prime example of this is wikileaks.org which was blacklisted after disclosing the ACMA&#39;s blacklist. Media outlets have also been threatened with an $11,000 a day fine for linking to banned sites. This is insanity: &lt;/p&gt; &lt;ul&gt; &lt;li&gt; What if you link to a site then at a later date it posts offending material?&lt;/li&gt; &lt;li&gt;What if a site is placed onto the blacklist after you&#39;ve linked to it?&lt;/li&gt; &lt;li&gt;What if a user posts a black listed link onto a forum you control?&lt;/li&gt; &lt;li&gt;&lt;strong&gt;The link itself doesn&#39;t contain any illicit material.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;It seems like a violation of free speech to prevent someone from discussing illicit material, how is linking to it any different? Of course the linking issue it the key issue being played out in music sharing cases such as the current trial for &lt;a href=&quot;http://en.wikipedia.org/wiki/The_Pirate_Bay_trial&quot;&gt;&quot;The Pirate Bay&quot;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Secondly, the list is secret and thus there is no accountability. The &lt;a href=&quot;http://www.computerworld.com.au/article/295977/australia_internet_filter_ruled_by_single_bureaucrat?pp=1&amp;amp;fp=39&amp;amp;fpid=27794&quot;&gt;article on ComputerWorld&lt;/a&gt; claims that the decision to add a site to the list can be made by a single bureaucrat. Without the list being disclosed how can there be any accountability for government. They may argue that disclosing the list will provide a central point for people to look for the offending illicit material (child pornography, etc). However:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;People know how to get to illicit material anyway. Pedophile networks can be &lt;a href=&quot;http://www.schneier.com/blog/archives/2009/03/the_techniques.html&quot;&gt;extremely sophisticated and secure&lt;/a&gt;. &lt;/li&gt; &lt;li&gt;If the governments filter is put in place all those sites will be blocked anyway.&lt;/li&gt;&lt;/ul&gt; &lt;h1&gt;Leave it to the Experts&lt;/h1&gt; &lt;p&gt;There is already a lot of evidence that the Internet filtering plan will not work out (including ACMA&#39;s own reports). Instead of entering into an unaccountable Internet censorship setup, I feel that we should direct the funding into our state and federal police bodies. They are already doing a &lt;a href=&quot;http://www.abc.net.au/news/stories/2008/03/06/2181544.htm&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;http://www.abc.net.au/news/stories/2009/01/17/2468237.htm&quot;&gt;job&lt;/a&gt; but could use the extra support. In NSW the police have just recently been given a &lt;a href=&quot;http://www.abc.net.au/news/stories/2008/03/06/2182021.htm&quot;&gt;boost to their online powers&lt;/a&gt; but only with a warrant - already much more accountable than a secret list.&lt;/p&gt; &lt;h1&gt;Further Reading&lt;/h1&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://www.smh.com.au/news/home/technology/banned-hyperlinks-could-cost-you-11000-a-day/2009/03/17/1237054787635.html?page=fullpage&quot;&gt;Banned hyperlinks could cost you $11,000 a day&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.efa.org.au/Issues/Censor/cens1.html&quot;&gt;Internet Censorship Laws in Australia&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Internet_censorship&quot;&gt;Internet censorship&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://news.smh.com.au/breaking-news-technology/australian-internet-blacklist-prompts-concern-20090321-94mh.html&quot;&gt;Australian Internet &#39;blacklist&#39; prompts concern&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.abc.net.au/news/stories/2009/02/03/2480743.htm&quot;&gt;Net filter &#39;will give parents a false sense of security&#39;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.getup.org.au/campaign/SaveTheNet/442&quot;&gt;Getup! - Save The Net&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/209421505164235061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/209421505164235061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/209421505164235061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/209421505164235061'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/03/net-censorship-in-australia.html' title='Net Censorship in Australia'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-2232654782160228832</id><published>2009-03-17T22:58:00.001+11:00</published><updated>2009-03-17T22:58:54.835+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Links"/><category scheme="http://www.blogger.com/atom/ns#" term="Parallel Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="SOLID"/><title type='text'>Interesting Links</title><content type='html'>&lt;ul&gt; &lt;li&gt;&lt;a href=&quot;http://www.lostechies.com/blogs/derickbailey/archive/2009/02/11/solid-development-principles-in-motivational-pictures.aspx&quot;&gt;SOLID principles as motivational pictures&lt;/a&gt; - an excellent succinct way to explain the SOLID principles.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.ohloh.net/p/8830&quot;&gt;ohloh&lt;/a&gt; - a site that provides stats on open source projects.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://channel9.msdn.com/pdc2008/TL26/&quot;&gt;Parallel extensions for .net&lt;/a&gt; - a library for writing parallel applications in .net. Daniel Moth explains some of the details (&lt;a href=&quot;http://www.danielmoth.com/Blog/2008/11/new-and-improved-clr-4-thread-pool.html&quot;&gt;improved thread pool&lt;/a&gt;, &lt;a href=&quot;http://www.danielmoth.com/Blog/2008/12/introducing-new-task-type.html&quot;&gt;tasks&lt;/a&gt;, &lt;a href=&quot;http://www.danielmoth.com/Blog/2009/01/parallelising-loops-in-net-4.html&quot;&gt;parallel for loops&lt;/a&gt;).&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/2232654782160228832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/2232654782160228832' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2232654782160228832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2232654782160228832'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/03/interesting-links.html' title='Interesting Links'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-4704826165056203249</id><published>2009-03-08T23:34:00.002+11:00</published><updated>2009-03-08T23:42:20.628+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Exceptions"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="SNR"/><title type='text'>Java Exceptions</title><content type='html'>&lt;p&gt;Checked exceptions... they cause me pain. At first glance they seem to provide a way for design by contract to include exceptions. However they only increase complexity and have limited usefulness for design by contract.&lt;/p&gt; &lt;h1&gt;SNR&lt;/h1&gt; &lt;p&gt;Firstly, they increase the &lt;em&gt;&quot;signal-to-noise ratio&quot;&lt;/em&gt; for the code. The SNR for code determines how clear your code is (someone else coined that term - but try Google for it!). Anders Hejlsberg also talks about imperative vs &lt;a href=&quot;http://en.wikipedia.org/wiki/Declarative_programming&quot;&gt;declarative programming&lt;/a&gt; which is a similar concept. Anyway consider the following code snippets:&lt;/p&gt; &lt;p&gt;Update UI from non UI-thread in Java:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;try&lt;br /&gt;{&lt;br /&gt;   // Run the update code on the Swing thread&lt;br /&gt;   SwingUtilities.invokeAndWait(new Runnable()&lt;br /&gt;   {&lt;br /&gt;       @Override&lt;br /&gt;       public void run()&lt;br /&gt;       {&lt;br /&gt;           try&lt;br /&gt;           {&lt;br /&gt;               // Update UI value from the file system data&lt;br /&gt;               FileUtility f = new FileUtility();&lt;br /&gt;               uiComponent.setValue(f.readSomething());&lt;br /&gt;           }&lt;br /&gt;           catch (IOException e)&lt;br /&gt;           {&lt;br /&gt;               throw new IllegalStateException(&quot;Error performing file operation.&quot;, e);&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;catch (InterruptedException ex)&lt;br /&gt;{&lt;br /&gt;   throw new IllegalStateException(&quot;Interrupted updating UI&quot;, ex);&lt;br /&gt;}&lt;br /&gt;catch (InvocationTargetException ex)&lt;br /&gt;{&lt;br /&gt;   throw new IllegalStateException(&quot;Invocation target exception updating UI&quot;, ex&quot;);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Update UI from non UI-thread in C#:&lt;/p&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private void UpdateValue()&lt;br /&gt;{&lt;br /&gt;   // Ensure the update happens on the UI thread&lt;br /&gt;   if (InvokeRequired)&lt;br /&gt;   {&lt;br /&gt;       Invoke(new MethodInvoker(UpdateValue));&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;       // Update UI value from the file system data&lt;br /&gt;       FileUtility f = new FileUtility();&lt;br /&gt;       uiComponent.Value = f.ReadSomething();&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The UI threading code in the C# example still adds some extra noise so I like to use &lt;a href=&quot;http://www.postsharp.org/&quot;&gt;Postsharp&lt;/a&gt; to reduce it down to this:&lt;/p&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;[UIMethod]&lt;br /&gt;private void UpdateValue()&lt;br /&gt;{&lt;br /&gt;   // Update UI value from the file system data&lt;br /&gt;   FileUtility f = new FileUtility();&lt;br /&gt;   uiComponent.Value = f.ReadSomething();&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Which seems a &lt;em&gt;lot&lt;/em&gt; clearer to me. When you start to do more and more UI work in Swing checked exceptions start to become really annoying and useless.&lt;/p&gt;&lt;br /&gt;&lt;h1&gt;Jail Break&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;To implement even the most basic of implementations, such as Java&#39;s &lt;a href=&quot;http://java.sun.com/j2se/1.4.2/docs/api/java/util/List.html&quot;&gt;List interface&lt;/a&gt;, checked exceptions as a tool for design by contract fall down. Consider a list that is backed by a database or a filesystem or any other implementation that throws a checked exception. The only possible implementation is to catch the checked exception and rethrow it as an unchecked exception:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public void clear()&lt;br /&gt;{&lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;       backingImplementation.clear();&lt;br /&gt;   }&lt;br /&gt;   catch (CheckedBackingImplException ex)&lt;br /&gt;   {&lt;br /&gt;       throw new IllegalStateException(&quot;Error clearing underlying list.&quot;, ex);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And now you have to ask what is the point of all that code? The checked exceptions just add noise, the exception has been caught but not &lt;em&gt;handled&lt;/em&gt; and design by contract (in terms of checked exceptions) has broken down.&lt;/p&gt;&lt;br /&gt;&lt;h1&gt;Service, s&#39;il vous plaît?&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;When the cost of checked exceptions starts to kick in (wrapping in unchecked exceptions, millions of checked exceptions) you can see code like this in response:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;try&lt;br /&gt;{&lt;br /&gt;   // Perform some action&lt;br /&gt;}&lt;br /&gt;catch (Exception e)&lt;br /&gt;{&lt;br /&gt;   log.warn(&quot;Unexpected exception processing action&quot;, e);&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;The problem with this code is &lt;a href=&quot;http://blogs.msdn.com/clrteam/archive/2009/02/19/why-catch-exception-empty-catch-is-bad.aspx&quot;&gt;well documented&lt;/a&gt; in the .net world. Basically if you can&#39;t handle the exception then step aside. &lt;/p&gt;&lt;br /&gt;&lt;h1&gt;Summary&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;In non-trivial situations all of the above problems compound making debugging and maintaining code harder. They add noise to the code and the usefulness as a design by contract mechanism is questionable.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Really, in Java the divide between checked exceptions and runtime exceptions should have been a red flag: some exceptions are are unexpected.  Exceptions are for exceptional circumstances and you don&#39;t always want to deal with exceptional circumstances at all levels in your code.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/4704826165056203249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/4704826165056203249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4704826165056203249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/4704826165056203249'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/03/java-exceptions.html' title='Java Exceptions'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-8266598921853218993</id><published>2009-03-03T19:29:00.005+11:00</published><updated>2009-03-08T23:43:27.696+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".net"/><category scheme="http://www.blogger.com/atom/ns#" term="Benchmarks"/><category scheme="http://www.blogger.com/atom/ns#" term="Finalizer"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><title type='text'>Java Suppress Finalizer</title><content type='html'>&lt;p&gt;A colleague pointed my to Dr Heinz M. Kabutz&#39;s article on &lt;a href=&quot;http://www.javaspecialists.eu/archive/Issue170.html&quot;&gt;Java finalizers&lt;/a&gt;. The article compares the performance of objects that have a trivial (empty) finalizer vs those that have a very simple finalizer. The basic outcome is that the running time for the non-trivial case is orders of magnitude larger than the trivial case.&lt;/p&gt; &lt;p&gt;I was quite shocked when I saw this since the simple finalizer given in the example is similar to what is proposed in .net &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms244737.aspx&quot;&gt;IDisposable pattern&lt;/a&gt;. I was thinking &lt;em&gt;&quot;Holy Smoke, Batman! How can it really be that bad??&quot;&lt;/em&gt;. The answer is in Jack Shirazi&#39;s &lt;a href=&quot;http://www.fasterj.com/articles/finalizer1.shtml&quot;&gt;article&lt;/a&gt;: basically the finalizer causes the object to live through the nursery collection and thus puts much more pressure on the mature space collector.&lt;/p&gt; &lt;h1&gt;.net?&lt;/h1&gt; &lt;p&gt;I decided to implement the test in C# quickly and see how it performed. Here is the code:&lt;/p&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace ConsoleApplication1&lt;br /&gt;{&lt;br /&gt;public class ConditionalFinalizer&lt;br /&gt;{&lt;br /&gt;    private static readonly bool DEBUG = false;&lt;br /&gt;&lt;br /&gt;    // Should be volatile as it is accessed from multiple threads.&lt;br /&gt;    // Thanks to Anton Muhin for pointing that out.&lt;br /&gt;    private volatile bool resourceClosed;&lt;br /&gt;    private readonly int id;&lt;br /&gt;&lt;br /&gt;    public ConditionalFinalizer(int id)&lt;br /&gt;    {&lt;br /&gt;        this.id = id;&lt;br /&gt;        resourceClosed = false;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ~ConditionalFinalizer()&lt;br /&gt;    {&lt;br /&gt;        if (DEBUG)&lt;br /&gt;        {&lt;br /&gt;            if (!resourceClosed)&lt;br /&gt;            {&lt;br /&gt;                Console.Error.WriteLine(&quot;You forgot to close the resource with id &quot; + id);&lt;br /&gt;            }&lt;br /&gt;            resourceClosed = true;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void close()&lt;br /&gt;    {&lt;br /&gt;        resourceClosed = true;&lt;br /&gt;        GC.SuppressFinalize(this);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Program&lt;br /&gt;{&lt;br /&gt;    static void Main(string[] args)&lt;br /&gt;    {&lt;br /&gt;        // Allow the JIT to warm up&lt;br /&gt;        for (int i = 0; i &amp;lt; 10 * 1000 * 1000; i++)&lt;br /&gt;        {&lt;br /&gt;            ConditionalFinalizer cf = new ConditionalFinalizer(i);&lt;br /&gt;            if (i % (1000 * 1000) != 0)&lt;br /&gt;            {&lt;br /&gt;                cf.close();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        DateTime start = DateTime.Now;&lt;br /&gt;&lt;br /&gt;        for (int i = 0; i &amp;lt; 10 * 1000 * 1000; i++)&lt;br /&gt;        {&lt;br /&gt;            ConditionalFinalizer cf = new ConditionalFinalizer(i);&lt;br /&gt;            if (i % (1000 * 1000) != 0)&lt;br /&gt;            {&lt;br /&gt;                cf.close();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        TimeSpan time = DateTime.Now - start;&lt;br /&gt;        Console.WriteLine(&quot;time = &quot; + time.TotalMilliseconds);&lt;br /&gt;&lt;br /&gt;        Console.ReadKey();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;The most important change is the added call to &quot;GC.SuppressFinalize&quot;. This test case is the specific reason for this call - basically it removes the object from the finalization queue thus allowing it to be collected in the nursery collection. I also added an initial loop to allow the JIT to compile the classes in use. Here are the results:&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitLqs4Dc3jXAbB-jVDyTotGr65FX_llBG_5-HoRIYx5IhrqGwHZrx5mtmLqx6idpsvSDFWN7tTyIFpD9GmFkIP7_P3gEkie2RusLBitGBbnMkJar6KtKVbG-V9oLd0fqWmAqA04VSOgZE/s1600-h/DotnetPerformance%5B6%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;275&quot; alt=&quot;DotnetPerformance&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnLewIWtD5hp0SvXDL0x3LfBiaRKx4xwzAlrnK9ILVzx4CIRBK-AnNpAcnQyuLvUGCQOEPcd1TyhTe2PHN17OnmX1A61ouYGpOYAoSOo1_0QnAMoGKJtU-gfbee_Z3JAjgArO2LgBpt0I/?imgmax=800&quot; width=&quot;428&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Calling &quot;GC.SuppressFinalize&quot; dramatically improves the performance for .net and my initial results line up with Dr Kabutz&#39;s. Java really does a neat optimisation for the trivial finalizer case! Unfortunately it also gets smashed in the non-trivial case...&lt;/p&gt;&lt;br /&gt;&lt;h1&gt;Java&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;Dr Kabutz&#39;s code for showing the classes pending finalization goes 90% of the way towards providing something similar to &quot;GC.SuppressFinalize&quot;, I decided to add that last little bit:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;import java.lang.ref.Reference;&lt;br /&gt;import java.lang.reflect.Field;&lt;br /&gt;&lt;br /&gt;public class FinalizeHelper {&lt;br /&gt;&lt;br /&gt;static FinalizeHelper finalizeHelper = new FinalizeHelper();&lt;br /&gt;&lt;br /&gt;private final Class&amp;lt;?&amp;gt; finalizerClazz;&lt;br /&gt;private final Object lock;&lt;br /&gt;private final Field unfinalizedField;&lt;br /&gt;private final Field nextField;&lt;br /&gt;private final Field prevField;&lt;br /&gt;private final Field referentField;&lt;br /&gt;&lt;br /&gt;public FinalizeHelper() {&lt;br /&gt;    try {&lt;br /&gt;        finalizerClazz = Class.forName(&quot;java.lang.ref.Finalizer&quot;);&lt;br /&gt;&lt;br /&gt;        // we need to lock on this field to avoid racing conditions&lt;br /&gt;        Field lockField = finalizerClazz.getDeclaredField(&quot;lock&quot;);&lt;br /&gt;        lockField.setAccessible(true);&lt;br /&gt;        lock = lockField.get(null);&lt;br /&gt;&lt;br /&gt;        // the start into the linked list of finalizers&lt;br /&gt;        unfinalizedField = finalizerClazz.getDeclaredField(&quot;unfinalized&quot;);&lt;br /&gt;        unfinalizedField.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        // the next element in the linked list&lt;br /&gt;        nextField = finalizerClazz.getDeclaredField(&quot;next&quot;);&lt;br /&gt;        nextField.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        // the prev element in the linked list&lt;br /&gt;        prevField = finalizerClazz.getDeclaredField(&quot;prev&quot;);&lt;br /&gt;        prevField.setAccessible(true);&lt;br /&gt;&lt;br /&gt;        // the object that the finalizer is defined on&lt;br /&gt;        referentField = Reference.class.getDeclaredField(&quot;referent&quot;);&lt;br /&gt;        referentField.setAccessible(true);&lt;br /&gt;&lt;br /&gt;    } catch (RuntimeException e) {&lt;br /&gt;        throw e;&lt;br /&gt;    } catch (Exception e) {&lt;br /&gt;        throw new IllegalStateException(&quot;Could not create FinalizeHelper&quot;, e);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private void suppress(Object instance) {&lt;br /&gt;    try {&lt;br /&gt;        synchronized (lock) {&lt;br /&gt;            // Get the start of the un-finalized list&lt;br /&gt;            Object current = unfinalizedField.get(null);&lt;br /&gt;            Object previous = null;&lt;br /&gt;&lt;br /&gt;            while (current != null) {&lt;br /&gt;                Object value = referentField.get(current);&lt;br /&gt;&lt;br /&gt;                // Check if this entry refers to the instance we are interested in&lt;br /&gt;                if (value == instance) {&lt;br /&gt;                    // Unlink the current entry from the queue&lt;br /&gt;                    Object next = nextField.get(current);                    &lt;br /&gt;                    if (previous == null) {&lt;br /&gt;                        unfinalizedField.set(null, next);&lt;br /&gt;                        prevField.set(next, null);&lt;br /&gt;                    } else {&lt;br /&gt;                        nextField.set(previous, next);&lt;br /&gt;                        prevField.set(next, previous);&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                // Move to the next entry&lt;br /&gt;                previous = current;&lt;br /&gt;                current = nextField.get(current);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    } catch (IllegalAccessException e) {&lt;br /&gt;        throw new IllegalStateException(e);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static void suppressFinalize(Object instance) {&lt;br /&gt;    finalizeHelper.suppress(instance);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Here is the updated test files:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public class ConditionalFinalizer {&lt;br /&gt;private static final boolean DEBUG = false;&lt;br /&gt;&lt;br /&gt;// Should be volatile as it is accessed from multiple threads.&lt;br /&gt;// Thanks to Anton Muhin for pointing that out.&lt;br /&gt;private volatile boolean resourceClosed;&lt;br /&gt;private final int id;&lt;br /&gt;&lt;br /&gt;public ConditionalFinalizer(int id) {&lt;br /&gt;    this.id = id;&lt;br /&gt;    resourceClosed = false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected void finalize() throws Throwable {&lt;br /&gt;    if (DEBUG) {&lt;br /&gt;        if (!resourceClosed) {&lt;br /&gt;            System.err.println(&quot;You forgot to close the resource with id &quot; + id);&lt;br /&gt;        }&lt;br /&gt;        resourceClosed = true;&lt;br /&gt;        super.finalize();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void close() {&lt;br /&gt;    resourceClosed = true;&lt;br /&gt;    FinalizeHelper.suppressFinalize(this);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;and:&lt;/p&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public class ConditionalFinalizerTest1 {&lt;br /&gt;public static void main(String[] args) throws InterruptedException {&lt;br /&gt;    long time = System.currentTimeMillis();&lt;br /&gt;    for (int i = 0; i &amp;lt; 10 * 1000 * 1000; i++) {&lt;br /&gt;        ConditionalFinalizer cf = new ConditionalFinalizer(i);&lt;br /&gt;        if (i % (1000 * 1000) != 0) {&lt;br /&gt;            cf.close();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    time = System.currentTimeMillis() - time;&lt;br /&gt;    System.out.println(&quot;time = &quot; + time);&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And here are the updated results:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzYtCX0G85k9dcfAKnKQfv2NZzF6anmnoFJIy6SNm8FC27e5PltZdZBe4kOd7cN8b9RBgicHO-nOp8rxgD0JcchGP36TfSVnLE2jkIOxxYwKbAeKyMgYyvIX3JpSB99Af5fR2QNJ2L1ag/s1600-h/DotnetPerformance2%5B4%5D.png&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;276&quot; alt=&quot;DotnetPerformance2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdA87sDiJ0j7-60_KVqSRhqXu43mTwbzG95v82OQPm76TCl8x4YtYuODVJioIN3nQjVRg8prJ6rt_Oy4AJoSL3oOa2UPOLEp4Rt_tklyDnsHFpLBz52ZXptUxZ4xw8_N-YYeUSFPrT_Xo/?imgmax=800&quot; width=&quot;435&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;Suppressing the finalizer for those objects significantly increases the performance of the test. The difference in performance between .net and Java is probably because I&#39;m using reflection to scan the finalizer list in the Java case.&lt;/p&gt;&lt;br /&gt;&lt;h1&gt;Summary&lt;/h1&gt;&lt;br /&gt;&lt;p&gt;There is a definite benefit to suppressing finalizers for object that get manually disposed, its just a pity that there is no native &quot;GC.SuppressFinalize&quot; method for Java. The IDiposable pattern is very useful for situations where you want to be able to:&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Manually dispose of an item when you know it is no longer needed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Be able to run clean up code to safely bring down connections, close files, etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Be able to rely on the finalizer to catch situation where it is not known when an object should be cleaned up or to catch mistakes that mean the clean code is not explicitly called.&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/8266598921853218993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/8266598921853218993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8266598921853218993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8266598921853218993'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/03/java-suppress-finalizer.html' title='Java Suppress Finalizer'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnLewIWtD5hp0SvXDL0x3LfBiaRKx4xwzAlrnK9ILVzx4CIRBK-AnNpAcnQyuLvUGCQOEPcd1TyhTe2PHN17OnmX1A61ouYGpOYAoSOo1_0QnAMoGKJtU-gfbee_Z3JAjgArO2LgBpt0I/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-80646382540859930</id><published>2009-02-02T20:33:00.001+11:00</published><updated>2009-02-02T20:33:11.845+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Joel Spolsky"/><category scheme="http://www.blogger.com/atom/ns#" term="SOLID"/><category scheme="http://www.blogger.com/atom/ns#" term="Stack Overflow"/><title type='text'>Joel on SOLID</title><content type='html'>&lt;p&gt;After listening to Jeff and Joel&#39;s Stack Overflow &lt;a href=&quot;http://blog.stackoverflow.com/2009/01/podcast-39/&quot;&gt;podcast&lt;/a&gt; today I felt like Joel had slightly missed the point of the &lt;a href=&quot;http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx&quot;&gt;SOLID&lt;/a&gt; principles. I can see how it is easy to miss the point of SOLID - an acronym of acronyms! But for me &quot;SOLID&quot; adds to design patterns and anti-patterns because it helps me to describe, more formally, when some code doesn&#39;t seem right - when code has a &quot;code smell&quot; to be a bit of a hippy about it.&lt;/p&gt; &lt;p&gt;Joel goes on to say that he doesn&#39;t think the principles apply well to real life situations, however, I think they apply perfectly. They are all about taking a pragmatic but disciplined approach. Take the current work I&#39;m doing as an example: I was asked to change our product&#39;s export function and make it parallel where possible. To start with it was a single class with a few thousand lines of code. It had a &quot;unit&quot; test to go with it that covers about 70% of the &lt;em&gt;entire&lt;/em&gt; code base when run and takes about five minutes to complete. To even think about how it might be made parallel I had to do some serious refactoring.&lt;/p&gt; &lt;p&gt;Anyway here is my interpretation of the principles and how I used them when refactoring our export code: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Single responsibility principle: Read &quot;keep it simple stupid&quot;. We literally had an Export class that did the whole export. It exported the raw data, PDF-ed if required, TIFF-ed if required, etc, etc. I changed the code so that the export class creates a WorkQueue class that determines the items to process; processors for processing items at each step; a report writer; and much more. Since parts of the system were no longer tightly coupled I could add tests for each part which ran faster and were more maintainable. Here is a simplified before and after:&lt;br&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5FvQBNr3-9TI20rGF5omdnorrSEKUqE3P67R4FXFIVnIr4PqtDKvvtLv1lyG_Sz-Fu_zQ_KDiFqaeNAXFJyOJtHwqyeMsuDynTEK-Tv-rZNMCNsDrOJHIQAAKTOrXdFnJ2InU2CWwS5Q/s1600-h/export%5B3%5D.png&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;164&quot; alt=&quot;Classes before and after.&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1wy7fRBPRRX3i8mIs04aVwV1814ggaCLHTdyhNmCxyAwC7P4wskIwrf9szu3UyOX6OBhl5zdI3kjHq9myuFGIz-R7fssajNVStVdkeAw2X_bVv9iYcsVSDJcVYcYDq9TFh2c3bHk8iM/?imgmax=800&quot; width=&quot;252&quot; border=&quot;0&quot;&gt;&lt;/a&gt; &lt;/li&gt; &lt;li&gt;Open/closed principle: extending a module shouldn&#39;t break stuff. To be honest I don&#39;t consider this principle much during my day to day work, perhaps that is due to the type of product I&#39;m working on.&lt;/li&gt; &lt;li&gt;Liskov substitution principle: have a good reason for using a base class. I feel that this strongly tied in with the SRP. For example our Exporter class inherited from BaseExporter (we have multiple types of export) and common &quot;export&quot; code was placed here. Sometimes a better solution is to place common code in a supporting class instead of inheriting. The acid test for inheritance should be am I ever going to use the base class independently of the subclasses? The LSP is about avoiding broken inheritance hierarchies. Uncle Bob gives the example of a set of number types which is excellent. He says inheritance is not &quot;is a&quot; and in the numbering example he points out that while integers are a subset of real numbers they have no commonality in terms of storage: an integer might be stored with a single 32 bit value where a real number has a mantissa and an exponent.&lt;/li&gt; &lt;li&gt;Interface segregation principle: again read &quot;keep it simple stupid&quot; but also &quot;you aren&#39;t going to need it&quot;. This is simply a principle to avoid creating fat interfaces. The point is to define a service in terms of the clients that are going to use it. This is especially important in Java where events an delegates aren&#39;t available. For example if you have an ExportListener interface that has itemProcessedNotification and itemCompletedNotification a client will have to implement both listeners even if it doesn&#39;t care about both. Fat interfaces reduce signal to noise ratio - it obscures what you are trying to do.&lt;/li&gt; &lt;li&gt;Dependency inversion principle: don&#39;t tightly couple things. If everything depends on concrete implementation classes, if there are global static singletons, etc, things will be hard to modify and test. This is especially important in C# where methods are sealed by default (in Java you can mock most classes and mock out their non-final methods). In my export code I change things so that the Exporter class only depended on abstractions such as the ExportProcessor interface. This decoupled the components and made testing easier.&lt;/li&gt;&lt;/ul&gt;  </content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/80646382540859930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/80646382540859930' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/80646382540859930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/80646382540859930'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2009/02/joel-on-solid.html' title='Joel on SOLID'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm1wy7fRBPRRX3i8mIs04aVwV1814ggaCLHTdyhNmCxyAwC7P4wskIwrf9szu3UyOX6OBhl5zdI3kjHq9myuFGIz-R7fssajNVStVdkeAw2X_bVv9iYcsVSDJcVYcYDq9TFh2c3bHk8iM/s72-c?imgmax=800" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-8993675994634995138</id><published>2008-12-10T14:04:00.005+11:00</published><updated>2009-01-21T19:54:24.803+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Inner-classes"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="SOLID"/><title type='text'>Java Inner Classes and SOLID</title><content type='html'>&lt;p&gt;I was dealing with some legacy code at work and came across some Java inner classes. Looking at those inner classes I realised that they had a bad feel to them; they break some of the &lt;a href=&quot;http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx&quot;&gt;SOLID&lt;/a&gt; principles.&lt;/p&gt;&lt;p&gt;The main problem lies with non-static inner classes. In the case of a static inner class why not just move the code out into a separate file? Some people argue that inner classes help to keep related things close together but it seems to go against the spirit of the SOLID principles. And other things aside, they completely break encapsulation.&lt;/p&gt;&lt;h1&gt;Single Responsibility Principle&lt;/h1&gt;&lt;p&gt;The single responsibility principle is about keeping things simple and manageable. However, inner classes add a highly (sometimes very highly) coupled added responsibility to a class. By adding the inner class complexity increases and testing is harder. In the case of a static inner class the two classes may be testable independently. However non-static inner classes can&#39;t be tested as an individual unit.&lt;/p&gt;&lt;h1&gt;Dependency Inversion Principle&lt;/h1&gt;&lt;p&gt;Again non-static inner classes break this principle: they are tightly coupled and depend on each other&#39;s implementation. As I mentioned above this makes testing the two classes in isolation impossible.&lt;/p&gt; &lt;h1&gt;Open/Close, Liskov Substitution and Interface Segregation Principles&lt;/h1&gt; &lt;p&gt;These principles relate more to the implementation specifics of classes. While the relationship between an inner class an its enclosing class doesn&#39;t explicitly break the principles, it must make it harder to write an outer class that complies with the principles.&lt;/p&gt;&lt;h1&gt;Anonymous Inner Classes&lt;/h1&gt;&lt;p&gt;In most cases anonymous inner classes fall into a slightly different category. Especially in Swing, anonymous inner classes are an important feature required to create clean UI code. However they are very much the exception to the norm. These sorts of small event handling classes are really just a poor substitute for language level events and delegates (such as those in the .net framework).&lt;/p&gt;&lt;h1&gt;Summary&lt;/h1&gt; &lt;p&gt;The more I consider Java inner classes the more I am inclined to avoid them. Looking at them in terms of the SOLID principles helps to outline why they can seem to complicate a class and related class design.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/8993675994634995138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/8993675994634995138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8993675994634995138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/8993675994634995138'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2008/12/java-inner-classes-and-solid.html' title='Java Inner Classes and SOLID'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-158658510765259813</id><published>2008-12-07T23:02:00.005+11:00</published><updated>2008-12-19T21:22:26.989+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Malware"/><category scheme="http://www.blogger.com/atom/ns#" term="Mobile"/><category scheme="http://www.blogger.com/atom/ns#" term="OS X"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>OSX and the Malware Economy</title><content type='html'>&lt;p&gt;&lt;/p&gt; &lt;p&gt;One thing that annoys me is when people make silly statements about IT security. After the &lt;a href=&quot;http://arstechnica.com/journals/apple.ars/2008/12/03/apples-virus-support-page-disappears-over-misunderstanding&quot;&gt;recent activity&lt;/a&gt; on the Apple forums regarding Mac anti-virus software, I found some people referencing this &lt;a href=&quot;http://www.macdailynews.com/index.php/weblog/comments/5933/&quot;&gt;old article&lt;/a&gt; claiming Mac users are safe from malware. The main part of the article that stands out to me is this quote:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;As Windows users continue to run their adware, spyware, and virus removal programs, Macintosh enthusiasts have enjoyed - literally - zero viruses. Adware and spyware are nonexistant as Mac users surf the Web without issue. OS X&#39;s UNIX shell is a secure system that keeps your computer safe, and Apple has built in a firewall for added security.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The first statement is certainly accurate, while there is an enormous amount of malware around for Windows systems there is very little around for Macs (&lt;a href=&quot;http://arstechnica.com/journals/apple.ars/2008/12/03/osx-rsplug-e-trojan-variant-goes-after-criminally-ignorant&quot;&gt;although&lt;/a&gt; &lt;a href=&quot;http://www.sophos.com/pressoffice/news/articles/2006/02/inqtana.html&quot;&gt;not&lt;/a&gt; &lt;a href=&quot;http://www.sophos.com/pressoffice/news/articles/2006/02/macosxleap.html&quot;&gt;zero&lt;/a&gt;). The second and third sentences are the sort of broad statements that are risky to make.&lt;/p&gt; &lt;p&gt;If you follow Robert Hensing&#39;s &lt;a href=&quot;http://blogs.technet.com/robert_hensing/default.aspx&quot;&gt;blog&lt;/a&gt; like I do, you&#39;ll be aware that security in OS X is not as good as some Mac users make it out to be. The links below are obviously slightly biased since Robert works for Microsoft however I feel he gives a fairly balanced point of view. Here are some examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The Mac is the first to fall in the &lt;a href=&quot;http://blogs.zdnet.com/security/?p=995&quot;&gt;pwn2own&lt;/a&gt; &lt;a href=&quot;http://blogs.technet.com/robert_hensing/archive/2008/03/27/and-the-mac-falls-within-10-minutes-on-day-2.aspx&quot;&gt;contest&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://blogs.technet.com/robert_hensing/archive/2006/11/15/osx-deepsight-security-report.aspx&quot;&gt;OS X&lt;/a&gt; &lt;a href=&quot;http://blogs.zdnet.com/security/?p=758&quot;&gt;vulnerabilities&lt;/a&gt; increasing instead of decreasing.&lt;/li&gt; &lt;li&gt;Vista, XP security &lt;a href=&quot;http://blogs.technet.com/security/archive/2008/01/23/download-windows-vista-one-year-vulnerability-report.aspx&quot;&gt;compared&lt;/a&gt; to Redhat, Ubuntu and OS X.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So if all that stuff is true why is there only a handful of malware out there for OS X?&lt;/p&gt; &lt;h1&gt;Platforms, platforms, platforms&lt;/h1&gt; &lt;p&gt;So you want to start an cybercrime shop creating and distributing malware, what things do you need to consider?&lt;/p&gt; &lt;p&gt;The first thing to sort out is probably an attack vector. Typically this is a vulnerability in some software; favourites include the browser, browser plugins, network services (such as SMB on Windows) or by just tricking the end user into installing your software.&lt;/p&gt; &lt;p&gt;If you are using a software vulnerability such as a &lt;a href=&quot;http://en.wikipedia.org/wiki/Buffer_overflow&quot;&gt;buffer overflow&lt;/a&gt; you will need to write some &quot;&lt;a href=&quot;http://en.wikipedia.org/wiki/Shellcode&quot;&gt;shellcode&lt;/a&gt;&quot; to get things started. The point of the shellcode is to provide a means to get the payload down onto the target system. It typically does this by opening a network connection to download the extra data. The tricky thing about shellcode is that it depends on the architecture of the system and probably also the operating system (e.g. if you need to open a socket to a remote host to get the payload).&lt;/p&gt; &lt;p&gt;Once you&#39;ve executed your shellcode and downloaded your payload the possibilities open up. From here you can either write your payload to disk so you can restart once the computer or browser starts up again. Alternatively you can just hang around for the current session. Again the payload depends on the system architecture and the operating system. What the malware can do all depends on what privileges it scored when the shellcode executed. This is why &lt;a href=&quot;http://blogs.technet.com/robert_hensing/archive/2008/09/03/on-chromium-and-practical-windows-sandboxing.aspx&quot;&gt;IE 8&lt;/a&gt; and &lt;a href=&quot;http://crypto.stanford.edu/websec/chromium/chromium-security-architecture.pdf&quot;&gt;Chrome&lt;/a&gt; both run with very limited privileges under Windows Vista and why Vista uses low privileges and &lt;a href=&quot;http://en.wikipedia.org/wiki/User_Account_Control&quot;&gt;UAC&lt;/a&gt; by default.&lt;/p&gt; &lt;p&gt;What this means is to put down a successful piece of malware you depend on a number of things: vulnerable software (or user error), operating system and architecture. And even then you may only exploit a low privilege user or process. A quick look at &lt;a href=&quot;http://www.metasploit.com/&quot;&gt;metasploit&lt;/a&gt; reveals something unsurprising: these are all solved problems for OS X - if you want to exploit an unpatched Mac, you can.&lt;/p&gt; &lt;h1&gt;Its a numbers game&lt;/h1&gt; &lt;p&gt;There are a few things that motivate malware writers but increasingly the trend seems to be &lt;a href=&quot;http://resources.zdnet.co.uk/articles/features/0,1000002000,39291463,00.htm&quot;&gt;financial&lt;/a&gt; &lt;a href=&quot;http://www.ftc.gov/bcp/workshops/spamsummit/presentations/Malware-Economy.pdf&quot;&gt;motivation&lt;/a&gt;. Naturally malware is going to focus on the platform with the largest market share but other factors come into play which alter the concentration of malware.&lt;/p&gt; &lt;p&gt;Firstly, you need a reason to put malware onto a device. It sounds silly but there is literally no point developing malware for a device that won&#39;t be used to store or enter valuable information such as personal details, banking details, account details. The best example of this is the mobile non-smartphone market: Nokia sold &lt;a href=&quot;http://www.reuters.com/article/technologyNews/idUSL0262945620070503&quot;&gt;200 million&lt;/a&gt; of its Nokia 1100 model phones but its WAP 1.1 browser is not exactly the thing that most people do their Internet banking with.&lt;/p&gt; &lt;p&gt;The size of the PC market (and by PC I mean all PCs not just WinTel PCs) is quite large, some estimates from last year put it at the &lt;a href=&quot;http://news.softpedia.com/news/Over-one-billion-PCs-In-Use-Worldwide-57154.shtml&quot;&gt;1.3 billion mark&lt;/a&gt;, with Windows taking about &lt;a href=&quot;http://en.wikipedia.org/wiki/Microsoft_Windows&quot;&gt;90%&lt;/a&gt; of that. As I mentioned above, a large user base is important but the Windows platform offers more that than -  it offers a standard platform. For example, a piece of malware that targets Windows NT will be able to run on Windows NT4, Windows 2000, Windows XP, Windows Server 2003, Windows Vista and Windows Server 2008. It also has a fairly standard set of applications to attack: Office, Flash, Acrobat Reader, etc. Furthermore it has loads and loads of badly written third-party &lt;a href=&quot;http://www.urbandictionary.com/define.php?term=crapplets&quot;&gt;crapplets&lt;/a&gt; that all add to attack surface. Finally, you have heaps of people running Vista without UAC and Windows XP as the administrator. Microsoft can do all the &lt;a href=&quot;http://blogs.msdn.com/sdl/&quot;&gt;threat modelling&lt;/a&gt; in the world and write the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms995349.aspx&quot;&gt;tightest code&lt;/a&gt; out there but if some Joe User clicks install when they visit a malware site all is lost. It all adds up to a malware bonanza.&lt;/p&gt; &lt;p&gt;While the Mac market share is growing it is still quite small in comparison (estimates currently range from &lt;a href=&quot;http://arstechnica.com/journals/apple.ars/2007/04/05/trends-in-mac-market-share&quot;&gt;3% to 16%&lt;/a&gt;). OS X on desktop has only been around since 2001 and in 2006 the system architecture changed from PPC to Intel. These changes along with a less stable (and possibly less crappy) API makes it less attractive for exploit, shellcode and malware writers.&lt;/p&gt; &lt;p&gt;It seems to me like you need a sort of critical mass before security researchers and malware writers will start to put serious effort towards looking into a piece of software or platform. I also think that better security practices in recent times, such as workstation firewalls and automatic updates (OS X come with both by default), combined with a smaller market share make Macs a less viable malware target.&lt;/p&gt; &lt;h1&gt;There&#39;s more than one way to skin a cat&lt;/h1&gt; &lt;p&gt;So you&#39;ve started up your cybercrime shop and decided initially to target the WinTel platform but now you&#39;re hungry for some extra cash. It turns out that there is more than one way to make money in the cybercrime economy and malware is only one of the options. Criminals are increasing using scams, &lt;a href=&quot;http://en.wikipedia.org/wiki/Image:Phishing_chart.png&quot;&gt;phishing&lt;/a&gt; and spam to target end users and often this can be done in a platform independent way - Mac users are no exception.&lt;/p&gt; &lt;p&gt;A Mac user can visit a malicious site and be unaffected but a Windows user may be infected with malware. However if enough of a target develops the malware may evolve to target things differently.&lt;/p&gt; &lt;h1&gt;A mobile focus&lt;/h1&gt; &lt;p&gt;Mobile sales are increasing and the sales of mobile &quot;smartphones&quot; is &lt;a href=&quot;http://www.appleinsider.com/articles/08/12/02/iphone_single_handedly_driving_smartphone_growth.html&quot;&gt;increasing too&lt;/a&gt;. To me, the key difference between a mobile phone and a smartphone is that you are more likely to store personal information in the smartphone and also more likely to use it for banking and other sensitive transactions. And this is a point that has not gone unnoticed; the DC 09 Black Hat conference will be focusing on embedded devices among others.&lt;/p&gt;&lt;h1&gt;Summary&lt;/h1&gt; &lt;p&gt;The moral of this story (and evident by this post) is that it is easy to throw stones. OS X has certainly had its share of security issues and Windows certainly has a strong malware industry. The point I would like to make is that perhaps Apple hasn&#39;t needed to step up their software process to the next level but things can change quickly. I also think Microsoft has stepped up to the plate after their previous security woes and also that people wine about UAC too much (if it pops up lots I think you&#39;re doing something wrong ... ). Finally, cybercrime is something that is starting to affect everyone.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/158658510765259813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/158658510765259813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/158658510765259813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/158658510765259813'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2008/12/osx-and-malware-economy.html' title='OSX and the Malware Economy'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5709001424201684592.post-2288920877222128364</id><published>2008-11-14T23:34:00.009+11:00</published><updated>2009-03-08T23:43:40.231+11:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Benchmarks"/><category scheme="http://www.blogger.com/atom/ns#" term="Dacapo"/><category scheme="http://www.blogger.com/atom/ns#" term="IKVM"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><title type='text'>IKVM Benchmarking</title><content type='html'>&lt;p&gt;I&#39;m interested in what options are available for migrating a high performance Java application over to the .net runtime. IKVM is one obvious pathway so I decided to run some quick benchmarks to gauge how well it performs.&lt;/p&gt; &lt;h1&gt;Method&lt;/h1&gt; &lt;p&gt;I ran the &lt;a href=&quot;http://www.dacapo-bench.org/&quot;&gt;DaCapo&lt;/a&gt; benchmark suite (2006-10-MR2) on my dual core PC and also a 16 core server. I allowed the execution time of the tests to converge (-converge) to help rule out startup costs and just used the default workload size. Since IVKM will have no heap restrictions I made the Java heap as large as possible. This turned out to be 1499Mb under the 32bit JVM and I limited the 64bit JVM to 2500Mb since I didn&#39;t want it to start page faulting on my box. As it turned out this was heaps [sic] of memory.&lt;/p&gt; &lt;p&gt;I took the fastest run time from the tests considering it as the &quot;least disturbed&quot; run. The graphs below are normalized to a percentage of the fastest runtime for each test so a smaller value is better. Several tests failed to run under IKVM which was a bit unfortunate - chart, eclipse and jython.&lt;/p&gt; &lt;h1&gt;Results&lt;/h1&gt; &lt;p&gt;Firstly lusearch is missing from the following results. This is because I&#39;m quite interested in this benchmark in particular and it performed so badly that it warrants further investigation...&lt;/p&gt; &lt;h2&gt;&lt;/h2&gt; &lt;h2&gt;Dual Core Machine&lt;/h2&gt; &lt;p&gt;I really should have the exact details of my machine but I don&#39;t have them handy. It is basically a dual core AMD 64 with 4Gb of RAM.&lt;/p&gt;&lt;p&gt;As you can see the results are quite mixed. Pmd and Xalan perform quite poorly, however looking at the &lt;a href=&quot;http://dacapobench.org/threads.html&quot;&gt;threading&lt;/a&gt; information and the &lt;a href=&quot;http://cs.anu.edu.au/people/Steve.Blackburn/dacapobench.org/dacapo-graphs/index.html&quot;&gt;memory stats&lt;/a&gt; nothing really jumps out. Xalan is one of the multithreaded tests however so is hsqldb in which IKVM fairs quite well.&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8DWai5LKcWyU_l9XiymQC6qsu-iIWdiaJdaL42JGEcXR9qhg1llEP82BkKhtZInvxwtipZ4vUaEnkk7GA3mp9Ki6xJhRYYMtlYXVLPXrWu_vdyAwTSSVwUdR59zPcUzakzqbabddKW6s/&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;275&quot; alt=&quot;dual-core results&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqU0zEOBsKnYUSxfu2mwGGyMFa0uBL5HFiljxGys3wfGssEiEINDOh21THES9jEF6uRSvLVZTmt4cFGpzpXEb0-Zn9EUNBPE7DZwYdOguORIhPnQ_iOqy7QINtFfZnfHaIOkRRojw7hKw/&quot; width=&quot;440&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;h2&gt;16 Core Machine&lt;/h2&gt; &lt;p&gt;Again I don&#39;t have the exact details of this box but it is a quad-quad-core with 32Gb of RAM. The extra cores seem to exaggerate the dual core results further. Interestingly, on hsqldb (one of the multithreaded tests) IKVM 32 bit outperforms the Java 64 bit VM and the 32 bit client. The other strange result is on pmd in which the 32 bit Java client is the fastest to execute - I suspect this is a copy paste issue :-(&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQPs9p8YXsxrbCvPUnverGAP4zWaIPNaNRcZgGG08t3b3KR09PO7bnD3yTy81ley6oOOmAKamYJMu-_rx_rTpbQcNOgHtOzwFacTaGiLq-YUg8D6CDeLE6xUxgyWIjFwEgjmYdc40KpIA/&quot;&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;275&quot; alt=&quot;16-core&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDfOUyXsdFcQHrlpiW21FyTi2trPzQnydSYTGzCjFhRYgnT4jgtjhFKQfynm5HYg8tkrhaILZC5yCx8Q1swc5sen2DwLke4HfS64XR8XmlBOIKezHhz91JJlgRPT07RbqgkcIX7tJXf7s/&quot; width=&quot;440&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;/p&gt; &lt;h2&gt;Summary&lt;/h2&gt; &lt;p&gt;Some very mixed results and some questionable test results :) I guess some more work is needed.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://lukequinane.blogspot.com/feeds/2288920877222128364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5709001424201684592/2288920877222128364' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2288920877222128364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5709001424201684592/posts/default/2288920877222128364'/><link rel='alternate' type='text/html' href='http://lukequinane.blogspot.com/2008/11/ikvm-benchmarking.html' title='IKVM Benchmarking'/><author><name>Luke Quinane</name><uri>http://www.blogger.com/profile/03951154305011364726</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWogHBilqh6yLCPG1x_weeOLKQ6_yLniIDT0WpQuQUAxNVDGFuD7CwnAB04OgyG_kn5HMeH5IJde3MEbiSVC-DuCcZ7z2wPMyKUgQsmbm6GhsgleDDY7Ma9-AdYSciw/s220/n1178020163_5754.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqU0zEOBsKnYUSxfu2mwGGyMFa0uBL5HFiljxGys3wfGssEiEINDOh21THES9jEF6uRSvLVZTmt4cFGpzpXEb0-Zn9EUNBPE7DZwYdOguORIhPnQ_iOqy7QINtFfZnfHaIOkRRojw7hKw/s72-c" height="72" width="72"/><thr:total>0</thr:total></entry></feed>