<rss version="0.92">
  <channel>
    <title>eyt* Blog</title>
    <link>http://www.eyt.ca/blog/</link>
    <description>eyt*'s Thoughts, Experiences, and Readings</description>
    <language>en</language>
        <item>
      <title>Math.abs has an edge case...</title>
      <description>&lt;p&gt;Consider the following Java code:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt; &amp;nbsp; int ai = Math.abs( i ); &lt;/li&gt;
&lt;li&gt; &amp;nbsp; assert ai &gt;= 0; &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Will the assert ever fire?&lt;/p&gt;
&lt;p&gt;Yes, it turns out that it can fire if &lt;code&gt;i = Integer.MIN_VALUE&lt;/code&gt;, and you have been warned about this in the &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Math.html#abs(int)&quot;&gt;Math.abs javadoc&lt;/a&gt;, which states &amp;ldquo;&lt;i&gt;Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.&lt;/i&gt;&amp;rsquo;&lt;/p&gt;
&lt;p&gt;Keep this in mind when looking at such innocent looking code...&lt;/p&gt;</description>
      <pubDate>Wed, 17 Sep 2008 21:55:58 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/138/</link>
    </item>
        <item>
      <title>Java Mail: Make sure the mail.smtp.auth property's value is a String...</title>
      <description>&lt;p&gt;If you are using the &lt;a href=&quot;http://java.sun.com/products/javamail/&quot;&gt;JavaMail API&lt;/a&gt; to send out e-mail via an e-mail server that requires authentication and are getting an error like &lt;code&gt;com.sun.mail.smtp.SMTPSendFailedException: 550 You must authenticate&lt;/code&gt;, make sure the &lt;a href=&quot;http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html&quot;&gt;mail.smtp.auth&lt;/a&gt; property is assigned as a String, like this:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt; &amp;nbsp; properties.put( &quot;mail.smtp.auth&quot;, &quot;true&quot; );&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Not exactly the most obvious bug to find...&lt;/p&gt;</description>
      <pubDate>Thu, 11 Sep 2008 21:38:54 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/137/</link>
    </item>
        <item>
      <title>Using Ant with Cygwin</title>
      <description>&lt;p&gt;If you have ever tried building something with &lt;kbd&gt;ant&lt;/kbd&gt; under Cygwin, you probably have noticed an error such as the following:&lt;/p&gt;
&lt;p&gt;&lt;tt&gt;build.xml:35: c:\cygdrive\c\Progra~1\java/SunAppServer\jdk\lib\J2EE.jar&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;The current &lt;a href=&quot;http://ant.apache.org/manual/platform.html&quot;&gt;Ant documentation&lt;/a&gt; suggests that you should change your build.xml to wrap all such environment labels and class paths with code that executes &lt;kbd&gt;cygpath&lt;/kbd&gt;, but this turns out to create some ugly code, especially if your build scripts use a lot of environment labels.&lt;/p&gt;
&lt;p&gt;An alternative scheme that I have just come up with is to use a layer of indication.  You can create an ant shell script that translates all of your necessary Cygwin environment labels using cygpath, and then call the ant.bat to do the actual build.  The advantage of this approach is that more build.xml files are cross-platform out of the box and require very few, if any, tweaks.&lt;/p&gt;
&lt;p&gt;The following file is an example of my approach:&lt;/p&gt;
&lt;p class=&quot;code&quot;&gt;
#!/bin/sh&lt;br /&gt;
# OS-Specific Stuff&lt;br /&gt;
export PATH=`/usr/bin/cygpath --path --windows $PATH`&lt;br /&gt;
export TEMP=`/usr/bin/cygpath --path --windows $TEMP`&lt;br /&gt;
export TMP=`/usr/bin/cygpath --path --windows $TMP`&lt;br /&gt;
&lt;br /&gt;
# Java Specific Stuff&lt;br /&gt;
export JAVA_HOME=`/usr/bin/cygpath --windows $JAVA_HOME`&lt;br /&gt;
export J2EE_HOME=`/usr/bin/cygpath --windows $J2EE_HOME`&lt;br /&gt;
export TOMCAT_HOME=`/usr/bin/cygpath --path --windows $TOMCAT_HOME`&lt;br /&gt;
export CLASSPATH=`/usr/bin/cygpath --path --windows $CLASSPATH`&lt;br /&gt;
&lt;br /&gt;
# Ant Specific Stuff&lt;br /&gt;
ORIGINAL_ANT_HOME=$ANT_HOME&lt;br /&gt;
export ANT_HOME=`/usr/bin/cygpath --path --windows $ANT_HOME`&lt;br /&gt;
&lt;br /&gt;
# Project-Specific Stuff&lt;br /&gt;
export WHATEVER_YOU_NEED=`/usr/bin/cygpath --windows $WHATEVER_YOU_NEED`&lt;br /&gt;
&lt;br /&gt;
# Invoke the ANT.BAT via the original ANT_HOME value&lt;br /&gt;
$ORIGINAL_ANT_HOME/bin/ant.bat $1 $2 $3 $4 $5 $6 $7 $8 $9
&lt;/p&gt;
&lt;p&gt;Of course, this technique can be generally applied to other applications that use environment labels.  Hope that helps.&lt;/p&gt;</description>
      <pubDate>Fri, 23 May 2008 21:29:12 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/136/</link>
    </item>
        <item>
      <title>Upgrading your BIOS from 64-bit Windows...</title>
      <description>&lt;p&gt;A while ago, I upgraded my &lt;a href=&quot;http://www.gateway.com/systems/product/529664605.php&quot;&gt;Tablet PC&lt;/a&gt; to Windows Vista Ultimate and decided to take advantage of my Core 2 Duo processors by installing the 64-bit version.  A lot of the pain I had upgrading was actually related to the 64-bit decision, but I will only talk about one of those today.&lt;/p&gt;
&lt;p&gt;A few days after upgrading, Gateway released a new version of the BIOS.  I downloaded the new BIOS version and attempted to install the new version, but unfortunately, I learned that WinPhlash does not work on 64-bit versions of Windows.  There are a wide variety of recipes to get around this, such as &lt;a href=&quot;http://www.windows-now.com/blogs/robert/archive/2007/02/17/solution-for-updating-the-bios-on-windows-vista-x64-machines.aspx&quot;&gt;this one&lt;/a&gt;, but none of them worked for me (I kept getting the 0xC000000F error mentioned in the comments).&lt;/p&gt;
&lt;p&gt;But I finally got the latest BIOS installed.  What I did is I downloaded Windows 98 boot disk ISO from &lt;a href=&quot;http://www.allbootdisks.com/&quot;&gt;All Boot Disks&lt;/a&gt; and downloaded a DOS-version of the Phlash program at &lt;a href=&quot;http://www.biosman.com/bios_flash2.html&quot;&gt;BIOS Man&lt;/a&gt;.  My system has a small FAT32 partition, and so I copied the firmware package and the phlash program there (if you don't have this luxury, you will probably need to edit the ISO to add the files you need to it) and booted from the CD, enabling the feature where it prompts before it loads anything and answering no to all the questions, and then ran the Phlash program from there.  Everything worked like a charm.&lt;/p&gt;</description>
      <pubDate>Sun, 29 Apr 2007 00:42:16 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/135/</link>
    </item>
        <item>
      <title>Firefox 2 and Thunderbird 2 on a Single-Button-Mouse Mac...</title>
      <description>&lt;p&gt;If you use a Mac with a single-button mouse and you have recently upgraded to &lt;a href=&quot;http://www.getfirefox.com&quot;&gt;Firefox 2&lt;/a&gt; or &lt;a href=&quot;http://www.getthunderbird.com&quot;&gt;Thunderbird 2&lt;/a&gt;, you may have noticed that holding the button down no longer brings up the context menu.  While you could use the &lt;a href=&quot;http://ask.metafilter.com/53777/Mac-rightclick-problems-with-firefox-20&quot;&gt;control key when clicking&lt;/a&gt;, that is not a perfect and seamless solution.  Instead, you can get the same behaviour back by enabling the &lt;tt&gt;ui.click_hold_context_menus&lt;/tt&gt; option.&lt;/p&gt;
