<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Greymeister.net]]></title>
  <link href="http://www.greymeister.net/atom.xml" rel="self"/>
  <link href="http://www.greymeister.net/"/>
  <updated>2012-02-22T03:05:40-05:00</updated>
  <id>http://www.greymeister.net/</id>
  <author>
    <name><![CDATA[Charles Erwin]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[The Problem With Architects]]></title>
    <link href="http://www.greymeister.net/blog/2012/02/22/the-problem-with-architects/"/>
    <updated>2012-02-22T03:03:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/02/22/the-problem-with-architects</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="http://www.youtube.com/embed/JznYDwazfYc" frameborder="0" allowfullscreen></iframe>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The 2012 Presidential Election in a Nutshell]]></title>
    <link href="http://www.greymeister.net/blog/2012/02/19/the-2012-presidential-election-in-a-nutshell/"/>
    <updated>2012-02-19T23:51:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/02/19/the-2012-presidential-election-in-a-nutshell</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="http://www.youtube.com/embed/G7iMqgOkbzo" frameborder="0" allowfullscreen></iframe>


<p>I think it&#8217;s pretty much a <a href="http://www.usatoday.com/news/washington/2007-04-26-tenet-interview_N.htm">slam dunk</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mount &amp; Blade Face Code Fun]]></title>
    <link href="http://www.greymeister.net/blog/2012/02/06/mount-and-blade-face-code-fun/"/>
    <updated>2012-02-06T23:33:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/02/06/mount-and-blade-face-code-fun</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been toying around with editing my <a href="http://www.taleworlds.com/">Mount and Blade</a> character&#8217;s looks for some time, and found
that one of the more annoying aspects is that the code generated is not the same format as the one when you export your character.</p>

<p><img src="http://images.greymeister.net.s3-website-us-east-1.amazonaws.com/mount_and_blade_character_screen.jpg" width="512" height="320" title="Character Editor Screen" alt="So original looking"></p>

<p>However, after looking at the different face code strings, I did see a method to the madness, and managed to create a crappy VBS file
that makes it easy for me to go from the one in the editor screen to the one in the character file.</p>

<!-- more -->




<figure class='code'><figcaption><span>facecode.vbs</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
</pre></td><td class='code'><pre><code class='vbnet'><span class='line'><span class="n">strInput</span> <span class="o">=</span> <span class="n">InputBox</span><span class="p">(</span><span class="s">&quot;Enter Full Face Code from CTRL-E on Character Screen&quot;</span><span class="p">,</span><span class="s">&quot;Facecode Converter&quot;</span><span class="p">)</span>
</span><span class='line'><span class="n">firstCode</span> <span class="o">=</span> <span class="n">GetFirstPart</span><span class="p">(</span> <span class="n">strInput</span> <span class="p">)</span>
</span><span class='line'><span class="n">lastCode</span> <span class="o">=</span> <span class="n">GetSecondPart</span><span class="p">(</span> <span class="n">strInput</span> <span class="p">)</span>
</span><span class='line'><span class="c">&#39; Thanks to http://nerds-central.blogspot.com/2007/01/using-vbscript-to-paste-text-into.html</span>
</span><span class='line'><span class="c">&#39; Open notepad </span>
</span><span class='line'><span class="k">Set</span> <span class="n">WshShell</span> <span class="o">=</span> <span class="n">WScript</span><span class="p">.</span><span class="n">CreateObject</span><span class="p">(</span><span class="s">&quot;WScript.Shell&quot;</span><span class="p">)</span>
</span><span class='line'><span class="n">WshShell</span><span class="p">.</span><span class="n">Run</span> <span class="s">&quot;notepad&quot;</span><span class="p">,</span> <span class="mi">9</span>
</span><span class='line'>
</span><span class='line'><span class="c">&#39; Give Notepad time to load</span>
</span><span class='line'><span class="n">WScript</span><span class="p">.</span><span class="n">Sleep</span> <span class="mi">1000</span>
</span><span class='line'>
</span><span class='line'><span class="n">WshShell</span><span class="p">.</span><span class="n">SendKeys</span> <span class="s">&quot;// Replace the bottom of your character text file with the following 2 lines: {ENTER}&quot;</span>
</span><span class='line'><span class="n">WshShell</span><span class="p">.</span><span class="n">SendKeys</span> <span class="s">&quot;face_key_1 = &quot;</span> <span class="o">&amp;</span> <span class="n">firstCode</span> <span class="o">&amp;</span> <span class="s">&quot; {ENTER}&quot;</span>
</span><span class='line'><span class="n">WshShell</span><span class="p">.</span><span class="n">SendKeys</span> <span class="s">&quot;face_key_2 = &quot;</span> <span class="o">&amp;</span> <span class="n">lastCode</span> <span class="o">&amp;</span> <span class="s">&quot; {ENTER}&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="k">Function</span> <span class="nf">GetFirstPart</span><span class="p">(</span> <span class="n">faceCode</span> <span class="p">)</span>
</span><span class='line'>  <span class="c">&#39; Take the first part of the face code based on substrings</span>
</span><span class='line'>  <span class="n">first16</span> <span class="o">=</span> <span class="n">Mid</span><span class="p">(</span> <span class="n">faceCode</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">16</span> <span class="p">)</span>
</span><span class='line'>  <span class="n">first16AsDecimal</span> <span class="o">=</span> <span class="n">Hex_to_Dec</span><span class="p">(</span> <span class="n">first16</span> <span class="p">)</span>  
</span><span class='line'>  <span class="n">GetFirstPart</span> <span class="o">=</span> <span class="n">MyHex</span><span class="p">(</span> <span class="n">first16AsDecimal</span> <span class="p">)</span>
</span><span class='line'>  <span class="n">WScript</span><span class="p">.</span><span class="n">Echo</span> <span class="s">&quot;First Code &quot;</span> <span class="o">&amp;</span> <span class="n">GetFirstPart</span>   
</span><span class='line'><span class="k">End</span> <span class="k">Function</span>
</span><span class='line'>
</span><span class='line'><span class="k">Function</span> <span class="nf">GetSecondPart</span><span class="p">(</span> <span class="n">faceCode</span> <span class="p">)</span>
</span><span class='line'>  <span class="c">&#39; Take the first part of the face code based on substrings</span>
</span><span class='line'>  <span class="n">secondPart</span> <span class="o">=</span> <span class="n">Mid</span><span class="p">(</span> <span class="n">faceCode</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="mi">32</span> <span class="p">)</span>
</span><span class='line'>  <span class="n">GetSecondPart</span> <span class="o">=</span> <span class="n">Left</span><span class="p">(</span> <span class="n">secondPart</span><span class="p">,</span> <span class="mi">16</span> <span class="p">)</span>
</span><span class='line'>  <span class="n">WScript</span><span class="p">.</span><span class="n">Echo</span> <span class="s">&quot;Second Code &quot;</span> <span class="o">&amp;</span> <span class="n">GetSecondPart</span> 
</span><span class='line'><span class="k">End</span> <span class="k">Function</span>
</span><span class='line'>
</span><span class='line'><span class="k">Function</span> <span class="nf">Hex_to_Dec</span><span class="p">(</span><span class="n">hex_value</span><span class="p">)</span>
</span><span class='line'>  <span class="n">Hex_to_Dec</span> <span class="o">=</span> <span class="k">CDbl</span><span class="p">(</span><span class="s">&quot;&amp;h&quot;</span> <span class="o">&amp;</span> <span class="n">hex_value</span><span class="p">)</span>
</span><span class='line'><span class="k">End</span> <span class="k">Function</span>
</span><span class='line'>
</span><span class='line'><span class="k">Function</span> <span class="nf">MyHex</span><span class="p">(</span><span class="k">ByVal</span> <span class="n">Number</span><span class="p">)</span>
</span><span class='line'><span class="c">&#39; Thanks to http://blogs.msdn.com/b/ericlippert/archive/2004/08/30/222760.aspx for this</span>
</span><span class='line'>  <span class="k">Dim</span> <span class="n">Sign</span>
</span><span class='line'>  <span class="k">Const</span> <span class="n">HexChars</span> <span class="o">=</span> <span class="s">&quot;0123456789ABCDEF&quot;</span>
</span><span class='line'>  <span class="n">Sign</span> <span class="o">=</span> <span class="n">Sgn</span><span class="p">(</span><span class="n">Number</span><span class="p">)</span>
</span><span class='line'>  <span class="n">Number</span> <span class="o">=</span> <span class="n">Fix</span><span class="p">(</span><span class="n">Abs</span><span class="p">(</span><span class="k">CDbl</span><span class="p">(</span><span class="n">number</span><span class="p">)))</span>
</span><span class='line'>  <span class="k">If</span> <span class="n">Number</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">Then</span>
</span><span class='line'>    <span class="n">MyHex</span> <span class="o">=</span> <span class="s">&quot;0&quot;</span>
</span><span class='line'>    <span class="k">Exit</span> <span class="k">Function</span>
</span><span class='line'>  <span class="nf">End</span> <span class="k">If</span>
</span><span class='line'>  <span class="k">While</span> <span class="n">Number</span> <span class="o">&gt;</span> <span class="mi">0</span>
</span><span class='line'>    <span class="n">MyHex</span> <span class="o">=</span> <span class="n">Mid</span><span class="p">(</span><span class="n">HexChars</span><span class="p">,</span> <span class="mi">1</span> <span class="o">+</span> <span class="p">(</span><span class="n">Number</span> <span class="o">-</span> <span class="mi">16</span> <span class="o">*</span> <span class="n">Fix</span><span class="p">(</span><span class="n">Number</span> <span class="o">/</span> <span class="mi">16</span><span class="p">)),</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="n">MyHex</span>
</span><span class='line'>    <span class="n">Number</span> <span class="o">=</span> <span class="n">Fix</span><span class="p">(</span><span class="n">Number</span><span class="o">/</span><span class="mi">16</span><span class="p">)</span>
</span><span class='line'>  <span class="k">WEnd</span>
</span><span class='line'>  <span class="k">If</span> <span class="n">Sign</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> <span class="k">Then</span> <span class="n">MyHex</span> <span class="o">=</span> <span class="s">&quot;-&quot;</span> <span class="o">&amp;</span> <span class="n">MyHex</span>
</span><span class='line'><span class="k">End</span> <span class="k">Function</span>
</span></code></pre></td></tr></table></div></figure>


<p>Ugly, as most <a href="http://en.wikipedia.org/wiki/VBScript">VBScript</a> is to me.  Unfortunately, Mount and Blade only runs on Windows.  I would
love it if I could stop having to use my Windows machine to play on it, but that&#8217;s a sacrifice I&#8217;m willing to make for this awesome game.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hudson]]></title>
    <link href="http://www.greymeister.net/blog/2012/02/02/hudson/"/>
    <updated>2012-02-02T16:32:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/02/02/hudson</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="http://www.youtube.com/embed/qrjFuTbl_SA" frameborder="0" allowfullscreen></iframe>


<p>Game over man.  <strong>Game over</strong>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ned Stark can't win at Mount &amp; Blade]]></title>
    <link href="http://www.greymeister.net/blog/2012/02/02/ned-stark-cant-win-at-mount-and-blade/"/>
    <updated>2012-02-02T11:19:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/02/02/ned-stark-cant-win-at-mount-and-blade</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="http://www.youtube.com/embed/D3PeNGsuAr8" frameborder="0" allowfullscreen></iframe>


<p>I have been spending <strong>way</strong> too much time playing this game lately.  More details to come.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The 2012 Presidential Match Game]]></title>
    <link href="http://www.greymeister.net/blog/2012/01/25/the-2012-presidential-match-game/"/>
    <updated>2012-01-25T20:15:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/01/25/the-2012-presidential-match-game</id>
    <content type="html"><![CDATA[<p><a href="http://www.usatoday.com/news/politics/candidate-match-game">USA Today</a> has a nice little website to let you pick a stance out of
a set of choices to see which of the theoretical candidates we get to vote on in November.  This is obviously not scientific, but
it&#8217;s still interesting because they based the choices on quotes from each of the candidates while they&#8217;ve been campaigning.</p>

<p><img src="http://images.greymeister.net.s3-website-us-east-1.amazonaws.com/2012_candidate_match_game.png" alt="political-match-game"></p>

<p>I wasn&#8217;t too surprised by my results.  I think for progressives, it has become a sad cycle of having to pick
the least conservative of the two options available.  We haven&#8217;t had a good progressive candidate since I&#8217;ve
been able to vote.</p>

<p>Oh, and by the way, this site uses Flash.  If by chance you&#8217;re one of those people who brag about disabling
Flash in your browser, don&#8217;t bother.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Go Get Your Shinebox]]></title>
    <link href="http://www.greymeister.net/blog/2012/01/18/go-get-your-shinebox/"/>
    <updated>2012-01-18T20:44:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/01/18/go-get-your-shinebox</id>
    <content type="html"><![CDATA[<iframe width="420" height="315" src="http://www.youtube.com/embed/2oP1NMB_I0s" frameborder="0" allowfullscreen></iframe>


<p>Great <a href="http://5by5.tv/movies/1">discussion</a> on <a href="http://5by5.tv">5by5</a> about the
classic movie <a href="http://www.imdb.com/title/tt0099685/">Goodfellas</a>.  <a href="https://twitter.com/#!/danbenjamin">Dan</a>
and <a href="https://twitter.com/#!/siracusa">John</a> devote a good 3 hours to the subject.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Boomer Ballin]]></title>
    <link href="http://www.greymeister.net/blog/2012/01/16/boomer-ballin/"/>
    <updated>2012-01-16T18:44:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/01/16/boomer-ballin</id>
    <content type="html"><![CDATA[<iframe width="560" height="315" src="http://www.youtube.com/embed/7yN3IP6rkvQ" frameborder="0" allowfullscreen></iframe>


<p>If nothing else, this just validates that Coach is the hippest character in the <a href="http://www.l4d.com/blog/">Left 4 Dead</a>
franchise.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Just How Out of Touch are Slashdot Commenters?]]></title>
    <link href="http://www.greymeister.net/blog/2012/01/10/just-how-out-of-touch-are-slashdot-commenters/"/>
    <updated>2012-01-10T09:22:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2012/01/10/just-how-out-of-touch-are-slashdot-commenters</id>
    <content type="html"><![CDATA[<p>I still read <a href="http://slashdot.org">Slashdot</a> daily in my RSS reader&#8230; for now.  While the
articles linked to usually contain interesting information, the comments are another story.  Comments have
always been a big component of Slashdot, but the way they work now feels more like a relic of the  past.  There have
been <a href="http://shawnblanc.net/2007/07/why-daring-fireball-is-comment-free/">several</a> <a href="http://mattgemmell.com/2012/01/03/comments-still-off/">blogs</a>
which are noteworthy for adhering to the idea that comments do not belong on a blog.  If you want to reach out or react to
content on the web, there are <a href="https://plus.google.com/">so</a> <a href="http://facebook.com">many</a> <a href="http://twitter.com">ways</a> to
achieve that now that blog comments should be segregated from the blog content and channeled through the appropriate
social network.</p>

<p>Whether Slashdot decides to do that is not the point of this post, but that they need to do something different.  The
content on Slashdot has not decreased in quality, but I think that the comments have.  I present three specific articles
that I think aptly demonstrates how terrible they really are now.</p>

<!-- more -->


<h2><a href="http://it.slashdot.org/story/11/12/18/2154224/how-to-thwart-the-high-priests-in-it">How to Thwart the High Priests In IT</a></h2>

<p>Okay, so right off the bat I immediately empathize with the title of this post.  Anyone who has had the misfortune of
working at big companies and dealing with an out-of-control IT bureaucracy probably will feel the same way.  As someone
who writes software for a living, I am always demanding more of the hardware and software I use to meet my deadlines and
ship software.  However, any situation involving IT turns into a quagmire.  For example, at one time, it was the policy to
start encrypting your hard drive on any laptop after some sales executive lost their laptop on vacation.  Fine, I enabled
encryption on my Ubuntu laptop I was using.  Suddenly though, it was apparent that &#8220;encryption&#8221; meant installing this very
specific software suite on a Windows machine.  &#8220;Linux Encryption is impossible.  Because it is Open Source you see.&#8221;  WOW.</p>

<p>Anyway, here&#8217;s a few of the comments on this article:</p>

<blockquote><p>Fine. When the CORPORATE network blows up, it isn&#8217;t &#8220;mine&#8221;, and I won&#8217;t give a shit. How does THAT sound?</p><p>&#8220;My Network&#8221; doesn&#8217;t imply &#8220;ownership&#8221; as much as it does &#8220;complete responsibility&#8221;, which is why TWITS like you don&#8217;t get it. &#8220;My Network&#8221; is something that I take a great deal of pride in. It is MY responsibility, and therefore it is MY network. It is like the sales guys getting all upset when another sales rep &#8220;steals my client&#8221;. It isn&#8217;t your client, it is the company. That isn&#8217;t YOUR desk, it is the company&#8217;s. It isn&#8217;t your office, it is the Company&#8217;s.</p><p>You get the point now?</p><footer><strong>Archangel Michael</strong><cite><a href='http://it.slashdot.org/comments.pl?sid=2580272&cid=38421248'>it.slashdot.org/&hellip;</a></cite></footer></blockquote>




<blockquote><p>Sounds like the article was written by a tool with no understanding of how enterprise IT works, and no grasp of what bringing alien, unknown systems into contact with critical infrastructure can lead to.</p><footer><strong>MaskedSlacker</strong><cite><a href='http://it.slashdot.org/comments.pl?sid=2580272&cid=38419266'>it.slashdot.org/&hellip;</a></cite></footer></blockquote>


<p>Oh yes, we know you&#8217;re important.  You don&#8217;t have to yell at us.</p>

<h2><a href="http://developers.slashdot.org/story/12/01/03/0315251/testing-the-mongodb-global-write-lock-improvements?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+Slashdot%2Fslashdot+%28Slashdot%29">Testing the MongoDB Global Write Lock Improvements</a></h2>

<p>For some background, <a href="http://www.mongodb.org/">MongoDB</a> is a very popular <a href="http://en.wikipedia.org/wiki/NoSQL">NoSQL</a>
solution for persistent storage.  This role has typically been filled by a <a href="http://en.wikipedia.org/wiki/Relational_database">RDBMS</a>
until recently.  This is largely due to some unique use cases that have arisen from the different type of processing that
social networking and other new technologies demand.  Well wait one second, I thought that was fairly well known in the
tech community?</p>

<blockquote><p>Congratulations. You matter enough to bother reinventing this wheel again. If you continue to matter for a meaningful amount of time you&#8217;ll end up locking individual documents, or whatever you call them. Oracle called that &#8216;row&#8217; locking. 15 years ago.</p><footer><strong>Anonymous Coward</strong><cite><a href='http://developers.slashdot.org/comments.pl?sid=2601014&cid=38569556'>developers.slashdot.org/&hellip;</a></cite></footer></blockquote>




<blockquote><p>For when you&#8217;re too cheap to spring for a BerkeleyDB license, some amateur playing a decade of catchup gives you everything you&#8217;d ever need, as long as you don&#8217;t need support, performance, stability or data integrity.</p><footer><strong>Rogerborg</strong><cite><a href='http://developers.slashdot.org/comments.pl?sid=2601014&cid=38575486'>developers.slashdot.org/&hellip;</a></cite></footer></blockquote>


<p>Um, okay.  Well they&#8217;re probably right, I mean this NoSQL business is silly then if it&#8217;s just rehashing old technology.  I
guess you could just stick with Oracle, I&#8217;m sure they won&#8217;t take part in any of
<a href="http://docs.google.com/viewer?a=v&amp;q=cache:G4pI4ZOkzWYJ:www.oracle.com/technetwork/database/debunking-nosql-twp-399992.pdf+oracle+debunking+nosql&amp;hl=en&amp;gl=uk&amp;pid=bl&amp;srcid=ADGEESiaUPuEdyJ9cnDc_GzgsfsNq6UytDZeO5f0pgDJyUeo7x-xfe2W091nseq4s1cIl9lZ79jmGT0TRpE5PF8svROWbJSjcbrm6TXb2AWfM2TaAa6Z80dEupN3oSFzZG6y9mWBsgTd&amp;sig=AHIEtbSXOrH6n87xP4yC4bqqMaLHSMBBNg">this NoSQL Hype</a>.  Oops,
<a href="http://www.wired.com/wiredenterprise/2011/10/oracle-nosql-database/">spoke too soon</a>.</p>

<h2><a href="http://news.slashdot.org/story/12/01/09/2359210/michael-dell-dismisses-tablet-threat-to-the-pc-market">Michael Dell Dismisses Tablet Threat To the PC Market</a></h2>

<p>Okay, the obvious point is that Michael Dell sells PCs, and tablets are a perceived threat on the PC market.  Of course,
Michael Dell <a href="http://www.zdnet.com/blog/btl/michael-dell-on-his-infamous-1997-apple-comment-video/61364">isn&#8217;t always right on his predictions anyway</a>.</p>

<blockquote><p>Trying to do much REAL WORK(tm) on a tablet is an exercise in frustration. By the time you add a keyboard and mouse so that you can be even marginally productive you might as well get the tablet so that you can work even where/when there isn&#8217;t a wireless network.</p><p>The tablet&#8217;s niche is on the couch or the train or the bus</p><footer><strong>icebike</strong><cite><a href='http://news.slashdot.org/comments.pl?sid=2612368&cid=38645090'>news.slashdot.org/&hellip;</a></cite></footer></blockquote>


<p>Do I even need to make a comment about this?  I think adding a keyboard means you don&#8217;t really understand what a tablet
is supposed to do, and if you have a hard time doing any work on a tablet, you&#8217;re probably using
<a href="http://www.marco.org/2011/11/17/kindle-fire-review">the wrong tablet</a>.</p>

<p>I don&#8217;t expect everyone to agree with me on my feelings about these comments, and of course there are some comments
that weren&#8217;t as out of touch with reality.  If anything, I hope it shows how comments don&#8217;t
necessarily add anything useful to site content.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[I Forgot how to uninstall Oracle]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/31/i-forgot-how-to-uninstall-oracle/"/>
    <updated>2011-12-31T19:55:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/31/i-forgot-how-to-uninstall-oracle</id>
    <content type="html"><![CDATA[<p>Near the end of the year I have been doing some housekeeping at work during the quiet days of December.  I was
about to install <a href="http://www.mongodb.org/">mongodb</a> on a development server for a new project, when I noticed the
server was low on disk space.  The culprit, an Oracle database I had installed near the beginning of the year.  This
made me laugh out loud when I realized that our team had not been using at since May.  After the initial amusement had
worn off, I suddenly realized something:</p>

<p>I had forgotten to how to uninstall Oracle.  The temerity!</p>

<!-- more -->


<p>After all, at my last job and for the past few years, installing and working with Oracle DB servers had become
old hat to me.  Whether we had to do some testing on a dump from production or we just needed a new
development database, I had learned how to do it myself.  Now, a year later, I was back to being an Oracle noob,
fumbling around looking for documentation.  Scouring Oracle blog posts for useless information and
broken links to supposedly useful information.  It finally came back to me deep inside some byzantine directory
like &#8220;/u01/app/oracle/11/dbms/oui&#8221; that I found what I needed to know.  Perhaps some last bit of forbidden knowledge
had been shaken loose by all of my searching, but eventually I was able to properly remove the last remnants of
Oracle 11g.</p>

<p>At first I felt a little ashamed: perfectly good knowledge of mine which had gone to waste from lack of use.  However,
thinking about it some more, it made me feel pretty good.  It was equivalent to forgetting how to wiggle the
TV antenna to get a broadcast station to come in without the static.  The tools I&#8217;m using now are far less
convoluted and are usually pretty easy to work with.  Anyone that I work with is perfectly capable of setting up
anything we use.  This made me think about what that role is like in a general case.  It can be enticing to be
&#8220;that wizard&#8221; who can get something working that no one else can.  Sure, you don&#8217;t want to ask them any questions
about what they had to do in order for it to work, it must be magic!  Sadly, I&#8217;m no longer that person when it comes
to Oracle database setups on random GNU/Linux or Solaris systems.</p>

<p>While it was nice to have people rely on you for something, it&#8217;s not necessarily a good
thing if it is just because you know something no one else really cares about.  If setting up Oracle database
systems was my only talent, I would be in a pretty bad spot at my current job.  Suppose at your family you
have &#8220;Uncle Frank&#8221; who is a wizard and knowing where the tinfoil goes on the rabbit ears to make your 4 channels
come in without static.  Now, when you get cable and no longer need the rabbit ears, Uncle Frank might seem to
be a little grouchier than normal.  Fortunately for me, that&#8217;s not the case, as I&#8217;m happy to leave that part of
my experience in the past alongside other embarrassing knowledge that once seemed important.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dark Bands showing intermittently for MacBook Pro]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/26/dark-bands-showing-intermittently-for-macbook-pro/"/>
    <updated>2011-12-26T13:16:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/26/dark-bands-showing-intermittently-for-macbook-pro</id>
    <content type="html"><![CDATA[<p>This blog post is to capture a support article which helped me fix a problem on
my <a href="http://www.everymac.com/systems/apple/macbook_pro/stats/macbook-pro-core-2-duo-2.5-15-early-2008-penryn-specs.html">MacBook Pro</a>.  Google still
<a href="http://lmgtfy.com/?q=reset+monitor+macbook+pro">brings it up</a> as the first result, but Apple seems to &#8220;misplace&#8221;
the page when I visit it.  The <a href="http://support.apple.com/kb/TS1258">page in question</a> was live at the time of this post,
but I&#8217;m going to capture the relevant information here in case Apple misplaces the page again.</p>

<!-- more -->


<ul>
<li>Last Modified: October 28, 2009</li>
<li>Article: <a href="http://support.apple.com/kb/TS1258">TS1258</a></li>
</ul>


<h3>Symptoms</h3>

<p>You may see multiple, dark vertical bands or dark bumps starting along the bottom of the MacBook Pro
(15-inch, Early 2008) or MacBook Pro (17-inch, Early 2008) with the high resolution LED backlit display, as shown below.</p>

<p><img src="http://images.greymeister.net.s3-website-us-east-1.amazonaws.com/MBP Dark bands.jpg"/></p>

<h3>Resolution</h3>

<p>To help prevent this from occurring, download and install Mac OS X v10.5.3 or later from Apple Downloads.</p>

<p>If the issue persists when running Mac OS X v10.5.3 or later, a quick reset of the display panel will reset the LED backlights.</p>

<p>The quickest way to reset the display is to use the following key combination:</p>

<ul>
<li>Press Control - Shift - Eject.</li>
<li>After the display goes to sleep, wake it by pressing any key on the keyboard.</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Festivus For The Rest Of Us]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/23/festivus-for-the-rest-of-us/"/>
    <updated>2011-12-23T11:09:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/23/festivus-for-the-rest-of-us</id>
    <content type="html"><![CDATA[<p>It&#8217;s <a href="http://en.wikipedia.org/wiki/Festivus">that</a> time of year again.  Happy Festivus!</p>

<iframe width="420" height="315" src="http://www.youtube.com/embed/7KIMRsTu12g" frameborder="0" allowfullscreen></iframe>




<blockquote><p>That must have been some kind of doll.<br/>She was.</p><footer><strong>Seinfeld</strong><cite>The Strike</cite></footer></blockquote>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Hobbit Teaser Trailer]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/22/the-hobbit-teaser-trailer/"/>
    <updated>2011-12-22T13:19:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/22/the-hobbit-teaser-trailer</id>
    <content type="html"><![CDATA[<iframe width="1280" height="720" src="http://www.youtube.com/embed/G0k3kHtyoqc?hd=1" frameborder="0" allowfullscreen></iframe>


<p>It&#8217;s weird to think that <a href="http://www.imdb.com/title/tt0120737/">Fellowship of the Ring</a> came out 10 years ago this
month.  I can vividly remember how excited I was to see the movie, and how I wasn&#8217;t disappointed in the slightest when
I saw it on opening day.  This teaser trailer has got me just as excited, possibly even more so because I know what
kind of quality to expect in December, 2012.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Duane &amp; Brando - Final Fantasy]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/19/duane-and-brando-final-fantasy/"/>
    <updated>2011-12-19T22:30:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/19/duane-and-brando-final-fantasy</id>
    <content type="html"><![CDATA[<iframe width="420" height="315" src="http://www.youtube.com/embed/yc32Znoj8dk" frameborder="0" allowfullscreen></iframe>


<p>It&#8217;s truly a shame that these guys no longer produce videos.  Check out their individual sites here:
<a href="http://www.actionadventureworld.com/">Duane</a>
<a href="http://theamazingbrando.com/news.cfm">Brando</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Let Them Know it's Christmas Time]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/11/let-them-know-its-christmas-time/"/>
    <updated>2011-12-11T14:16:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/11/let-them-know-its-christmas-time</id>
    <content type="html"><![CDATA[<iframe width="420" height="315" src="http://www.youtube.com/embed/bmj7KlIut1w" frameborder="0" allowfullscreen></iframe>



]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Browsers I've Used]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/05/the-browsers-ive-used/"/>
    <updated>2011-12-05T08:17:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/05/the-browsers-ive-used</id>
    <content type="html"><![CDATA[<p>I&#8217;ve used several different web browsers over the years:</p>

<ul>
<li><a href="http://en.wikipedia.org/wiki/Netscape#Netscape_Navigator_.28versions_0.9.E2.80.934.08.29">Netscape Navigator Gold 3</a> - The browser my school system had installed.</li>
<li><a href="http://en.wikipedia.org/wiki/Netscape_Communicator">Netscape Communicator</a> - Just an upgraded version with more features.</li>
<li><a href="http://en.wikipedia.org/wiki/Mozilla_Application_Suite">Mozilla</a> - Netscape Communicator without the &#8220;N&#8221;.</li>
<li><a href="http://en.wikipedia.org/wiki/History_of_the_Opera_web_browser#Version_5">Opera</a> - The first browser I found with good tab navigation.</li>
<li><a href="http://en.wikipedia.org/wiki/Firefox_2">Mozilla Firefox</a> - I switched when several sites I visited stopped working.</li>
<li><a href="http://en.wikipedia.org/wiki/Safari_(web_browser)#Safari_5">Safari</a> - When Firefox 4 came out and broke every add-on I used with Macs.</li>
</ul>


<p>It&#8217;s been an interesting ride.  The story that came out last week about
<a href="http://gs.statcounter.com/press/chrome-overtakes-firefox-globally-for-first-time">Chrome overtaking Firefox</a>
in browser market share got me thinking about it.  I can&#8217;t say I&#8217;m surprised, it was hard
navigating to any of Google sites in the last few years without being inundated with &#8220;Try Google Chrome&#8221;
on each page.  I&#8217;ve never tried using Chrome as my primary browser. The only places I always install
it are on Linux machines or Windows Servers.  Chrome works pretty well on Linux machines, considering
that the computers I usually put Linux on are older laptops.  Windows Servers had IE so locked down
by default I couldn&#8217;t navigate anywhere, and I didn&#8217;t care enough to figure out exactly what policies
I needed to change in order to fix that.  I&#8217;d just copy a Chrome Installer.exe over onto the server
and be done with it.</p>

<p>The thing that surprises me about this list is that Safari is the first browser I&#8217;ve ever used that&#8217;s
the default for an operating system.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Real Problem With Carrier IQ]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/02/the-real-problem-with-carrier-iq/"/>
    <updated>2011-12-02T18:50:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/02/the-real-problem-with-carrier-iq</id>
    <content type="html"><![CDATA[<p>One of the biggest tech stories this week involved the independent discovery of an application embedded in
<a href="http://www.theregister.co.uk/2011/12/01/apple_sprint_carrier_iq/">several major smartphones</a>.  The application,
created by the company <a href="http://www.carrieriq.com/">Carrier IQ Inc.</a>, functions by &#8220;counting and measuring operational
information in mobile devices - feature phones, smartphones and tablets.&#8221;  According
to Trevor Eckhart, who <a href="http://androidsecuritytest.com/features/logs-and-services/loggers/carrieriq/carrieriq-part2/">reported</a>
the application&#8217;s existence and functionality, Carrier IQ&#8217;s software goes so far as to
<a href="http://en.wikipedia.org/wiki/Keystroke_logging">log individual keystrokes</a> made by the user.  The broad scope of
such capability seems to render concerns associated with
<a href="http://radar.oreilly.com/2011/04/apple-location-tracking.html">tracking location data</a> insignificant by
comparison.  Eckhart <a href="http://www.wired.com/threatlevel/2011/11/secret-software-logging-video/">demonstrates several examples</a>
of Carrier IQ&#8217;s interesting capabilities:</p>

<ul>
<li>Recording individual keys pressed by the user</li>
<li>Recording the contents of SMS messages</li>
<li>Recording requests made to websites, even when using HTTPS</li>
</ul>


<!-- more -->


<p>I recommend you watch Eckhart&#8217;s video.  If you feel the way I do about privacy, you should start to have
a sinking feeling about 9 minutes in.</p>

<iframe width="420" height="315" src="http://www.youtube.com/embed/T17XQI_AYNo" frameborder="0" allowfullscreen></iframe>


<p>All of this seems <a href="http://www.youtube.com/watch?v=jyaLZHiJJnE">bad</a>.  More
<a href="http://latimesblogs.latimes.com/technology/2011/12/carrier-iq-privacy.html">developments</a>
have been reported that seem to indicate that Eckhart&#8217;s findings portray Carrier IQ&#8217;s software
inaccurately.  I&#8217;m sure that this story is far from over, but I think the most shocking part to me is
unrelated to the veracity of Eckhart&#8217;s findings.  In response to Eckhart sharing his information, Carrier IQ sent him a
<a href="http://www.wired.com/threatlevel/2011/11/rootkit-brouhaha/">cease-and-desist notice</a> based on copyright
infringement related to hosting the company&#8217;s manuals on his website.  Eckhart argued that he wanted the
manuals in order to verify his research.  He obtained them from the Carrier IQ website, and
hosted them only as a precaution should they become unavailable from Carrier IQ.  According to Wired.com,
Carrier IQ had in fact removed the manuals around the same time they sent the
letter to Eckhart.  Another Wired.com article goes on to show how the <a href="https://www.eff.org/">EFF</a> stepped in, and not
long after that, <a href="http://www.wired.com/threatlevel/2011/11/rootkit-brouhaha-apology/">Carrier IQ apologized</a> for the
letter.</p>

<p>Carrier IQ&#8217;s response is more damning than anything Eckhart could have
demonstrated.  The &#8220;root&#8221; of the problem isn&#8217;t necessarily what mechanisms the application is capable of, but what
data it actually records.  It&#8217;s possible that Carrier IQ only records a small subset of what it is
capable of logging.  If they had been more transparent about it, this whole story goes from &#8220;brouhaha&#8221; to not
even newsworthy.  However, instead of disclosure, Carrier IQ&#8217;s initial reaction was to push the big red lawyer
button.  This means that the only notion I think anyone can take away is that Carrier IQ has something to
hide.  After threatening didn&#8217;t work, Carrier IQ defended themselves based on a premise that the
<a href="http://allthingsd.com/20111201/carrier-iq-speaks-our-software-monitors-service-messages-ignores-other-data/">carriers determine what information</a>
was collected and stored.  Why should full disclosure be a last resort if someone inaccurately portrays your work?  If
Carrier IQ&#8217;s claims are true, why not come out with that first and not after you fail in silencing your critics?</p>

<p>I would hope that most companies choose not to react the way Carrier IQ did to criticism.  They should be
up front in defending their products or at least acknowledging privacy issues when they arise.  By threatening legal
action against Eckhart as a first response, Carrier IQ set themselves up as a bully who can&#8217;t own up to the facts,
no matter how damaging they actually are.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why I Left blogspot.com]]></title>
    <link href="http://www.greymeister.net/blog/2011/12/01/why-i-left-blogspot-dot-com/"/>
    <updated>2011-12-01T00:29:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/12/01/why-i-left-blogspot-dot-com</id>
    <content type="html"><![CDATA[<p>I have recently resumed hosting my own blog.  My first absence from blogging was the result of
giving up on seemingly endless security patches required to keep my
<a href="http://drupal.org/">Drupal</a> blog alive.  When I started using the
<a href="http://en.wikipedia.org/wiki/Gratis_versus_libre">free as in beer</a> service blogspot.com, I thought
I had found the solution to my dearth of blogging.  Blogspot was used by
<a href="http://dave-klein.blogspot.com/">several</a> <a href="http://kensipe.blogspot.com/">technical</a>
<a href="http://javajeff.blogspot.com/">people</a> I had seen give presentations, and it was run by Google
who I was an embarrassingly huge fan of.  Without much hassle, I found it was sufficient to
publish any technical notes I accumulated and wanted to share.  However, recently I began
exploring alternatives for reasons I outline below.</p>

<!-- more -->


<ul>
<li><p><em>Customization</em>: I said free as in beer because on blogspot you are limited in what you can
use.  They have several designs, and I&#8217;ll admit the one I&#8217;m using is probably one of the
worst.  However, changing the design might break parts of my blog.  That is unless I modify
arcane CSS and Javascript inside of the blogspot web forms.  To explain what I mean, my first
customization was to install a library for highlighting code snippets.  I decided on the
<a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a> library by Alex Gorbatchev.
Installing it consisted of
<a href="http://www.cyberack.com/2007/07/adding-syntax-highlighter-to-blogger.html">combing through</a>
the blogspot template HTML to find the right places to include the required CSS and JS.  I
succeeded, but after the hassle, if I wanted to update or try a different library, the work involved
would deter me from even bothering.</p></li>
<li><p><em>Usability</em>: I am not completely averse to
<a href="http://5by5.tv/hypercritical/33">using HTML for my content</a>, but over the last few months I
have learned to love <a href="http://daringfireball.net/projects/markdown/">Markdown</a>, created by
John Gruber, to author my content.  It allows me to keep the data in an application agnostic
format, with the flexibility to generate HTML to publish or share it with others.  As someone who writes
code pretty regularly, having things in text is always more convenient than relying on an
application-specific format.  While HTML is not application-specific, it is not very
readable in source form in my opinion, and it lends itself to be noisy with all of the tags.</p></li>
<li><p><em>Content Corruption</em>: Another thing related to usability is the transmogrification my input goes
through while using blogspot.  It is very frustrating that the HTML content I used for my source
and what I see when I go to edit it are not identical.  Take for example this snippet
from one of my posts there:</p></li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;div</span> <span class="na">style=</span><span class="s">&quot;font-family: inherit;&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>I had been reading off and on the book <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;http://pragprog.com/titles/fr_r4j/rails-for-</span>
</span><span class='line'><span class="s">java-developers&quot;</span> <span class="na">target=</span><span class="s">&quot;_rfj&quot;</span><span class="nt">&gt;</span>Rails for Java Developers<span class="nt">&lt;/a&gt;</span> by Stuart Halloway and Justin
</span><span class='line'>Gehtland.<span class="ni">&amp;nbsp;</span> I recommend it for all developers, not for either a Java or Rails reference,
</span><span class='line'>but for interesting comparative analysis on web development technologies.<span class="ni">&amp;nbsp;</span> One of the things
</span><span class='line'>mentioned in that book is using <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">&quot;http://ar.rubyonrails.org/&quot;</span><span class="nt">&gt;</span>ActiveRecord<span class="nt">&lt;/a&gt;</span> for schema
</span><span class='line'>versioning even in applications not using Rails.<span class="ni">&amp;nbsp;</span> After playing around with ActiveRecord in
</span><span class='line'>their sample code for awhile, I thought it would clearly provide two big wins:<span class="nt">&lt;/div&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Like all the clutter?  Only the link markup was present when I submitted the
content.  When I converted that post to Markdown, it was incredibly annoying to have to prune
out the HTML noise blogspot had contributed.  The format of the HTML input was not completely
preserved, which made locating sections of a blog post additionally frustrating.</p>

<ul>
<li><p><em>Content Ownership</em>: This is late on this list but possibly the most important.  With recent
changes to both
<a href="http://www.marco.org/2011/11/13/google-reader-redesign-terrible-decision">Google Reader</a>
and GMail&#8217;s interfaces, relying on Google&#8217;s services is becoming increasingly risky.  It has also
become apparent that Google is not focused on any of its services unless they serve as a
mechanism for funneling people into Google+.  Blogspot is owned by Google and if their trend
continues, I have very little confidence that I will be able to continue using it the way I do
today.  I need to have my content in one place, and have control over my publishing
workflow.  Neither of these should change unless to adapt for my needs, not based on the
whims of a third-party.</p></li>
<li><p><em>Octopress</em>: I came across <a href="http://octopress.org/">Octopress</a> a few days ago.  I had been
looking for a blogging solution that relied on static files and I&#8217;d heard of
<a href="http://jekyllrb.com/">jekyll</a> but wasn&#8217;t thrilled by it.  I even started working on my own static
blogging engine based on Rails and Dropbox integration.  I had that working but by the time
I starting working on deployment, I found Octopress.  So far I love it, and I plan on tweaking
it as time goes on.</p></li>
</ul>


<p>One last note, I will not adopt a
<a href="http://www.steverubel.me/post/6070334427/why-i-adopted-a-scorched-earth-policy-dismantled-two">scorched earth</a>
policy when it comes to my old blog.  The links to my old articles may still be in someone&#8217;s bookmarks
or hyperlinks in other pages.  I will simply replace the content with a link to the updated
URL.  Shame on anyone for creating dead links purposefully.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Jackrabbit Clustering Primer]]></title>
    <link href="http://www.greymeister.net/blog/2011/11/28/jackrabbit-clustering-primer/"/>
    <updated>2011-11-28T20:53:00-05:00</updated>
    <id>http://www.greymeister.net/blog/2011/11/28/jackrabbit-clustering-primer</id>
    <content type="html"><![CDATA[<h2>Introduction</h2>

<p>I&#8217;ve worked with the <a href="http://jackrabbit.apache.org/">Apache Jackrabbit</a> implementation of the Java Content Repository
(also known as JCR or <a href="http://jcp.org/en/jsr/detail?id=170">JSR-170</a>) for some time now, and found it was a bit confusing
to get a load balanced implementation.  There are plenty of guides and documentation on the
<a href="http://wiki.apache.org/jackrabbit/FrontPage">Jackrabbit wiki</a> but piecing them together in a way that makes sense took a significant
effort.  The purpose of this blog post is to describe my approach in the hope that it may make it easier for others with the same goal in
mind.  I have created a <a href="https://github.com/greymeister/clustered-jackrabbit">GitHub project</a> with some of
the key configuration files included, please feel free to check it out to refer to it as I go along.</p>

<!-- more -->


<h2>Technology stack</h2>

<p>I will be describing how to use Jackrabbit 2.2.x with <a href="http://tomcat.apache.org/tomcat-6.0-doc/index.html">Apache Tomcat 6.0</a>.  I&#8217;ll also be
using an NFS shared filesystem and a <a href="http://www.postgresql.org">PostgreSQL 8.4</a> database.  Based on what you are using, there may be differences
and so my steps may not directly apply.  If you find something that gives you problems, please let me know and I&#8217;ll see if I can help.  I don&#8217;t
think it matters much, but this will be performed on VMs running <a href="http://www.centos.org">CENTOS 5.x 64-bit</a>.  It should also work on any other system that the
<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java J2SE</a> runs on, but you may have to alter configuration files such as
the file paths and mount points.</p>

<h2>Setting up the host systems</h2>

<p>Assuming we have a vanilla GNU/Linux system, the first priority will be installing Tomcat.  You may install using apt-get or some other package-based
installation, but I tend to use the binary distribution, especially for test purposes.  It essentially rules out mistakes I make when trying to
conform to the proper directory layout of some other distribution.  I initially create two directories, one for the tomcat server, and another for the
repository.  To follow along, I use</p>

<pre><code>/srv/tomcat                 # Location for Tomcat 6.x installation
/srv/repository/datastore   # Location for NFS mount point
</code></pre>

<p>I assign the owner as a user I&#8217;ve created named &#8220;tomcat&#8221;, mainly to avoid using the root user for running the Tomcat servers.  Generally, this is
just a user who does not have sudo priveleges but that can SSH into the system.  If your setup is similar, your /srv directory
will probably look something like this:</p>

<pre><code>drwxr-xr-x 5 tomcat users 4096 Nov 21 02:25 repository
drwxr-xr-x 9 tomcat users 4096 Nov 21 01:51 tomcat
</code></pre>

<p>I&#8217;ll also create a subdirectory &#8220;datastore&#8221; underneath the repository directory for the shared datastore mount point.
Here is the relevant entry in my /etc/fstab file for each system:</p>

<pre><code>//10.20.1.3/Public/datastore    /srv/repository/datastore   cifs    password="",uid=tomcat,gid=users    0 0
</code></pre>

<p>Any remote mount point will do.  It must be accessible by all nodes in the Jackrabbit cluster.  Make sure that the mount is active and that
the tomcat user has write privileges to before proceeding.</p>

<h2>Tomcat configuration</h2>

<p>I&#8217;ll assume you&#8217;ve unzipped the Apache Tomcat binary and have the default layout.  A directory listing should be similar to this one:</p>

<pre><code>drwxr-xr-x 2 tomcat tomcat   4096 Nov 20 02:29 bin
drwxr-xr-x 3 tomcat tomcat   4096 Nov 21 01:09 conf
drwxr-xr-x 2 tomcat tomcat   4096 Nov 20 23:24 lib
-rw-r--r-- 1 tomcat tomcat  38657 Jan 10  2011 LICENSE
drwxr-xr-x 2 tomcat tomcat   4096 Nov 21 01:42 logs
-rw-r--r-- 1 tomcat tomcat    574 Jan 10  2011 NOTICE
-rw-r--r-- 1 tomcat tomcat   8672 Jan 10  2011 RELEASE-NOTES
-rw-r--r-- 1 tomcat tomcat   6836 Jan 10  2011 RUNNING.txt
drwxr-xr-x 8 tomcat tomcat   4096 Nov 28 06:55 temp
drwxr-xr-x 6 tomcat tomcat   4096 Nov 21 01:52 webapps
drwxr-xr-x 3 tomcat tomcat   4096 Nov 20 02:29 work
</code></pre>

<p>From now on, I&#8217;ll refer to this as CATALINA_HOME.  Mine will be located in /srv/tomcat but yours can be anywhere else.  I will not be referencing a
CATALINA_BASE because I am not using a split Tomcat deployment.  The Tomcat configuration consists of exposing both a PostgreSQL datasource and the
Jackrabbit repository using <a href="http://www.oracle.com/technetwork/java/jndi/index.html">JNDI</a>.  Inside of CATALINA_HOME/conf there are two XML files to
edit.  The first is server.xml.  Edit the section &#8220;GlobalNamingResources&#8221; to contain a reference to your JDBC connection that the Jackrabbit
repository will use.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>  <span class="c">&lt;!-- Global JNDI resources</span>
</span><span class='line'><span class="c">       Documentation at /docs/jndi-resources-howto.html</span>
</span><span class='line'><span class="c">  --&gt;</span>
</span><span class='line'>  <span class="nt">&lt;GlobalNamingResources&gt;</span>
</span><span class='line'>    <span class="c">&lt;!-- Editable user database that can also be used by</span>
</span><span class='line'><span class="c">         UserDatabaseRealm to authenticate users</span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Resource</span> <span class="na">name=</span><span class="s">&quot;UserDatabase&quot;</span> <span class="na">auth=</span><span class="s">&quot;Container&quot;</span>
</span><span class='line'>        <span class="na">type=</span><span class="s">&quot;org.apache.catalina.UserDatabase&quot;</span>
</span><span class='line'>        <span class="na">description=</span><span class="s">&quot;User database that can be updated and saved&quot;</span>
</span><span class='line'>        <span class="na">factory=</span><span class="s">&quot;org.apache.catalina.users.MemoryUserDatabaseFactory&quot;</span>
</span><span class='line'>        <span class="na">pathname=</span><span class="s">&quot;conf/tomcat-users.xml&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;Resource</span> <span class="na">name=</span><span class="s">&quot;jdbc/repository&quot;</span> <span class="na">auth=</span><span class="s">&quot;Container&quot;</span>
</span><span class='line'>        <span class="na">type=</span><span class="s">&quot;javax.sql.DataSource&quot;</span> <span class="na">driverClassName=</span><span class="s">&quot;org.postgresql.Driver&quot;</span>
</span><span class='line'>        <span class="na">url=</span><span class="s">&quot;jdbc:postgresql://192.168.0.8:5432/jr_repository&quot;</span>
</span><span class='line'>        <span class="na">username=</span><span class="s">&quot;jackrabbit&quot;</span> <span class="na">password=</span><span class="s">&quot;jackrabbit&quot;</span>
</span><span class='line'>        <span class="na">validationQuery=</span><span class="s">&quot;select version();&quot;</span>
</span><span class='line'>        <span class="na">maxActive=</span><span class="s">&quot;20&quot;</span> <span class="na">maxIdle=</span><span class="s">&quot;10&quot;</span> <span class="na">maxWait=</span><span class="s">&quot;-1&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nt">&lt;/GlobalNamingResources&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>You&#8217;ll need to alter the configuration to suit your needs.  If you are using PostgreSQL like I am, all you need to do is create a database and user
for the repository cluster.  This will need to be the same for each cluster node.  The UserDatabase section is not required, I left it in as
a reference to the location in the server.xml file.  The next file to edit is context.xml.  You&#8217;ll need to add another JNDI resource, this time
for the repository.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="c">&lt;!-- The contents of this file will be loaded for each web application --&gt;</span>
</span><span class='line'><span class="nt">&lt;Context&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c">&lt;!-- Default set of monitored resources --&gt;</span>
</span><span class='line'>    <span class="nt">&lt;WatchedResource&gt;</span>WEB-INF/web.xml<span class="nt">&lt;/WatchedResource&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c">&lt;!-- Uncomment this to disable session persistence across Tomcat restarts --&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">    &lt;Manager pathname=&quot;&quot; /&gt;</span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c">&lt;!-- Uncomment this to enable Comet connection tacking (provides events</span>
</span><span class='line'><span class="c">         on session expiration as well as webapp lifecycle) --&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">    &lt;Valve className=&quot;org.apache.catalina.valves.CometConnectionManagerValve&quot; /&gt;</span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;ResourceLink</span> <span class="na">global=</span><span class="s">&quot;jdbc/repository&quot;</span>
</span><span class='line'>      <span class="na">name=</span><span class="s">&quot;jdbc/repository&quot;</span>
</span><span class='line'>      <span class="na">type=</span><span class="s">&quot;javax.sql.DataSource&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;Resource</span> <span class="na">name=</span><span class="s">&quot;jcr/repository&quot;</span>
</span><span class='line'>        <span class="na">auth=</span><span class="s">&quot;Container&quot;</span>
</span><span class='line'>        <span class="na">type=</span><span class="s">&quot;javax.jcr.Repository&quot;</span>
</span><span class='line'>        <span class="na">factory=</span><span class="s">&quot;org.apache.jackrabbit.core.jndi.BindableRepositoryFactory&quot;</span>
</span><span class='line'>        <span class="na">configFilePath=</span><span class="s">&quot;/srv/repository/repository.xml&quot;</span>
</span><span class='line'>        <span class="na">repHomeDir=</span><span class="s">&quot;/srv/repository&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;/Context&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>You&#8217;ll notice that I left some of the default configuration in there just as a reference.  The only tags relevant to the Jackrabbit configuration are
the ResourceLink to the jdbc/repository resource and the jcr/repository Resource definition.  You&#8217;ll notice the paths declared in that tag must be
where you plan on having the repository configured on the node.  I am still using my /srv/repository location.</p>

<p>The last step is to make sure that the proper libraries are available for tomcat to start the shared resources.  I had some problems getting the exact
right jar files in my CATALINA_HOME/lib directory, so I&#8217;m just going to show a directory listing.  Note that several of these jars will be present in
the default Tomcat installation.</p>

<pre><code>-rw-r--r-- 1 tomcat tomcat  481535 Nov 20 23:24 log4j-1.2.16.jar
-rw-r--r-- 1 tomcat tomcat    9753 Nov 20 23:24 slf4j-log4j12-1.6.1.jar
-rw-r--r-- 1 tomcat tomcat   62086 Nov 20 23:23 commons-pool-1.3.jar
-rw-r--r-- 1 tomcat tomcat 2512189 Nov 20 23:22 derby-10.5.3.0_1.jar
-rw-r--r-- 1 tomcat tomcat  740930 Nov 20 23:21 jackrabbit-spi-commons-2.2.0.jar
-rw-r--r-- 1 tomcat tomcat   26822 Nov 20 23:20 jackrabbit-spi-2.2.0.jar
-rw-r--r-- 1 tomcat tomcat  286499 Nov 20 23:20 jackrabbit-jcr-commons-2.2.0.jar
-rw-r--r-- 1 tomcat tomcat   25496 Nov 20 23:20 slf4j-api-1.6.1.jar
-rw-r--r-- 1 tomcat tomcat  575389 Nov 20 23:19 commons-collections-3.2.1.jar
-rw-r--r-- 1 tomcat tomcat  121757 Nov 20 23:19 commons-dbcp-1.2.2.jar
-rw-r--r-- 1 tomcat tomcat  109043 Nov 20 23:19 commons-io-1.4.jar
-rw-r--r-- 1 tomcat tomcat 4326608 Nov 20 23:19 netcdf-4.2-min.jar
-rw-r--r-- 1 tomcat tomcat  189284 Nov 20 23:19 concurrent-1.3.4.jar
-rw-r--r-- 1 tomcat tomcat   23861 Nov 20 23:19 jackrabbit-api-2.2.0.jar
-rw-r--r-- 1 tomcat tomcat 2117338 Nov 20 23:18 jackrabbit-core-2.2.0.jar
-rw-rw-r-- 1 tomcat tomcat  539510 Nov 20 22:51 postgresql-8.4-702.jdbc4.jar
-rw-r--r-- 1 tomcat tomcat   69246 Nov 20 22:46 jcr-2.0.jar
-rw-r--r-- 1 tomcat tomcat   15239 Jan 10  2011 annotations-api.jar
-rw-r--r-- 1 tomcat tomcat   53756 Jan 10  2011 catalina-ant.jar
-rw-r--r-- 1 tomcat tomcat  129739 Jan 10  2011 catalina-ha.jar
-rw-r--r-- 1 tomcat tomcat 1208895 Jan 10  2011 catalina.jar
-rw-r--r-- 1 tomcat tomcat  237317 Jan 10  2011 catalina-tribes.jar
-rw-r--r-- 1 tomcat tomcat 1563059 Jan 10  2011 ecj-3.3.1.jar
-rw-r--r-- 1 tomcat tomcat   33410 Jan 10  2011 el-api.jar
-rw-r--r-- 1 tomcat tomcat  112550 Jan 10  2011 jasper-el.jar
-rw-r--r-- 1 tomcat tomcat  526946 Jan 10  2011 jasper.jar
-rw-r--r-- 1 tomcat tomcat   76692 Jan 10  2011 jsp-api.jar
-rw-r--r-- 1 tomcat tomcat   88210 Jan 10  2011 servlet-api.jar
-rw-r--r-- 1 tomcat tomcat  762878 Jan 10  2011 tomcat-coyote.jar
-rw-r--r-- 1 tomcat tomcat  253526 Jan 10  2011 tomcat-dbcp.jar
-rw-r--r-- 1 tomcat tomcat   70034 Jan 10  2011 tomcat-i18n-es.jar
-rw-r--r-- 1 tomcat tomcat   51965 Jan 10  2011 tomcat-i18n-fr.jar
-rw-r--r-- 1 tomcat tomcat   55036 Jan 10  2011 tomcat-i18n-ja.jar
</code></pre>

<h2>Repository configuration</h2>

<p>The repository configuration resides mostly in one file, the repository.xml file that must be at the root of each node&#8217;s repository location.
The complete repository.xml file I&#8217;m using will be in the
<a href="https://github.com/greymeister/clustered-jackrabbit">linked GitHub project</a>, so check that out for the
complete copy.  I will be describing each section though here where I think it is relevant.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;Repository&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">        virtual file system where the repository stores global state</span>
</span><span class='line'><span class="c">        (e.g. registered namespaces, custom node types, etc.)    </span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nt">&lt;FileSystem</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.fs.db.DbFileSystem&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>       <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;javax.naming.InitialContext&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>       <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;java:comp/env/jdbc/repository&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>       <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;rep_&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>       <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schema&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>   <span class="nt">&lt;/FileSystem&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The initial FileSystem definition is required to be shared based on the Jackrabbit Wiki
<a href="http://wiki.apache.org/jackrabbit/Clustering">clustering article</a>.  I am accessing it via the JNDI datasource set up in the previous section.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="c">&lt;!--</span>
</span><span class='line'><span class="c">    data store configuration</span>
</span><span class='line'><span class="c">--&gt;</span>
</span><span class='line'><span class="nt">&lt;DataStore</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.data.FileDataStore&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;path&quot;</span> <span class="na">value=</span><span class="s">&quot;${rep.home}/datastore&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;minRecordLength&quot;</span> <span class="na">value=</span><span class="s">&quot;100&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/DataStore&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <a href="http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/core/data/FileDataStore.html">Datastore implementation</a> I&#8217;m using requires the
file system to be shared amongst all the nodes.  Here, I am pointing it at the mount point I created earlier on the file server, in a subdirectory
of the repository home named &#8220;datastore&#8221;.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="nt">&lt;Workspaces</span> <span class="na">rootPath=</span><span class="s">&quot;${rep.home}/workspaces&quot;</span> <span class="na">defaultWorkspace=</span><span class="s">&quot;default&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="c">&lt;!--</span>
</span><span class='line'><span class="c">    workspace configuration template:</span>
</span><span class='line'><span class="c">    used to create the initial workspace if there&#39;s no workspace yet</span>
</span><span class='line'><span class="c">--&gt;</span>
</span><span class='line'><span class="nt">&lt;Workspace</span> <span class="na">name=</span><span class="s">&quot;${wsp.name}&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">        virtual file system of the workspace:</span>
</span><span class='line'><span class="c">        class: FQN of class implementing the FileSystem interface</span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>    <span class="nt">&lt;FileSystem</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.fs.local.LocalFileSystem&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;path&quot;</span> <span class="na">value=</span><span class="s">&quot;${wsp.home}&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/FileSystem&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">        persistence manager of the workspace:</span>
</span><span class='line'><span class="c">        class: FQN of class implementing the PersistenceManager interface</span>
</span><span class='line'><span class="c">--&gt;</span>
</span><span class='line'><span class="nt">&lt;PersistenceManager</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>         <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;javax.naming.InitialContext&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>         <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;java:comp/env/jdbc/repository&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>         <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;ws_&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>         <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schema&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/PersistenceManager&gt;</span>
</span><span class='line'>
</span><span class='line'><span class="nt">&lt;/Workspace&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is the <a href="http://jackrabbit.apache.org/jackrabbit-configuration.html#JackrabbitConfiguration-Workspaceconfiguration">workspace configuration</a>
I&#8217;m using.  It is pretty bare bones, but it uses a <a href="http://wiki.apache.org/jackrabbit/PersistenceManagerFAQ">PersistenceManager</a> based on the
recommendations of the Jackrabbit wiki.  Again, it will be pointed at the PostgreSQL JNDI datasource we set up in Tomcat.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'>   <span class="nt">&lt;Versioning</span> <span class="na">rootPath=</span><span class="s">&quot;${rep.home}/version&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">        Configures the filesystem to use for versioning for the respective</span>
</span><span class='line'><span class="c">        persistence manager</span>
</span><span class='line'><span class="c">    --&gt;</span>
</span><span class='line'>    <span class="nt">&lt;FileSystem</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.fs.local.LocalFileSystem&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>        <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;path&quot;</span> <span class="na">value=</span><span class="s">&quot;${rep.home}/version&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/FileSystem&gt;</span>
</span><span class='line'>
</span><span class='line'>    <span class="c">&lt;!--</span>
</span><span class='line'><span class="c">        Configures the persistence manager to be used for persisting version state.</span>
</span><span class='line'><span class="c">        Please note that the current versioning implementation is based on</span>
</span><span class='line'><span class="c">        a &#39;normal&#39; persistence manager, but this could change in future</span>
</span><span class='line'><span class="c">        implementations.</span>
</span><span class='line'><span class="c">--&gt;</span>
</span><span class='line'><span class="nt">&lt;PersistenceManager</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>          <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;javax.naming.InitialContext&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>          <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;java:comp/env/jdbc/repository&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>          <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;version_&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>          <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schema&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'><span class="nt">&lt;/PersistenceManager&gt;</span>
</span><span class='line'><span class="nt">&lt;/Versioning&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This is the <a href="http://jackrabbit.apache.org/jackrabbit-configuration.html#JackrabbitConfiguration-Versioningconfiguration">versioning configuration</a>
that I&#8217;m using.  Again, make sure it is pointed at the PostgreSQL datasource using JNDI.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='xml'><span class='line'><span class="c">&lt;!--</span>
</span><span class='line'><span class="c">    Cluster configuration with system variables.</span>
</span><span class='line'>
</span><span class='line'><span class="c">--&gt;</span>
</span><span class='line'><span class="nt">&lt;Cluster</span> <span class="na">id=</span><span class="s">&quot;node1&quot;</span> <span class="na">syncDelay=</span><span class="s">&quot;2000&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="nt">&lt;Journal</span> <span class="na">class=</span><span class="s">&quot;org.apache.jackrabbit.core.journal.DatabaseJournal&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;revision&quot;</span> <span class="na">value=</span><span class="s">&quot;${rep.home}/revision.log&quot;</span> <span class="nt">/&gt;</span>
</span><span class='line'>            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;driver&quot;</span> <span class="na">value=</span><span class="s">&quot;javax.naming.InitialContext&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;url&quot;</span> <span class="na">value=</span><span class="s">&quot;java:comp/env/jdbc/repository&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>            <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;databaseType&quot;</span> <span class="na">value=</span><span class="s">&quot;postgresql&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>             <span class="nt">&lt;param</span> <span class="na">name=</span><span class="s">&quot;schemaObjectPrefix&quot;</span> <span class="na">value=</span><span class="s">&quot;journal_&quot;</span><span class="nt">/&gt;</span>
</span><span class='line'>    <span class="nt">&lt;/Journal&gt;</span>
</span><span class='line'><span class="nt">&lt;/Cluster&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>The last and one of the most important pieces of information in the repository.xml file is the Cluster configuration.  Again we will point
to the PostgreSQL datasource using JNDI to store the <a href="http://wiki.apache.org/jackrabbit/Clustering#Journal_Type">journal</a>.  The journal will
allow a consistent view by producing a composite of the actions taken by individual nodes.  The one piece of information here that will change node
to node is the id attribute of the Cluster tag.  This <strong>must be</strong> unique for every node.</p>

<h2>Testing</h2>

<p>Start up tomcat server on one of the nodes.  You should have notifications that Jackrabbit has been started.  You should see some directories created
in your repository home directory for workspaces and versioning.  I would recommend deploying something like
<a href="http://www.jcr-explorer.org/">JCR-Explorer</a> and connecting to your JCR using JNDI.  You should be able to browse and add files to the repository.
<strong>Note</strong>: Be sure to use the JNDI name that we created, which within Tomcat will be <em>java:comp/env/jcr/repository</em></p>

<p><img src="http://images.greymeister.net.s3-website-us-east-1.amazonaws.com/jcr_explorer.png" alt="JCR Explorer"/></p>

<h2>Adding additional nodes</h2>

<p>At this point, all we&#8217;ve really created is a single Jackrabbit server running on Tomcat.  However, the next step allows a load balanced configuration.
The Jackrabbit Wiki notes that there are some limitations, but based on this default configuration, it is very easy to
<a href="http://wiki.apache.org/jackrabbit/Clustering#Easily_add_new_cluster_nodes">add additional nodes</a>.  If
you have been using a VM like me, all you need to do is:</p>

<ul>
<li>Shut down Tomcat</li>
<li>Create a clone of the GNU/Linux machine with the configuration on it</li>
<li>Update networking/etc to not conflict with the first node</li>
<li>Get the current revision number from your first node.  Here&#8217;s an SQL query on the PosgreSQL datasource</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">journal_local_revisions</span> <span class="k">where</span> <span class="n">journal_id</span> <span class="o">=</span> <span class="s1">&#39;node1&#39;</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li>Start up both GNU/Linux machines, and start Tomcat on the first node</li>
<li>Update the repository.xml file on the second node and give it a new Cluster ID, for example &#8220;node2&#8221;</li>
<li>Insert the new node&#8217;s location revision into the JOURNAL_LOCAL_REVISIONS table, again with my configuration:</li>
</ul>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sql'><span class='line'><span class="k">insert</span> <span class="k">into</span> <span class="n">journal_local_revisions</span> <span class="p">(</span><span class="n">journal_id</span><span class="p">,</span> <span class="n">revision_id</span><span class="p">)</span> <span class="k">values</span> <span class="p">(</span><span class="s1">&#39;node2&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<ul>
<li><strong>Note</strong>, replace the <em>revision_id</em> value of the insert clause with the number you got in the select statement.</li>
<li>Start Tomcat on the second node.</li>
</ul>


<p>Now, whenever you modify either repository directly (by using JCR-Explorer etc) you will see that the nodes synchronize using the journal.  You can
now put in any type of load balancing technology you wish in front of any number of Jackrabbit nodes, and have a fault-tolerant repository.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[PostgreSQL and PostGIS Cooperating on OSX Lion Server]]></title>
    <link href="http://www.greymeister.net/blog/2011/07/30/postgresql-and-postgis-cooperating-on-osx-lion-server/"/>
    <updated>2011-07-30T18:15:00-04:00</updated>
    <id>http://www.greymeister.net/blog/2011/07/30/postgresql-and-postgis-cooperating-on-osx-lion-server</id>
    <content type="html"><![CDATA[<p>I recently replaced my home server with some
<a href="http://www.everymac.com/systems/apple/xserve/stats/xserve-intel-nehalem-xeon-2.26-2009-eight-core-specs.html">Apple hardware</a>
and instead of having to buy a rather costly Server version of Snow Leopard, <a href="http://www.apple.com/macosx/">Lion</a>
had just come out, as well as an App store <a href="http://www.apple.com/macosx/server/">Server upgrade</a>
option.  I was delighted to hear that OSX Lion Server shipped with the
<a href="http://www.postgresql.org/">PostgreSQL database</a> that I use for my
<a href="http://www.frizfinder.com">application</a>.  I know that some people are probably surprised by
this, but I think it is an excellent choice over <a href="http://www.mysql.com">MySQL</a> which I try to avoid.</p>

<!-- more -->


<h2>Fingering postgres</h2>

<p>My first problem was finding the <em>postgres</em> user which is the daemon user for the PostgreSQL software
on a system.  I&#8217;m used to having to find it on
<a href="http://www.centos.org/">multiple</a> <a href="http://www.ubuntu.com/">systems</a> using
the <b>finger</b> command standard with modern *nix systems.  However, on OSX Lion, the user is
<em>_postgres</em> which seems draconian.  I guess that is a security feature but nonetheless I was able to
continue in my PostgreSQL setup.  Oddly enough, the database username is still <em>postgres</em>, so it is
likely that the underscore prefix is a standard way for Apple systems to designate daemon users, although
I doubt you would have many people who wanted to log in to a machine as <em>postgres</em> unless they were just
trying to break in via SSH.  I suppose it would be just as easy to try <em>_postgres</em> as an SSH remote user,
which is why Apple made the shell for <em>_postgres</em> <strong>/usr/bin/false</strong> reducing the risk of remote break in
attempts.  However, this just points out that the underscore naming scheme is completely superfluous.</p>

<h2>PostGIS</h2>

<p>One feature I always need to enable in my PostgreSQL installations is
<a href="http://en.wikipedia.org/wiki/Spatial_database">spatial indexes</a>.  Ever since I read the
<a href="http://www.amazon.com/GIS-Web-Developers-Adding-Applications/dp/0974514098/ref=sr_1_3?s=books&ie=UTF8&qid=1312061007&sr=1-3">excellent introduction</a>
by <a href="http://twitter.com/#!/scottdavis99">Scott Davis</a> on the subject I have used
<a href="http://postgis.refractions.net/">PostGIS</a> to enable that in PostgreSQL.  The
<a href="http://postgis.refractions.net/docs/ch02.html#id2565921">installation instructions</a> are
pretty straightforward once you&#8217;ve created your database, however, the required scripts were not included
in the PostgreSQL installation on OSX Lion Server.</p>

<p>To get the required scripts, I turned to my trusty friend
<a href="http://www.macports.org/">MacPorts</a>.  I keep hearing about how I shouldn&#8217;t use MacPorts and
how <a href="http://mxcl.github.com/homebrew/">Homebrew</a> is way better.  Having used
<a href="http://www.freebsd.org">FreeBSD</a> in the past, the MacPorts experience is very familiar to me
and it does its job.  Without going down a rat hole on this, MacPorts has worked very well for me in the
past and I usually don&#8217;t switch something I&#8217;ve used for so long unless I have a really good reason.</p>

<p>That said, obviously with Lion being so new, I expected a few humps getting MacPorts set up with it.<br/>
MacPorts has a PostGIS install which I use on my
<a href="http://www.everymac.com/systems/apple/mac_pro/stats/mac-pro-eight-core-3.0-specs.html">development
machine</a> with PostgreSQL already.  However, it looks like one of its dependencies
<a href="https://trac.macports.org/ticket/30309">is broken</a> at least as of the time of this writing.<br/>
However, there is a workaround in the ticket and thusly I was able to move forward.</p>

<h2>Remote Connections</h2>

<p>Last but not least, I always like to enable remote connections to my PostgreSQL server.  It makes
pointing my development work at it to test for incompatibilities easier, as well as many other things.  I
obviously would not do this if the machine were Internet reachable, so I understand that the default
option in OSX Lion&#8217;s install would be not to allow remote connections.  I went to configure the
<em>pg_hba.conf</em> file and made the appropriate configuration change and restarted PostgreSQL.  This is
slightly less convenient than Ubuntu because instead of running something like</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>sudo service postgres restart</span></code></pre></td></tr></table></div></figure>


<p>I had to familiarize myself with <em>launchd</em> and <em>launchctl</em> again.  I was able to find out the proper
command to stop and start PostgreSQL was using the name <em>org.postgresql.postgres</em>.  However, even after
restarting, I was still unable to connect from my workstation.  A little research in the form of</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>ps -ef | grep postgres
</span></code></pre></td></tr></table></div></figure>


<p>revealed that the process was getting launched with a command line option of <em>listen_addresses=</em> which
I assume was overwriting the option in the <em>postgresql.conf</em> file.  I had to comment this line out in
the plist file, located in <em>/System/Library/LaunchDaemons/org.postgresql.postgres.plist</em>.  To get
<strong>launchd</strong> to respect these changes, I had to run</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>launchctl unload org.postgresql.postgres.plist 
</span><span class='line'>launchctl load org.postgresql.postgres.plist  </span></code></pre></td></tr></table></div></figure>


<p>After that, I was able to connect from my workstation.</p>

<p>I&#8217;m not sure that this is the proper way to get the functionality I needed, but it might help someone
else who happens to be in a similar situation as I was.</p>
]]></content>
  </entry>
  
</feed>