&lt;p&gt;In Firefox, type &lt;kbd&gt;about:config&lt;/kbd&gt; in the address bar and press enter.  Under the filter, type in &lt;kbd&gt;context&lt;/kbd&gt;, find the &lt;tt&gt;ui.click_hold_context_menus&lt;/tt&gt; item, and double click (the line should be bold and the value should be true).&lt;/p&gt;
&lt;p&gt;In Thunderbird, go to the Thunderbird pulldown menu and select &lt;i&gt;Preferences&lt;/i&gt;.  Under the &lt;i&gt;Advanced&lt;/i&gt; section, choose the &lt;i&gt;General&lt;/i&gt; tab, and click the &lt;i&gt;Config Editor&lt;/i&gt; button.  Under the filter, type in &lt;kbd&gt;context&lt;/kbd&gt;, find the &lt;tt&gt;ui.click_hold_context_menus&lt;/tt&gt; item, and double click (the line should be bold and the value should be true).&lt;/p&gt;
&lt;p&gt;With this simple recipe, you should be back to your old browsing habits.&lt;/p&gt;</description>
      <pubDate>Tue, 24 Apr 2007 22:53:38 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/134/</link>
    </item>
        <item>
      <title>C++ Strongly-Typed Enumerations...</title>
      <description>&lt;p&gt;With the release on Java 5, we finally have enumerations in Java, but they really outdone themselves, in that an enumerated type is actually a class, where you can add your own methods.  Take, for example, this code:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;public enum Color {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Red,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Yellow,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Orange,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Green,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Blue,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Brown,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Black,&lt;/li&gt;
&lt;li&gt; &amp;nbsp; Purple;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &lt;/li&gt;
&lt;li&gt; &amp;nbsp; public boolean isPrimaryColor() {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; switch ( this ) {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; case Red:&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; case Blue:&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; case Yellow:&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; return true;&lt;/li&gt;
&lt;li&gt; &amp;nbsp;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; default:&lt;li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; return false;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead of having a utility class off to the side that takes an enumeration as a parameter, you can now add that method directly to the enumeration, and I do not think that there would be much controversy that &lt;code&gt;color.isPrimaryColor();&lt;/code&gt; reads better than &lt;code&gt;ColorUtils.isPrimaryColor( color );&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Putting this aside for a moment, C++09 is cleaning up their enumerations by &lt;a href=&quot;http://www.informit.com/guides/content.asp?g=cplusplus&amp;seqNum=316&amp;rl=1&quot;&gt;adding support for strongly type &lt;code&gt;enum&lt;/code&gt;s&lt;/a&gt; (&lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1719.pdf&quot;&gt;PDF Proposal&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;In the current version of C++, we have problems with code like this:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;enum Color { RED, YELLOW, ORANGE, GREEN, BLUE, BROWN, BLACK, PURPLE };&lt;/li&gt;
&lt;li&gt;enum TerrorAlertLevel { RED, ORANGE, YELLOW, BLUE, GREEN };&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This does not compile, because by the time it gets to TerrorAlertLevel, RED, ORANGE, YELLOW, BLUE, and GREEN are already defined, thanks to the Color enumeration.  And worst off, if you have a coding standard that does not require you to have your enumerations all in caps (which makes sense, since part of the reason that Macros are usually done in caps is to discourage their use), then you could have an issue with any variables, such as &lt;code&gt;int red = 0xFF0000;&lt;/code&gt; would not compile if the enumeration was all in lower-case.&lt;/p&gt;
&lt;p&gt;As such, developers in C++ tend to add a prefix to the definition, such as:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;enum Color { COLOR_RED, COLOR_YELLOW, COLOR_ORANGE, COLOR_GREEN, COLOR_BLUE, COLOR_BROWN, COLOR_BLACK, COLOR_PURPLE };&lt;/li&gt;
&lt;li&gt;enum TerrorAlertLevel { TAL_RED, TAL_ORANGE, TAL_YELLOW, TAL_BLUE, TAL_GREEN };&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Oh, that looks friendly.&lt;/p&gt;
&lt;p&gt;Well, to help in that friendliness, C++09 is adding strongly typed &lt;code&gt;enum&lt;/code&gt;s.  This is done by adding the &lt;code&gt;class&lt;/code&gt; keyword to the &lt;code&gt;enum&lt;/code&gt; definition.  For example, the first C++ example above could compile under C++09 as this:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;enum &lt;b&gt;class&lt;/b&gt; Color { RED, YELLOW, ORANGE, GREEN, BLUE, BROWN, BLACK, PURPLE };&lt;/li&gt;
&lt;li&gt;enum &lt;b&gt;class&lt;/b&gt; TerrorAlertLevel { RED, ORANGE, YELLOW, BLUE, GREEN };&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The bold emphasizes the difference.&lt;/p&gt;
&lt;p&gt;Conceptually, I think this is a great addition to C++, making it easier to reuse enumerations and avoiding the crazy compilation errors that you can get if you accidentally name your variable a name that has already been defined in an &lt;code&gt;enum&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The part that I do not like about this proposal, however, is the fact that it uses the keyword &lt;code&gt;class&lt;/code&gt; but it is not a class.  You cannot add member functions to it, which because of the power of the Java enumerations, I think this is confusing for developers which experience with Java enumerations.&lt;/p&gt;
&lt;p&gt;C# enumerations are strongly typed but you cannot add any methods to them.  But at least, they do not use the word class in their definition.&lt;/p&gt;
&lt;p&gt;While I more than welcome the strongly-typed nature of enumerations in C++, I think that the implementation could have overloaded a better keyword than &lt;code&gt;class&lt;/code&gt;.  Since it does seem like this has been accepted already, hopefully a future version of the standard will add the ability to add member functions to the enumeration, minimizing some of this confusion.&lt;/p&gt;</description>
      <pubDate>Sun, 11 Feb 2007 18:15:37 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/133/</link>
    </item>
        <item>
      <title>A feed for mFiles.co.uk...</title>
      <description>&lt;p&gt;One of the music sites that I've enjoyed over the years has been &lt;a href=&quot;http://mfiles.co.uk/&quot;&gt;mFiles&lt;/a&gt;.  Not only does it provide you with great commentary ranging from classical composers to modern pieces, but it also provides you with pieces of music in MIDI, MP3, and, my personal favorite, free sheet music.  I have found it to be a great place to get introduced to various musical styles and composers.&lt;/p&gt;
&lt;p&gt;One thing that I noticed a while ago was that this site did not have a feed, so to keep up with the site's regular updates, one had to visit the site regularly.&lt;/p&gt;
&lt;p&gt;After approaching Jim Paterson (the site's webmaster) about an RSS feed, I decided to write a little program that will generate an RSS feed from mFiles.  The feed is now available at &lt;a href=&quot;http://www.eyt.ca/mfiles.co.uk.rss&quot;&gt;http://www.eyt.ca/mfiles.co.uk.rss&lt;/a&gt; (which is linked to directly from mFiles.co.uk's homepage).&lt;/p&gt;
&lt;p&gt;My program is very simple, and usually visits mFiles once a day, parses through the articles, and generates an RSS 2.0 feed.  The feed currently only contains the titles of the articles and a link to mFiles.co.uk.  A few notes about the feed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; If you click on a link and the title does not match, use the Find feature of your browser to find the article that you clicked on.  This is something that will eventually be improved. &lt;/li&gt;
&lt;li&gt; The feed only contains the titles of the articles; it does not contain any of the article's content.  I have done this for many reasons, but primarily since I did not want any plagiarism to occur. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have any suggestions, problems, or questions about the feed, please feel free to &lt;a href=&quot;mailto:eric@eyt.ca&quot;&gt;contact me&lt;/a&gt;, or if you have questions about mFiles, please contact &lt;a href=&quot;mailto:jim@mfiles.co.uk?subject=mfiles%20contact&quot;&gt;mFiles directly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope that you will find this useful!&lt;/p&gt;</description>
      <pubDate>Fri, 24 Nov 2006 00:25:40 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/132/</link>
    </item>
        <item>
      <title>Error Changing Samba Password...</title>
      <description>&lt;p&gt;When I went to change my Samba password earlier today, I got this error message:&lt;/p&gt;
&lt;p class=&quot;code&quot;&gt;eyt@zaterdag 19% smbpasswd&lt;br /&gt;
Old SMB password: &lt;br /&gt;
New SMB password: &lt;br /&gt;
Retype new SMB password: &lt;br /&gt;
Error connecting to 127.0.0.1 (Connection refused) &lt;br /&gt;
unable to connect to SMB server on machine 127.0.0.1. Error was : SUCCESS - 0. &lt;br /&gt;
Failed to change password for eyt&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;Googling&lt;/a&gt; did not say it directly, but it appears that the problem above was that my smb.conf did not mention 127.0.0.1 (localhost) for the listening interfaces; adding 127.0.0.1 to the &lt;tt&gt;interfaces&lt;/tt&gt; setting in the &lt;tt&gt;global&lt;/tt&gt; section resolved my problem, as demonstrated here:&lt;/p&gt;
&lt;p class=&quot;code&quot;&gt;[global]&lt;br /&gt;
&lt;span class=&quot;comment&quot;&gt;...&lt;/span&gt;&lt;br /&gt;
interfaces = &lt;b&gt;127.0.0.1&lt;/b&gt; 192.168.1.1/255.255.255.0&lt;br /&gt;
&lt;span class=&quot;comment&quot;&gt;...&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After this quick change and restarting Samba, I was able to change my password and all was happy again.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Nov 2006 22:50:20 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/131/</link>
    </item>
        <item>
      <title>Corrupted Comments Table...</title>
      <description>&lt;p&gt;I was recently cleaning up the endless comment spam this blog gets, and at some point while doing this, I noticed that one comment ended up not being deletable.  From the &lt;a href=&quot;http://www.bblog.com/&quot;&gt;bBlog&lt;/a&gt; admin interface, it was not evident that there was a problem, and I decided to look at it when I got home.  When I got home, I had received a couple more comment spams, but I could not delete these or the previous one from the admin interface, and so I decided to drop to the &lt;kbd&gt;mysql&lt;/kbd&gt; interface.&lt;/p&gt;
&lt;p&gt;The &lt;kbd&gt;mysql&lt;/kbd&gt; interface seemed fine at first, as it allowed me to &lt;kbd&gt;select * from bB_comments&lt;/kbd&gt;, however, when I attempted to delete all the items on hold, I noticed something different:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;mysql&amp;gt; &lt;kbd&gt;delete from bB_comments where onhold = 1;&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;ERROR 126 (HY000): Incorrect key file for table './bBlog_table/bB_comments.MYI'; try to repair it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some of my initial search results were non-conclusive as to what the deal was, and so I hoped that by restarting MySQL, that the error would be more evident.  MySQL started up fine, but my query results now were different:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;mysql&amp;gt; &lt;kbd&gt;delete from bB_comments where onhold = 1;&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;ERROR 145 (HY000): Table './Blog/bB_comments' is marked as crashed and should be repaired&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From that error message, I landed on &lt;a href=&quot;http://drupal.org/node/73297&quot;&gt;this&lt;/a&gt; message that indicated that the repair was as simple as running the &lt;kbd&gt;REPAIR&lt;/kbd&gt; query, as described &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/repair.html&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;mysql&amp;gt; &lt;kbd&gt;REPAIR Table bB_comments;&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;+-------------------------+--------+----------+----------+&lt;/li&gt;
&lt;li&gt;| Table                   | Op     | Msg_type | Msg_text |&lt;/li&gt;
&lt;li&gt;+-------------------------+--------+----------+----------+&lt;/li&gt;
&lt;li&gt;| bBlog_table.bB_comments | repair | status   | OK       |&lt;/li&gt;
&lt;li&gt;+-------------------------+--------+----------+----------+&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And now I am back in business and able to delete my comment spam.  It is unclear what corrupted the table to begin with; I was impatient in deleting the comment spam, but I doubt that is the root cause.  If it happens again, I will take a look.&lt;/p&gt;</description>
      <pubDate>Thu, 03 Aug 2006 07:20:28 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/130/</link>
    </item>
        <item>
      <title>Searching for nil in all the wrong places...</title>
      <description>&lt;p&gt;A few days ago, I was adding some migrations to a Ruby on Rails project, but when I went to initialize a newly created database, I saw this error:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;rake aborted!&lt;/li&gt;
&lt;li&gt;You have a nil object when you didn't expect it!&lt;/li&gt;
&lt;li&gt;You might have expected an instance of Array.&lt;/li&gt;
&lt;li&gt;The error occured while evaluating nil.first&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This being the third or so time working in Ruby, I immediately thought that it was something I did, so I started up the automatically generated &lt;code&gt;scripts/application&lt;/code&gt;, pasted my new code into there, and proceeded to use it.  The code had a couple issues that I fixed and I was confident enough to try again.&lt;/p&gt;
&lt;p&gt;But again, I got the same error message.  I then decided to add a couple prints around the new code, and re-run it, but the error above occurred without my print outs.  Not sure how to proceed, I asked for some assistance from some co-workers.  The advice was great, and I learned a lot about Ruby and Rails, but it still did not resolve my problem.&lt;/p&gt;
&lt;p&gt;Finally someone recommended adding &lt;code&gt;--trace&lt;/code&gt; to the my command:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;eyt@zaterdag 5031% rake --trace migrate&lt;/li&gt;
&lt;li&gt;** Invoke migrate (first_time)&lt;/li&gt;
&lt;li&gt;** Invoke environment (first_time)&lt;/li&gt;
&lt;li&gt;** Execute environment&lt;/li&gt;
&lt;li&gt;** Execute migrate&lt;/li&gt;
&lt;li&gt;rake aborted!&lt;/li&gt;
&lt;li&gt;You have a nil object when you didn't expect it!&lt;/li&gt;
&lt;li&gt;You might have expected an instance of Array.&lt;/li&gt;
&lt;li&gt;The error occured while evaluating nil.first&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:253:in `migration_files'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:252:in `sort_by'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:252:in `each'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:252:in `sort_by'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:252:in `migration_files'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:235:in `migration_classes'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:223:in `migrate'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:190:in `up'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/active_record/migration.rb:181:in `migrate'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rails-1.0.0/lib/tasks/databases.rake:3&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rails-1.0.0/lib/tasks/databases.rake:2:in `call'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:202:in `execute'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:202:in `each'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:202:in `execute'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:180:in `invoke'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:1454:in `run'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:1454:in `each'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/lib/rake.rb:1454:in `run'&lt;/li&gt;
&lt;li&gt;.../lib/ruby/gems/1.8/gems/rake-0.6.2/bin/rake:7&lt;/li&gt;
&lt;li&gt;.../bin/rake:18:in `load'&lt;/li&gt;
&lt;li&gt;.../bin/rake:18 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So that is very interesting.  Note how there is nothing in the above points to anything of mine.  In pondering this with one of my coworkers, I explained how one of the things that I tried during debugging it was renaming the name of the class and filename, and that struck a cord.&lt;/p&gt;
&lt;p&gt;It turns out that the mess above was all caused by my filename.  I had named my file &lt;code&gt;&lt;i&gt;revision&lt;/i&gt;_add_blah_to_myApp&lt;/code&gt; and named my class &lt;code&gt;AddBlahToMyApp&lt;/code&gt;.  The problem with this is that the Rails convention for class names requires me to either name my file &lt;code&gt;&lt;i&gt;revision&lt;/i&gt;_add_blah_to_my_app&lt;/code&gt; or name my class &lt;code&gt;AddBlahToMyapp&lt;/code&gt;.  This very subtle issue caused this most unusable error message to cause a few completely wasted hours.&lt;/p&gt;
&lt;p&gt;I have &lt;a href=&quot;http://www.eyt.ca/blog/item/68/&quot;&gt;blogged before&lt;/a&gt; about great and &lt;a href=&quot;http://www.eyt.ca/blog/item/49/&quot;&gt;not so great&lt;/a&gt; exceptions and their handling.  I think this also falls in that category of not-so-great.  It would have been nice to know that this problem originated with an attempt to load a class that did not exist, for example.  In that case, I would have looked at that issue more closer than looking for references to &lt;code&gt;first&lt;/code&gt; (and indirect references thereof) where the object invoking that method could have been nil.&lt;/p&gt;</description>
      <pubDate>Wed, 02 Aug 2006 21:19:04 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/129/</link>
    </item>
        <item>
      <title>Clearing an empty java.util.HashMap...</title>
      <description>&lt;p&gt;Here is an interesting question; which of the following programs executes faster:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
  &lt;li&gt;public class &lt;b&gt;ProgramA&lt;/b&gt; {&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; public static void main( String [] args ) {&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; java.util.Map&amp;lt;String, String&amp;gt; map = new java.util.HashMap&amp;lt;String, String&amp;gt;( 100000000 );&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; long start = System.currentTimeMillis();&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; for ( int i = 0; i &amp;lt; 100; ++ i ) { &lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; map.clear();&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; }&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; System.err.println( ( System.currentTimeMillis() - start ) + &quot;ms&quot; );&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; }&lt;/li&gt;
  &lt;li&gt;}&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class=&quot;code&quot;&gt;
  &lt;li&gt;public class &lt;b&gt;ProgramB&lt;/b&gt; {&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; public static void main( String [] args ) {&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; java.util.Map&amp;lt;String, String=&amp;gt; map = new java.util.HashMap&amp;lt;String, String=&amp;gt;( 100000000 );&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; long start = System.currentTimeMillis();&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; for ( int i = 0; i &amp;lt; 100; ++ i ) { &lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; if ( ! map.isEmpty() ) { &lt;div class=&quot;comment&quot;&gt;// this line is not in the above.&lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; map.clear();&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; }&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; &amp;nbsp; System.err.println( ( System.currentTimeMillis() - start ) + &quot;ms&quot; );&lt;/li&gt;
  &lt;li&gt; &amp;nbsp; }&lt;/li&gt;
  &lt;li&gt;}&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By simply looking at the code or reading through the &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html&quot;&gt;documentation&lt;/a&gt;, you may think that they are similar since the map is empty, since presumably the &lt;tt&gt;&lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashMap.html#clear%28%29&quot;&gt;clear()&lt;/a&gt;&lt;/tt&gt; method would take this into consideration. But of course, if that were the answer, this would not be much of a blog post.&lt;/p&gt;
&lt;p&gt;On my machine, Program_A runs in about 37625 milliseconds with one of my processors pegged whereas the Program_B runs in about 1 millisecond. Why? It would appear that the clear() method recreates its internal representation each time that you call it instead of looking at the current state of the object and realizing that it is indeed empty. Naturally if the initialCapacity is smaller, the program is less affected by this.&lt;/p&gt;
&lt;p&gt;Obviously no one writes code exactly like the above snippet, but if you are calling clear() from within a loop, you may want to be aware of this.&lt;/p&gt;</description>
      <pubDate>Sun, 25 Jun 2006 10:24:07 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/128/</link>
    </item>
        <item>
      <title>Installing SuSE Linux 10.1...</title>
      <description>&lt;p&gt;&lt;a href=&quot;http://www.amazon.com/gp/redirect.html?link_code=ur2&amp;amp;tag=eyt00-20&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fproduct%2F158298302X%2Fqid%3D1151182935%2Fsr%3D8-1%2Fref%3Dpd_bbs_1%3F%255Fencoding%3DUTF8%26v%3Dglance%26n%3D229534&quot;&gt;SuSE
Linux 10.1&lt;/a&gt; has been recently released and it is freely
available via &lt;a href=&quot;http://en.opensuse.org/Welcome_to_openSUSE.org&quot;&gt;OpenSuSE&lt;/a&gt;. I opted for purchasing the DVD's, though, and I just received them earlier this week.&lt;/p&gt;
&lt;p&gt;The only part that I really dislike about Fedora and SuSE's installation procedure is that you have to shutdown the machine for anywhere between 30 minutes and 2 hours depending on how much you are paying attention to the installation process; because of this, you'll probably see this site down an hour sometime in the upcoming couple of weeks.&lt;/p&gt;
&lt;p&gt;Last night, I decided to upgrade one of my workstations from 10.0 to 10.1, and the process went very smoothly... until the end. At the end, it wanted to configure the on-line update and to do this, it opened up Mozilla so I could go through the registration form. After filling out the form, it said that it was successful and that was it; it did not feel very well integrated, since it did not tell me what the next step was. I assumed that it was to close the window, however, the setup program just kept on insisting to open up Mozilla and have me repeat the process, until I eventually just gave up configuring the on-line updater and clicked Cancel. This ended up being the final step, and then I logged into my machine.&lt;/p&gt;
&lt;p&gt;I then proceeded to attempt to update my machine, however, the YaST Online Update (YOU) was quite insistent that there were no updates, to which I was a little surprised since in each SuSE release that I have installed thus far, there have always been some updates afterwards. So I decided to start playing with my machine and to figure that out later, and this is when I started noticing my problem: when I started up Thunderbird and Firefox, I got a segmentation fault, but I tend not to use the SuSE default &lt;a href=&quot;http://www.getfirefox.com&quot;&gt;Firefox&lt;/a&gt; and &lt;a href=&quot;http://www.getthunderbird.com&quot;&gt;Thunderbird&lt;/a&gt;, so I initially thought it was a problem with those, so then I tried the SuSE default Firefox, only to get the same results:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;eyt@zaterdag 1$ firefox&lt;/li&gt;
&lt;li&gt;/usr/bin/firefox: line 159: 11151 Segmentation fault $AOSS $MOZ_PROGRAM $@&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After &lt;a href=&quot;http://www.google.com&quot;&gt;searching&lt;/a&gt;, I found that there were &lt;a href=&quot;http://www.novell.com/linux/download/updates/101_i386.html&quot;&gt;updates&lt;/a&gt;, and that this was probably one of them. Installing the BASH one really did not help any, so I then shifted my efforts to getting the Online Update to work properly.&lt;/p&gt;
&lt;p&gt;After many failed attempts, I fell onto &lt;a href=&quot;http://www.justlinux.com/forum/printthread.php?t=146031&quot;&gt;this&lt;/a&gt; which led me to resolving my problem. The deal is that with previous versions of &lt;acronym title=&quot;YaST2 Online Update&quot;&gt;YOU&lt;/acronym&gt;, you used to only use one source for updates, but with the new version, it works closer to how &lt;a href=&quot;http://www.cygwin.com/&quot;&gt;Cygwin&lt;/a&gt;'s installer works, in that you can get put in multiple update sites for different applications. This is pretty cool, however, it is unfortunate that it does not make adding the default SuSE sites easier to set up. As such, here is what you have to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Start &lt;kbd&gt;yast2&lt;/kbd&gt;, under &lt;i&gt;Software&lt;/i&gt;, select &lt;i&gt;Installation Source&lt;/i&gt;. &lt;/li&gt;
&lt;li&gt; Once initialized, select &lt;i&gt;Add&lt;/i&gt;, &lt;i&gt;HTTP&lt;/i&gt; and enter these sites:
&lt;table border=&quot;0&quot; class=&quot;table&quot;&gt;
&lt;tr&gt;&lt;th&gt;Server Name&lt;/th&gt;&lt;th&gt;Directory on Server&lt;/th&gt;&lt;th&gt;Notes&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;download.opensuse.org&lt;/td&gt;&lt;td&gt;distribution/SL-10.1/non-oss-inst-source/&lt;/td&gt;&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;suse.cs.utah.edu&lt;/td&gt;&lt;td&gt;suse/update/10.1/&lt;/td&gt;&lt;td&gt;Or another &lt;a href=&quot;http://www.novell.com/products/suselinux/downloads/ftp/int_mirrors.html&quot;&gt;mirror&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;&lt;/li&gt;
&lt;li&gt;Once those are added, make sure that &lt;i&gt;Status&lt;/i&gt; and &lt;i&gt;Refresh&lt;/i&gt; are on for these sites. If they are not, select them, and then click the appropriate button in the lower right-hand corner.&lt;/li&gt;
&lt;li&gt;Next click &lt;i&gt;Finish&lt;/i&gt;. This will take several minutes to complete, or at least it does the first time&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once that was done, the Software Updater icon turned into an orange exclamation mark, so I proceeded to tell it to update everything. After a few moments, it errored out with:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;Establishing script:libzypp-patch-zmdrestart.sh-2-1533-1.noarch[20060624-115231]&lt;/li&gt;
&lt;li&gt;This would invalidate script:libzypp-patch-zmdrestart.sh-2-1533-1.noarch[20060624-115231].&lt;/li&gt;
&lt;li&gt;Marking this resolution attempt as invalid.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because I had manually installed a few packages in prior to this, I thought that I would try selecting packages around this problem, but to no avail. As a final attempt, I went into YaST2, and selected &lt;i&gt;Online Update&lt;/i&gt; from &lt;i&gt;Software&lt;/i&gt;, and after it initialized, it downloaded a bunch of patches, one of which included some updated &lt;acronym title=&quot;YaST2 Online Update&quot;&gt;YOU&lt;/acronym&gt;.  This required &lt;acronym title=&quot;YaST2 Online Update&quot;&gt;YOU&lt;/acronym&gt; to be restarted, and then it continued to download a bunch of packages.&lt;/p&gt;
&lt;p&gt;And after all that, I am now able to start Mozilla Thunderbird and Mozilla Firefox without any segmentation faults. And besides that experience, I am so far very pleased with the changes in SuSE Linux 10.1, particularly with the look and feel, but I've only been using it for a couple hours now.&lt;/p&gt;</description>
      <pubDate>Sat, 24 Jun 2006 15:15:49 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/127/</link>
    </item>
        <item>
      <title>.NET and loading assemblies for other platforms...</title>
      <description>&lt;p&gt;If you are working with .NET, and you see the following exception:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;TypeLoadException: Method 'Dispose' in type 'eSQL.SqlConnection' from assembly 'eSQLNet, Version=2.9.2056.14469, Culture=neutral, PublicKeyToken=null' does not have an implementation&lt;/p&gt;
&lt;p&gt;Make sure that the .NET assembly you are referencing (&lt;a href=&quot;http://www.vieka.com/esql.htm&quot;&gt;eSQL&lt;/a&gt; in this case) is for your current platform.&lt;/p&gt;
&lt;p&gt;In the case depicted above, I had accidentally selected the ARM version of the eSQL DLL instead of the x86 version.  Unfortunately, however, the exception message above does not exactly say that.  It would have been nicer to have gotten a message that would have said something about the assembly not being compiled for the current platform...&lt;/p&gt;</description>
      <pubDate>Sat, 10 Jun 2006 23:19:26 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/126/</link>
    </item>
        <item>
      <title>Adding the comment URL to bBlog's RSS 2.0 Feeds...</title>
      <description>&lt;p&gt;The default bBlog RSS 2.0 feed template does not present the user with a link to the comments page.  Although this is easily derived, some RSS readers can do some funky stuff with this information.  It turns out that adding this is extremely easy.  Simply do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Change the current directory to your bBlog directory &lt;/li&gt;
&lt;li&gt; Edit &lt;tt&gt;bblog/inc/admin_templates/rss20.html&lt;/tt&gt;. &lt;/li&gt;
&lt;li&gt; Search for the &lt;tt&gt;guid&lt;/tt&gt; tag, and you should see something like: &lt;ul class=&quot;code&quot;&gt;
&lt;li&gt; ... &lt;/li&gt;
&lt;li&gt; &amp;lt;guid isPermaLink=&quot;true&quot;&amp;gt;{$post.permalink}&amp;lt;/guid&amp;gt; &lt;/li&gt;
&lt;li&gt; &amp;lt;title&amp;gt;{$post.title|htmlspecialchars}&amp;lt;/title&amp;gt; &lt;/li&gt;
&lt;li&gt; &amp;lt;link&amp;gt;{$post.permalink}&amp;lt;/link&amp;gt; &lt;/li&gt;
&lt;li&gt; &lt;b&gt;&amp;lt;comments&amp;gt;{$post.permalink}#comments&amp;lt;/comments&amp;gt;&lt;/b&gt; &lt;/li&gt;
&lt;li&gt; &amp;nbsp; &lt;/li&gt;
&lt;li&gt; {if strlen($post.author.email) &gt; 0}&lt;/li&gt;
&lt;li&gt; ... &lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt; The line in bold above is the one you should add in. &lt;/li&gt;
&lt;li&gt; Save, and enjoy! &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Or just take a short cut to all this and snag &lt;a href=&quot;http://www.eyt.ca/Software/bblog_rss20.html&quot;&gt;mine&lt;/a&gt;.  Let me know if there&amp;apos;s anything.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Jun 2006 00:08:06 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/125/</link>
    </item>
        <item>
      <title>Introducing ReallySimpleSnagger Version 0.1beta...</title>
      <description>&lt;p&gt;After a few months of development and testing, I am pleased to introduce ReallySimpleSnagger version 0.1beta.&lt;/p&gt;
&lt;p&gt;ReallySimpleSnagger is an off-line Atom, OPML, and RSS reader.  What most feed readers do is only read the information in the feed itself, and unfortunately, most feeds only contain a small snippet of the actual article, and they only gather images if you are actually on-line.&lt;/p&gt;
&lt;p&gt;ReallySimpleSnagger, on the other hand, downloads the the feed and all the referenced content in the feed, including the articles, images, and everything required to make your off-line experience almost indistinguishable from your on-line experience.&lt;/p&gt;
&lt;p&gt;Once that ReallySimpleSnagger has downloaded this content, you can simply either use the content directly or copy the content onto a device, such as a Palm or Pocket PC/Windows Mobile device and use a standard web browsers to view the content.&lt;/p&gt;
&lt;p&gt;If you are using a Pocket PC/Windows Mobile device, ReallySimpleSnagger comes with a service that uses ActiveSync to synchronize the content between your desktop and mobile device. But even if you do not have a Pocket PC or Windows Mobile device, our documentation will walk you through how to manage your content effectively.&lt;/p&gt;
&lt;p&gt;This version is a stable beta version that is provided free of charge (this may change in the future).  I am particularly interested in hearing about any bugs that you may find and what you think would make it a better product.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.eyt.ca/Software/ReallySimpleSnagger/RSSInstaller-0.1.zip&quot;&gt;Download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.eyt.ca/Software/ReallySimpleSnagger/RSS.html&quot;&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.eyt.ca/Boards/viewforum.php?f=1&quot;&gt;Forums&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Sun, 04 Jun 2006 22:13:28 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/124/</link>
    </item>
        <item>
      <title>C++ and finally</title>
      <description>&lt;p&gt;Almost two months ago, &lt;a href=&quot;http://www.informit.com/guides/guide.asp?g=cplusplus&amp;rl=1&quot;&gt;Danny Kalev&lt;/a&gt; wrote a piece regarding &lt;a href=&quot;http://www.informit.com/guides/content.asp?g=cplusplus&amp;seqNum=189&quot;&gt;adding &lt;code&gt;finally&lt;/code&gt; to C++&lt;/a&gt;.  Unlike Danny, however, I think this is a great addition to C++.&lt;/p&gt;
&lt;p&gt;Danny has a good point that part of the reason that &lt;code&gt;finally&lt;/code&gt; exists in garbage collected languages is that they lack a destruction mechanism that allows for cleaning up.  For example, a common use of &lt;code&gt;finally&lt;/code&gt; in Java is with files, sockets, and other such resources to ensure that the resource is guaranteed to be released (since the finalizer is not guaranteed to be ran).  In C#, this could be done via the &lt;code&gt;using&lt;/code&gt; keyword and hopefully in a future release on Java, a similar mechanism will exist that would allow the same behaviour.&lt;/p&gt;
&lt;p&gt;But I think that there is a certain amount of value to adding such a feature to the language.  For example, if you wanted to have a code segment display a log message at the end of a method, you would need to do something like:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;class Trace {&lt;/li&gt;
&lt;li&gt;public:&lt;/li&gt;
&lt;li&gt; &amp;nbsp;Trace() { &lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;comment&quot;&gt;// ... maybe display something or grab a statistics&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;li&gt; &amp;nbsp;~Trace() { &lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;comment&quot;&gt;// ... log something or accumulate&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &lt;/li&gt;
&lt;li&gt;void myFunc() {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; try {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; Trace t; &lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;comment&quot;&gt;// ... do something&lt;/span&gt;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; } catch ( ... ) {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;span class=&quot;comment&quot;&gt;// ... handle it&lt;/span&gt;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a general purpose tracing class, this would be, by far, the best approach.  But for a specific operation that is done for one specific method, I think that the code above is not as readable as the same code written using a &lt;code&gt;finally&lt;/code&gt;, even in the case where the statements in the &lt;code&gt;finally&lt;/code&gt; explicitly call a function.&lt;/p&gt;
&lt;p&gt;Said another way, the &lt;code&gt;for&lt;/code&gt; keyword is equally redundant, since the 1998 C++ ISO Standard states in section 6.5.3 that the statement &lt;code&gt;for ( &lt;i&gt;for-init-statement&lt;/i&gt; ; &lt;i&gt;condition&lt;/i&gt; ; &lt;i&gt;expression&lt;/i&gt; ) &lt;i&gt;statement&lt;/i&gt;&lt;/code&gt; is equivalent to:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;{&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &lt;i&gt;for-init-statement&lt;/i&gt;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; while ( &lt;i&gt;condition&lt;/i&gt; ) {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;i&gt;statement&lt;/i&gt;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &lt;i&gt;expression&lt;/i&gt; ;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But while the latter is equivalent to the former, there is a certain readability value that comes with the &lt;code&gt;for&lt;/code&gt; statement that it is a welcomed keyword.&lt;/p&gt;
&lt;p&gt;I feel that the addition of the &lt;code&gt;finally&lt;/code&gt; keyword would have the same benefits.  It is easily implemented in terms of existing infrastructure quite similar to the &lt;code&gt;for&lt;/code&gt; example above is.  It has adds increased readability, particularly for cases where the creation of a class would consume many more lines than a line or two in a finally block.  Lastly, I think that there is a huge benefit to people using C++ that are accustomed to using other languages; the familiarity with this feature would permit such developers to concentrate on other, more important C++ features instead of trying to figure out how to get around the perceived lack of this feature.  I think these benefits outweigh the cons of adding a new keyword, and I welcome the change.&lt;/p&gt;</description>
      <pubDate>Thu, 01 Jun 2006 00:43:20 PDT</pubDate>
      <link>http://www.eyt.ca/blog/item/123/</link>
    </item>
        <item>
      <title>Adapting for Concurrency...</title>
      <description>&lt;p&gt;&lt;a href=&quot;http://www.gotw.ca/&quot;&gt;Herb Sutter&lt;/a&gt; gave a &lt;a href=&quot;http://pluralsight.com/blogs/hsutter/archive/2006/03/16/20167.aspx&quot;&gt;talk on concurrency at PARC&lt;/a&gt; earlier this week, and the &lt;a href=&quot;http://www.parc.com/cms/get_article.php?id=533&quot;&gt;Audio, Video,&lt;/a&gt; and &lt;a href=&quot;http://pluralsight.com/blogs/hsutter/archive/2006/03/19/20259.aspx&quot;&gt;Slides&lt;/a&gt; are available.&lt;/p&gt;
&lt;p&gt;Where as even up to a few years ago, multiple processor (and multiple core) machines were only available for niche markets, the talk highlights the fact that very soon multiple core machines will be everywhere.  This is very exciting, however, we must change how we develop our applications to take advantage of this.  From this perspective, it is not just simply using the existing tools that we have such as locks and threads, but also expanding our tools in order to take advantage of these language features.&lt;/p&gt;
&lt;p&gt;Herb gives the analogy that this is similar to the early 1990&amp;rsquo;s when Object Orientation was new.  While you could write an object-oriented application in C (for example, consider the &lt;code&gt;FILE&lt;/code&gt; structure and methods), it is far easier to write such applications in languages that have native support for objects.  Herb states that while we currently can write multithreaded software in our existing tools, writing correct multithreaded software is hard, pointing out that some of the class libraries and even some of his own examples have been incorrect.&lt;/p&gt;
&lt;p&gt;During the discussion, Herb mentioned something that I was unaware of.  A while ago, I discussed &lt;a href=&quot;http://www.eyt.ca/blog/?postid=9&quot;&gt;Double Check Locking&lt;/a&gt; and how it was broken and later about &lt;a href=&quot;http://www.aristeia.com/&quot;&gt;Scott Meyers&lt;/a&gt; and &lt;a href=&quot;http://www.moderncppdesign.com/&quot;&gt;Andre Alexandrescu&lt;/a&gt;&amp;rsquo;s &lt;a href=&quot;http://www.eyt.ca/blog/item/28/&quot;&gt;C++ and the Perils of Double-Check Locking&lt;/a&gt;.  One part that I had not noticed in Scott and Andre&amp;rsquo;s paper is that, thanks to reworking the memory model, the Double Check Locking Pattern once again works in Java 1.5/5.0 (&lt;a href=&quot;http://www.jcp.org/aboutJava/communityprocess/review/jsr133/index.html&quot;&gt;JSR 133&lt;/a&gt;) and .NET 2.0 (&lt;a href=&quot;http://msdn.microsoft.com/netframework/ecma/&quot;&gt;CLI 2.0&lt;/a&gt; Section 12.6).  The solution is to use the keyword &lt;code&gt;volatile&lt;/code&gt; as follows:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;private static volatile Singleton instance= null;&lt;/li&gt;
&lt;li&gt;public static Singleton get() {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; if ( instance == null ) {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; synchronized ( Singleton.class ) {&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;instance = new Singleton();&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt; &amp;nbsp; return instance;&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Again, this only works in Java 1.5 and .NET 2.0 because of the changes in the memory model.  There are some &lt;a href=&quot;http://www.theserverside.com/news/thread.tss?thread_id=24199&quot;&gt;discussions&lt;/a&gt; that the restrictions on &lt;code&gt;volatile&lt;/code&gt; may not make it faster than volatile, but then &lt;a href=&quot;http://discuss.develop.com/archives/wa.exe?A2=ind0203B&amp;L=DOTNET&amp;P=R375&quot;&gt;there&amp;rsquo;s a solution&lt;/a&gt; that uses the Memory Barriers instead of &lt;code&gt;volatile&lt;/code&gt; that could get around this in .NET.  Of course, some of this feels like premature optimization, as synchronization and volatile improvements are things that compiler vendors are likely to working on.  I guess its like the free lunch.&lt;/p&gt;
&lt;p&gt;And speaking of which, if you haven't really thought about having your desktop application take advantage of a 32 core machine, this is good discussion to get you thinking about that and why.&lt;/p&gt;</description>
      <pubDate>Wed, 22 Mar 2006 22:21:04 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/122/</link>
    </item>
        <item>
      <title>Long-Lived IIOP.NET Objects...</title>
      <description>&lt;p&gt;I have been working with &lt;a href=&quot;http://iiop-net.sourceforge.net/&quot;&gt;IIOP.NET&lt;/a&gt;, a CORBA toolkit for .NET, a bit more than with &lt;a href=&quot;http://www.eyt.ca/CORBA/nameservice.html&quot;&gt;Using Multiple Vendor's ORBs with Name Services&lt;/a&gt;.  While my test application was working great, my actual application was not, however.&lt;/p&gt;
&lt;p&gt;The server component started up, instantiated a CORBA object, and saved the IOR into the registry.  Then my client component would start up and take the IOR from the registry, send a message to the CORBA server, do some data processing for about 15-30 minutes, and send another message to the CORBA server.  This issue I ran into is that usually the first message made it to the server, but the second one rarely did, with the error message:&lt;/p&gt;
&lt;ul class=&quot;code&quot;&gt;
&lt;li&gt;CORBA system exception : omg.org.CORBA.OBJECT_NOT_EXIST, completed: Completed_No minor: 0
omg.org.CORBA.OBJECT_NOT_EXIST: CORBA system exception : omg.org.CORBA.OBJECT_NOT_EXIST, completed: Completed_No minor: 0&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;Server stack trace:&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;&lt;/li&gt;
&lt;li&gt;Exception rethrown at [0]:&lt;/li&gt;
&lt;li&gt; &amp;nbsp; at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)&lt;/li&gt;
&lt;li&gt; &amp;nbsp; at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)&lt;/li&gt;
&lt;li&gt; &amp;nbsp; ...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this level of detail, it would appear that something goes wonky on the client side, since the first message &lt;i&gt;usually&lt;/i&gt; gets to the server, however, I also failed to mention that I &lt;i&gt;usually&lt;/i&gt; started the server and client at the same time.  When I did not start the server at the same time of the client, I would get the exception above.&lt;/p&gt;
&lt;p&gt;In light of this detail, it became very obvious that I had an object lifetime issue on the server.  Coming from more of a Java CORBA experience, I had assumed that the lifetime of the object would by-default be long-lived, however, it appears that this is not the case.  To make your IIOP.NET objects long-lived (or to control the default behaviour), your objects that derive from &lt;code&gt;System.MarshalByRefObject&lt;/code&gt; must override the method &lt;code&gt;&lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemmarshalbyrefobjectclassinitializelifetimeservicetopic.asp&quot;&gt;InitializeLifetimeService()&lt;/a&gt;&lt;/code&gt;.  The follow makes the object live forever:&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;public class &lt;a href=&quot;/CORBA/CS/TimeImpl.cs&quot;&gt;TimeImpl&lt;/a&gt; : &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemmarshalbyrefobjectclasstopic.asp&quot;&gt;System.MarshalByRefObject&lt;/a&gt;, TimeTools.Time {&lt;/li&gt;
&lt;li&gt;// ...&lt;/li&gt;
&lt;li&gt; &amp;nbsp; public override object InitializeLifetimeService() {&lt;/li&gt;
&lt;li&gt; &amp;nbsp;  &amp;nbsp; return null;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; }&lt;/li&gt;
&lt;li&gt;// ...&lt;/li&gt;
&lt;li&gt;}&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Since my objects are all long-lived, the above fixed my problem.  The documentation for &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemmarshalbyrefobjectclassinitializelifetimeservicetopic.asp&quot;&gt;InitializeLifetimeService()&lt;/a&gt; does, however, have some other examples in the event that you need more fine-grained control.&lt;/p&gt;</description>
      <pubDate>Wed, 22 Mar 2006 11:15:17 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/121/</link>
    </item>
        <item>
      <title>OpenNETCF.org Desktop.Communication Library 2.9...</title>
      <description>&lt;p&gt;About a month ago, a new version of &lt;a href=&quot;http://www.opennetcf.org/PermaLink.aspx?guid=d7b7cbef-4ab6-477b-924c-0498a523beaf&quot;&gt;OpenNETCF.org Desktop.Communication Library&lt;/a&gt; was released, and I finally got a chance to work with it last night.  Unfortunately, the problem I discussed &lt;a href=&quot;http://www.eyt.ca/blog/item/117/&quot;&gt;here&lt;/a&gt; regarding the FileInformation buffer is too small is still an issue in this release.  I think that it was accidently removed, since the file has a number of whitespace-type changes from the previous release.&lt;/p&gt;
&lt;p&gt;Another issue that has not been fixed is the issue I &lt;a href=&quot;http://www.opennetcf.org/forums/topic.asp?TOPIC_ID=6799&quot;&gt;reported&lt;/a&gt; to the forums.  The issue is that if the RAPI fails to communicate with ActiveSync, an exception is thrown, but the finalizer is still called, and the finalizer does not properly handle the case where the constructor is not ran to completion.  This is handled by a quick fix of (changes are in bold):&lt;/p&gt;
&lt;ol class=&quot;code&quot;&gt;
&lt;li&gt;// ...&lt;/li&gt;
&lt;li&gt;~RAPI()&lt;/li&gt;
&lt;li&gt;{&lt;/li&gt;
&lt;li&gt;&lt;b&gt; &amp;nbsp; if ( m_activesync != null ) {&lt;/b&gt;&lt;/li&gt;
&lt;li&gt; &amp;nbsp; &amp;nbsp; m_activesync.EndListen();&lt;/li&gt;
&lt;li&gt;&lt;b&gt; &amp;nbsp; }&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;// ...&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And aside from hitting the first problem in my application, the new release seems good after patching the above two issues.&lt;/p&gt;</description>
      <pubDate>Wed, 22 Mar 2006 08:44:15 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/120/</link>
    </item>
        <item>
      <title>java.util.concurrent Memory Leaks...</title>
      <description>&lt;p&gt;About two months ago, one of the Java servers my group maintains ran out of memory, and since then, if this service was up for more than a week, again, we get the dreaded &lt;code&gt;java.lang.OutOfMemoryError&lt;/code&gt;.  Each time that this would happen, we would take a histogram of the memory usage (&lt;kbd&gt;jmap -histo &lt;var&gt;pid&lt;/var&gt;&lt;/kbd&gt;).  After gathering a few of those and comparing those results to what we expected, there are two classes that seemed suspiciously using a lot of memory, &lt;code&gt;java.util.concurrent.LinkedBlockingQueue$Node&lt;/code&gt; and &lt;code&gt;java.util.concurrent.locks.AbstractQueuedSynchronizer$Node&lt;/code&gt;, so I started looking at how these classes were used.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/LinkedBlockingQueue.html&quot;&gt;java.util.concurrent.LinkedBlockingQueue&lt;/a&gt; was used in several places in the program, however, its usage was fairly straight forward.  In addition to usually being the one that used the most memory, the other thing that made this class suspect was that its usage was just added a week before the problem first occurred.  Furthermore, in all of the various tests that I ran, the number of &lt;code&gt;Node&lt;/code&gt;s would increase significantly, but when the full garbage collector ran (either automatically or when forced), the number of nodes would drop to the number of entries that I expected there to be.  This made me suspect that perhaps the garbage collector was not running when the OutOfMemoryError was thrown or that perhaps there was not enough memory at that point to even run the garbage collector, but alas, I was quickly brought back to my senses.&lt;/p&gt;
&lt;p&gt;During the investigation of the above, I googled on the class and it brought some interesting results.  On the Concurrency Interest mailing list, an entry from last year &lt;a href=&quot;http://altair.cs.oswego.edu/pipermail/concurrency-interest/2005-January/001318.html&quot;&gt;suggests a memory leak in LinkedBlockingQueue&lt;/a&gt; and it was &lt;a href=&quot;http://altair.cs.oswego.edu/pipermail/concurrency-interest/2005-January/001319.html&quot;&gt;confirmed&lt;/a&gt; by &lt;a href=&quot;http://gee.cs.oswego.edu/dl/&quot;&gt;Doug Lea&lt;/a&gt;.  I &lt;a href=&quot;http://www.eyt.ca/CORBA/Java/src/ca/eyt/tests/ConcurrentMemoryLeak.java&quot;&gt;re-wrote the program&lt;/a&gt; (in the method: &lt;code&gt;originallyReportedLeak&lt;/code&gt;) suggested in the message to confirm that it was an actual issue, and surely, it is a current problem.  Running the program with the JMX arguments, you can attach &lt;kbd&gt;jconsole&lt;/kbd&gt; to see the memory grow, and no amount of forcing the garbage collector to run will bring it down.&lt;/p&gt;
&lt;p&gt;But of course, that was not my problem.  The issue with the leak in the above program has to do with a timeout occurring.  In all but one of the cases was not using the methods with a timeout, and in that case, however, the timeout value was &lt;code&gt;MAX_INT&lt;/code&gt;, and because of the way we use this particular service, there is no way that it would have been able to timeout and leak.  And as I mentioned above, forcing a garbage collection always brought it back to normal, so alas, back to the drawing board.&lt;/p&gt;
&lt;p&gt;The other class that used outrageous amounts of memory, &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/AbstractQueuedSynchronizer.html&quot;&gt;AbstractQueuedSynchronizer&lt;/a&gt;&amp;rsquo;s Node inner class, however, was not as easy to find where it was used.  By using &lt;a href=&quot;http://www.borland.com/us/products/optimizeit/&quot;&gt;Borland OptimizeIt&lt;/a&gt;, however, I found out that this class was used by &lt;code&gt;&lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html&quot;&gt;java.util.concurrent.CountDownLatch&lt;/a&gt;&lt;/code&gt;, where the code was calling &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html#await(long,%20java.util.concurrent.TimeUnit)&quot;&gt;await()&lt;/a&gt; with a one second timeout, and in this case, the timeout was always triggered.  Sound familiar?  I &lt;a href=&quot;http://www.eyt.ca/CORBA/Java/src/ca/eyt/tests/ConcurrentMemoryLeak.java&quot;&gt;wrote a program&lt;/a&gt; (in the method: &lt;code&gt;anotherSimilarLeak&lt;/code&gt;) that demonstrates this precise memory leak, and surely, it is the same underlying problem as in the LinkedBlockingQueue above.&lt;/p&gt;
&lt;p&gt;In this particular program, we decided that the latch was not necessary for this particular method, and that replacing it with a sleep was all that was necessary.  This &lt;a href=&quot;http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6236036&quot;&gt;Bug is fixed in Mustang&lt;/a&gt;, the next version of Java, so hopefully your project can wait until it fixed.  Otherwise, you may unfortunately need to roll-your-own timeout functionality... just make sure to properly document such hacks so that you can remove them in the near future!&lt;/p&gt;</description>
      <pubDate>Wed, 18 Jan 2006 22:58:23 PST</pubDate>
      <link>http://www.eyt.ca/blog/item/119/</link>
    </item>
      </channel>
</rss>