<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Marc Schwieterman</title>
  <link href="http://marcschwieterman.com/feed/" rel="self"/>
  <link href="http://marcschwieterman.com/"/>
  <updated>2019-01-31T19:00:00-08:00</updated>
  <id>http://marcschwieterman.com/</id>
  <generator>Hugo -- gohugo.io</generator>
  <entry>
    <title type="html"><![CDATA[Infinity and Beyond: Count &#43; 1]]></title>
    <link href="http://marcschwieterman.com/blog/infinity-and-beyond/2/"/>
    <id>http://marcschwieterman.com/blog/infinity-and-beyond/2</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2019-01-31T19:00:00-08:00</published>
    <updated>2019-01-31T19:00:00-08:00</updated>
    <content type="html"><![CDATA[<p>This is a follow up post to <a href="../1">Infinity and Beyond: Introduction</a>.</p>

<p>The &ldquo;Count + 1&rdquo; approach pads the row count by one and uses that extra row to
display loading and error information. While one of the simplest
implementations, it also has one of the worst user experiences.</p>

<h2 id="user-experience">User Experience</h2>












<figure>
  
    
      <img class="lazyload" data-src="../count-plus-one.gif" alt="Count &#43; 1" />
    
  
  
</figure>

<p>This approach&rsquo;s main weakness is its user experience. Because new content isn&rsquo;t
requested until the user reaches the end of the currently visible content, the
user is forced to wait for every screenful of information. This can be very
frustrating if they know that the content they&rsquo;re interested in is several
screens away. This approach also renders the scroll indicator useless because
the total row count increases with every content response.</p>

<h2 id="complexity">Complexity</h2>

<p>This is one of the least complicated implementation approaches. There&rsquo;s no need
for <code>OperationQueue</code>s or <code>DispatchQueue</code>s. The main thing you need to do is
manage request state, so that you don&rsquo;t make more than one request for a given
batch of data.</p>

<h2 id="code">Code</h2>

<p>What follows are some of the key parts of this approach. The full code for this
example can be found in the <a href="https://github.com/marcisme/InfinityAndBeyond/blob/master/InfinityAndBeyond/Examples/CountPlusOneViewController.swift">Infinity and
Beyond</a>
project.</p>

<p>As the name &ldquo;Count + 1&rdquo; implies, you&rsquo;ll need to pad the actual current count of
models by one.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kr">override</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="kc">_</span><span class="p">:</span> <span class="n">UITableView</span><span class="p">,</span>
        <span class="n">numberOfRowsInSection</span> <span class="kc">_</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">models</span><span class="p">.</span><span class="bp">count</span> <span class="o">+</span> <span class="mi">1</span>
<span class="p">}</span></code></pre></div>
<p>You need some way to track the request state. You don&rsquo;t have to use an <code>enum</code>,
but doing so clearly defines the expected states, which will make it easier to
reason about them.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kd">enum</span> <span class="nc">State</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">loading</span>
    <span class="k">case</span> <span class="n">loaded</span>
    <span class="k">case</span> <span class="n">error</span>
<span class="p">}</span></code></pre></div>
<p>In <code>tableView:cellForRowAt:</code>, you simply return the row if you have it or
initiate a new network request. If the view controller is already in the
<code>loading</code> state, you only need to reconfigure the informational cell.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kr">override</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="kc">_</span> <span class="n">tableView</span><span class="p">:</span> <span class="n">UITableView</span><span class="p">,</span>
        <span class="n">cellForRowAt</span> <span class="n">indexPath</span><span class="p">:</span> <span class="n">IndexPath</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="n">UITableViewCell</span> <span class="p">{</span>
    <span class="kd">let</span> <span class="nv">cell</span> <span class="p">=</span> <span class="n">tableView</span><span class="p">.</span><span class="n">dequeueReusableCell</span><span class="p">(</span>
        <span class="n">withIdentifier</span><span class="p">:</span> <span class="n">CountPlusOneCell</span><span class="p">.</span><span class="n">identifier</span><span class="p">)</span> <span class="k">as</span><span class="o">!</span> <span class="n">CountPlusOneCell</span>

    <span class="k">if</span> <span class="n">indexPath</span><span class="p">.</span><span class="n">row</span> <span class="o">&lt;</span> <span class="n">models</span><span class="p">.</span><span class="bp">count</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nv">model</span> <span class="p">=</span> <span class="n">models</span><span class="p">[</span><span class="n">indexPath</span><span class="p">.</span><span class="n">row</span><span class="p">]</span>
        <span class="n">cell</span><span class="p">.</span><span class="n">configure</span><span class="p">(</span><span class="k">for</span><span class="p">:</span> <span class="p">.</span><span class="n">loaded</span><span class="p">(</span><span class="n">model</span><span class="p">))</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">cell</span><span class="p">.</span><span class="n">configure</span><span class="p">(</span><span class="k">for</span><span class="p">:</span> <span class="p">.</span><span class="n">loading</span><span class="p">)</span>
        <span class="k">switch</span> <span class="n">state</span> <span class="p">{</span>
        <span class="k">case</span> <span class="p">.</span><span class="n">loading</span><span class="p">:</span>
            <span class="k">break</span>
        <span class="k">case</span> <span class="p">.</span><span class="n">loaded</span><span class="p">,</span> <span class="p">.</span><span class="n">error</span><span class="p">:</span>
            <span class="n">fetch</span><span class="p">()</span>
        <span class="p">}</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">cell</span>
<span class="p">}</span></code></pre></div>
<p>Retry can be as simple as tapping on a cell, but you can do whatever you want
here.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kr">override</span> <span class="kd">func</span> <span class="nf">tableView</span><span class="p">(</span><span class="kc">_</span> <span class="n">tableView</span><span class="p">:</span> <span class="n">UITableView</span><span class="p">,</span>
        <span class="n">didSelectRowAt</span> <span class="n">indexPath</span><span class="p">:</span> <span class="n">IndexPath</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">tableView</span><span class="p">.</span><span class="n">deselectRow</span><span class="p">(</span><span class="n">at</span><span class="p">:</span> <span class="n">indexPath</span><span class="p">,</span> <span class="n">animated</span><span class="p">:</span> <span class="kc">true</span><span class="p">)</span>

    <span class="k">if</span> <span class="n">state</span> <span class="p">==</span> <span class="p">.</span><span class="n">error</span> <span class="p">{</span>
        <span class="n">configureLastRow</span><span class="p">(</span><span class="k">for</span><span class="p">:</span> <span class="p">.</span><span class="n">loading</span><span class="p">)</span>
        <span class="n">fetch</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></div>
<p>Your code that executes network requests needs to manage the controller state to
ensure everything else behaves correctly.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kd">private</span> <span class="kd">func</span> <span class="nf">fetch</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">state</span> <span class="p">=</span> <span class="p">.</span><span class="n">loading</span>
    <span class="kd">let</span> <span class="nv">nextRange</span> <span class="p">=</span> <span class="n">models</span><span class="p">.</span><span class="bp">count</span> <span class="p">..</span><span class="o">&lt;</span> <span class="n">models</span><span class="p">.</span><span class="bp">count</span> <span class="o">+</span> <span class="n">batchSize</span>
    <span class="n">networkClient</span><span class="p">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">offset</span><span class="p">:</span> <span class="n">nextRange</span><span class="p">.</span><span class="n">lowerBound</span><span class="p">,</span>
            <span class="n">limit</span><span class="p">:</span> <span class="n">nextRange</span><span class="p">.</span><span class="bp">count</span><span class="p">)</span> <span class="p">{</span> <span class="n">response</span> <span class="k">in</span>
        <span class="k">switch</span> <span class="n">response</span> <span class="p">{</span>
        <span class="k">case</span> <span class="kd">let</span> <span class="p">.</span><span class="n">success</span><span class="p">(</span><span class="n">newModels</span><span class="p">):</span>
            <span class="kc">self</span><span class="p">.</span><span class="bp">insert</span><span class="p">(</span><span class="n">newModels</span><span class="p">:</span> <span class="n">newModels</span><span class="p">,</span> <span class="k">for</span><span class="p">:</span> <span class="n">nextRange</span><span class="p">)</span>
            <span class="kc">self</span><span class="p">.</span><span class="n">state</span> <span class="p">=</span> <span class="p">.</span><span class="n">loaded</span>
        <span class="k">case</span> <span class="p">.</span><span class="n">failure</span><span class="p">:</span>
            <span class="kc">self</span><span class="p">.</span><span class="n">configureLastRow</span><span class="p">(</span><span class="k">for</span><span class="p">:</span> <span class="p">.</span><span class="n">error</span><span class="p">)</span>
            <span class="kc">self</span><span class="p">.</span><span class="n">state</span> <span class="p">=</span> <span class="p">.</span><span class="n">error</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></div>
<p>After you&rsquo;ve loaded the initial batch of data, inserting new rows will avoid
moving the scroll position or visual changes that can result from reloading an
already visible cell.</p>
<div class="highlight"><pre class="chroma"><code class="language-swift" data-lang="swift"><span class="kd">private</span> <span class="kd">func</span> <span class="nf">insert</span><span class="p">(</span><span class="n">newModels</span><span class="p">:</span> <span class="p">[</span><span class="n">Model</span><span class="p">],</span> <span class="k">for</span> <span class="n">range</span><span class="p">:</span> <span class="nb">Range</span><span class="p">&lt;</span><span class="nb">Int</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">models</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">contentsOf</span><span class="p">:</span> <span class="n">newModels</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">models</span><span class="p">.</span><span class="bp">count</span> <span class="o">&gt;</span> <span class="n">range</span><span class="p">.</span><span class="bp">count</span> <span class="p">{</span>
        <span class="kd">let</span> <span class="nv">insertedIndexPaths</span> <span class="p">=</span> <span class="n">range</span><span class="p">.</span><span class="bp">map</span> <span class="p">{</span>
            <span class="n">IndexPath</span><span class="p">(</span><span class="n">row</span><span class="p">:</span> <span class="nv">$0</span><span class="p">,</span> <span class="n">section</span><span class="p">:</span> <span class="mi">0</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="n">tableView</span><span class="p">.</span><span class="n">insertRows</span><span class="p">(</span><span class="n">at</span><span class="p">:</span> <span class="n">insertedIndexPaths</span><span class="p">,</span> <span class="n">with</span><span class="p">:</span> <span class="p">.</span><span class="kr">none</span><span class="p">)</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">tableView</span><span class="p">.</span><span class="n">reloadData</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span></code></pre></div>
<h2 id="pros-and-cons">Pros and Cons</h2>

<ul>
<li>Pros

<ul>
<li>Low complexity</li>
<li>No need for separate queues</li>
</ul></li>
<li>Cons

<ul>
<li>User must wait for every screenful of content</li>
<li>No scroll indicator</li>
</ul></li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>That&rsquo;s it for this example. Next up will be a refinement on this approach to
improve the user experience.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Infinity and Beyond: Introduction]]></title>
    <link href="http://marcschwieterman.com/blog/infinity-and-beyond/1/"/>
    <id>http://marcschwieterman.com/blog/infinity-and-beyond/1</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2019-01-24T13:50:00-08:00</published>
    <updated>2019-01-24T13:50:00-08:00</updated>
    <content type="html"><![CDATA[<p>I recently had to implement infinite scrolling in an iOS app. If you&rsquo;re not
familiar with infinite scrolling, it&rsquo;s an alternative to pagination, where
instead of having the user explicitly do something to advance to the next page,
new content is lazily loaded as the user nears the end of the currently visible
content. This pattern is often used on the web for social media sites, where its
main goal is to increase engagement. If you don&rsquo;t have to click on a &ldquo;next&rdquo;
button, it&rsquo;s much easier for you to keep consuming content.</p>

<p>The often slow or unreliable networks that mobile devices operate on make it
even more difficult to implement infinite scrolling well. You can&rsquo;t provide a
seamless transition to the next batch of data if the network isn&rsquo;t available
when you need it, or if it takes several seconds to retrieve the data you need.
This post will outline a variety of considerations, along with a brief overview
of two general implementation approaches.</p>

<h2 id="keeping-it-simple">Keeping It Simple</h2>

<p>If you&rsquo;re contemplating infinite scrolling, make sure that you actually need it,
and think carefully about the impacts on user experience. If the data you&rsquo;re
displaying is small enough, there may not be a significant benefit to fetching
it incrementally. If you can get everything in a single request, your code will
be simpler, and there&rsquo;s no risk of not having the data you need when the user
wants to view it. Remember also that every network request is an opportunity for
an error. If you wait to load data on-demand, the user may have lost their
network connection, and now what was intended to improve user experience has
instead harmed it. You may be able to get the best of both worlds by fetching a
small amount of data up front, then proactively fetching the rest of it in the
background, so it&rsquo;ll be there when you need it.</p>

<h2 id="things-to-consider">Things to Consider</h2>

<p>So you&rsquo;ve decided that infinite scrolling makes sense for your app. There are a
variety of things to consider related to your user experience goals, the kind of
data you&rsquo;re working with, and the API that is providing the data. In addition to
the questions below, the Nielsen Norman Group discusses some of the trade-offs
of infinite scrolling in their article, <a href="https://www.nngroup.com/articles/infinite-scrolling/">Infinite Scrolling Is Not for Every
Website</a>. While written in the context of the web, some of the
concepts are applicable to mobile apps too.</p>

<h3 id="user-experience">User Experience</h3>

<p>Is position in the data you&rsquo;ll be displaying meaningful? Depending on the
implementation that you choose, it may not be possible to show an accurate
scroll indicator. It&rsquo;s also possible that the total number of results may
change, so you&rsquo;ll have to decide if and how you want to communicate that to the
user. What are your primary goals? Are you trying to decrease latency? Are you
trying to minimize cellular data use? How common is it for users of your app to
have intermittent network connectivity? How important is this feature to your
app? The answers to questions like these will help you decide how much
complexity is justified and ultimately which implementation to use.</p>

<h3 id="api">API</h3>

<p>The API that provides your app&rsquo;s data can place strong constraints on your
implementation decisions. Do you control the API, or is it provided by a third
party? Are there rate limits to worry about? What will you show the user if you
exceed a limit? Is the result set that you&rsquo;re displaying stable, or can it
change while you&rsquo;re viewing it? Are the results explicitly ordered? Will you
hide duplicate results if you receive them? Is there any way for you to detect
missed results? Does your API use indices that you can calculate, or is it
cursor-based, which may force you to serialize your network requests and
prohibit cancellation of pending requests?</p>

<h2 id="blocking-vs-non-blocking">Blocking vs Non-Blocking</h2>

<p>In the iOS apps that I use, I&rsquo;ve seen two main infinite scrolling variants,
which I&rsquo;ll be referring to as blocking and non-blocking. I&rsquo;ll also be discussing
these approaches in the context of a <code>UITableView</code>, but everything should be
relevant to <code>UICollectionView</code> and custom UI too.</p>

<p>The blocking version of infinite scrolling allows the user to scroll all the way
to the bottom of the screen. Once at the end of the current data, a loading view
is displayed, usually as either a <code>UITableViewCell</code> or a table footer. The user
then has to wait while the next batch of data is fetched. Once the new data
arrives, it is added to the table, and the user can continue. While the need to
wait for every screenful of data can be frustrating, this approach is
considerably easier to implement than any of the alternatives.</p>

<p>The non-blocking version does not interrupt scrolling, instead it shows a
loading version of cells while their data is retrieved. Once the data arrives,
the cells that were in a loading state are updated to display the real data.
This approach has the potential to provide a better user experience. However
it&rsquo;s still highly dependent on network performance, and because the UI is never
blocked, it may be necessary to implement more complex batching or delays in the
app in order to avoid exceeding API rate limits. <a href="https://developer.apple.com/videos/play/wwdc2012/211/">Building Concurrent User
Interfaces on iOS</a> has some great information on loading table view
content asynchronously.</p>

<p>Both approaches above can be enhanced by proactively fetching more data before
it&rsquo;s needed. Common techniques involve running code in <code>scrollViewDidScroll</code> or
even <code>layoutSubviews</code> as discussed in <a href="https://developer.apple.com/videos/play/wwdc2011/104/">Advanced ScrollView Techniques</a>.
If you&rsquo;re targeting iOS 10 or newer, you can use
<code>UITableViewDataSourcePrefetching</code> or <code>UICollectionViewDataSourcePrefetching</code> as
discussed in <a href="https://developer.apple.com/videos/play/wwdc2016/219/">What&rsquo;s New in UICollectionView in iOS 10</a>.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Hopefully this post has given you some things to think about. Which of the two
approaches above make sense for your app depends a lot on the specifics of the
data you&rsquo;re displaying, as well as how much technical complexity is appropriate
for the features you&rsquo;re implementing. Upcoming posts will provide some example
implementations of infinite scrolling and discuss the trade offs involved.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Mobile CI in 2018]]></title>
    <link href="http://marcschwieterman.com/blog/mobile-ci-in-2018/"/>
    <id>http://marcschwieterman.com/blog/mobile-ci-in-2018</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2018-08-08T08:30:00-07:00</published>
    <updated>2018-08-08T08:30:00-07:00</updated>
    <content type="html"><![CDATA[<p>It&rsquo;s been a couple years since I looked at the options for Mobile Continuous
Integration (CI) for iOS apps. Last time I did this, I decided on
<a href="https://www.buddybuild.com">BuddyBuild</a>, who has since been <a href="https://www.buddybuild.com/blog/buddybuild-is-now-part-of-apple">bought by
Apple</a>.
Unfortunately BuddyBuild is no longer accepting new customers, and they
discontinued free plans and Android support in March of 2018. I hope this means
that Apple will offer their own hosted CI solution soon, and with any luck it
will go as well as the acquisition of TestFlight did. There was no news at this
year&rsquo;s WWDC, so for now we must find something else.</p>

<h2 id="candidates">Candidates</h2>

<p>While I&rsquo;ve built complicated CI setups on Jenkins in the past, I don&rsquo;t think
that&rsquo;s a good use of most people&rsquo;s time these days. I&rsquo;m also not interested in
Xcode Server because it had a lot of stability problems when my team used it.
It&rsquo;s possible that our Mac Mini just wasn&rsquo;t up to the task, but even if that was
the issue, its native feature set is pretty basic. If you do want to roll your
own Xcode Server or <a href="https://fastlane.tools">Fastlane</a> setup,
<a href="https://www.macstadium.com">MacStadium</a> seems to be a popular hosting provider.</p>

<p>The options I found are similar to two years ago. Buddybuild is gone, but Visual
Studio App Center looks interesting. The
<a href="https://greenhouseci.com">GreenhouseCI</a> domain now forwards to Nevercode, so I
assume they changed their name or there was some kind of acquisition. That
leaves us with the following candidates.</p>

<ul>
<li><a href="https://www.bitrise.io">Bitrise</a></li>
<li><a href="https://appcenter.ms/">Visual Studio App Center</a></li>
<li><a href="https://nevercode.io">Nevercode</a></li>
<li><a href="https://circleci.com/">CircleCI</a></li>
<li><a href="https://travis-ci.com/">Travis CI</a></li>
</ul>

<h2 id="features">Features</h2>

<p>The current hosted Mobile CI options come in two main flavors. There are &ldquo;full
feature&rdquo; providers that try to automatically configure everything for you, as
well as manage code signing and the various mobile-specific deatils. Then there
are services that basically give you a Mac VM and some job infrastructure. The
latter tend to be cheaper than a full time Mac hosting provider, and they also
have some nice features that are generally useful for CI builds, like custom VM
images and workflows.</p>

<p>The features I care about are as follows.</p>

<ul>
<li>VCS support: cloning repos, starting builds on push, updating build status
<sup class="footnote-ref" id="fnref:1"><a href="#fn:1">1</a></sup></li>
<li>Deployment: both ad-hoc and to AppStore Connect</li>
<li>Extensibility: some way to run code review tools like
<a href="https://danger.systems/ruby/">Danger</a>.</li>
<li>Crash reporting: web access to crash reports is nice, and most services offer
other integrations, so you can get notification in your chat software or have
tickets opened automatically for new crashes.</li>
<li>Basic analytics</li>
</ul>

<p>Based on my reading of the documentation, these are the features that are
supported.</p>

<table>
<thead>
<tr>
<th>Service</th>
<th>VCS</th>
<th>Deployment</th>
<th>Extensibility</th>
<th>Crash Reporting</th>
<th>Analytics</th>
<th>Other</th>
</tr>
</thead>

<tbody>
<tr>
<td>Bitrise</td>
<td>Bitbucket, GitHub, Gitlab</td>
<td>yes</td>
<td>Step Library</td>
<td>no</td>
<td>no</td>
<td>no</td>
</tr>

<tr>
<td>App Center</td>
<td>Bitbucket, GitHub, VSTS</td>
<td>yes</td>
<td>build lifecycle scripts</td>
<td>yes</td>
<td>yes</td>
<td>real device testing, push notifications</td>
</tr>

<tr>
<td>Nevercode</td>
<td>Bitbucket, GitHub, Gitlab</td>
<td>3rd party only</td>
<td>build lifecycle scripts / Fastlane</td>
<td>no</td>
<td>no</td>
<td>real device testing <sup class="footnote-ref" id="fnref:2"><a href="#fn:2">2</a></sup></td>
</tr>

<tr>
<td>CircleCI</td>
<td>Bitbucket, GitHub</td>
<td>Fastlane</td>
<td>full control</td>
<td>no</td>
<td>no</td>
<td></td>
</tr>

<tr>
<td>Travis CI</td>
<td>GitHub</td>
<td>Fastlane</td>
<td>full control</td>
<td>no</td>
<td>no</td>
<td></td>
</tr>
</tbody>
</table>

<h2 id="pricing">Pricing</h2>

<p>Pricing strategies vary quite a bit. They&rsquo;re usually based on some combination
of number of concurrent builds, build runtime and number of total builds for the
month. Some services offer an open source discount, which is usually free. Low
usage plans range from $40 - $100, and some providers offer a modest discount
for paying yearly instead of monthly.</p>

<p>These are the prices at the time of this writing. Most plans scale up beyond the
entry-level tier by charging for more concurrent builds, and features like real
device testing and push notifications are usually an additional charge.</p>

<table>
<thead>
<tr>
<th>Service</th>
<th>Free Tier</th>
<th>Lowest Paid Tier</th>
<th>Discounts</th>
</tr>
</thead>

<tbody>
<tr>
<td>Bitrise</td>
<td>10 minutes per build / 200 builds per month</td>
<td>$40 / 45 minutes / unlimited builds</td>
<td>Student, Contributor</td>
</tr>

<tr>
<td>App Center</td>
<td>30 minutes per build / 240 minutes per month</td>
<td>$40 / 60 minutes / unlimited</td>
<td></td>
</tr>

<tr>
<td>Nevercode</td>
<td>n/a</td>
<td>$99 / 2 apps / 2 concurrent builds / 45 minutes per build / unlimited builds per month</td>
<td>Case by case</td>
</tr>

<tr>
<td>CircleCI</td>
<td>n/a</td>
<td>$39 / 2 concurrent builds / 500 minutes per month</td>
<td>Open Source</td>
</tr>

<tr>
<td>Travis CI</td>
<td>n/a</td>
<td>$69 / unlimited</td>
<td>Open Source</td>
</tr>
</tbody>
</table>

<h2 id="conclusion">Conclusion</h2>

<p>The only candidate that provides the same level of functionality that BuddyBuild
did is Visual Studio App Center. I assume that some of their iOS functionality
came from their acquisition of <a href="https://www.hockeyapp.net">HockeyApp</a>, which
I&rsquo;ve used in the past and been happy with. Being a Microsoft offering, I think
we shouldn&rsquo;t have to worry about it going away anytime soon. All that said, only
240 build minutes per month on the free tier is low. Once you account for
dependency setup, launching the simulator for tests and possibly doing an
archive build, it&rsquo;s not hard to have an iOS build get into the 5-10 minute range
with even a minimal number of tests. While I can&rsquo;t recommend something I haven&rsquo;t
used yet, App Center would be on the top of the list if I was doing this
evaluation for a client.</p>

<p>Nevercode doesn&rsquo;t have a free tier, and their entry level is more than double
the cost of other options. They also don&rsquo;t have some features that I&rsquo;m
interested in.</p>

<p>Travis and Circle only offer a free tier for open source, and they&rsquo;re both more
work to setup and maintain than I want to deal with. Travis also doesn&rsquo;t support
Bitbucket. While I haven&rsquo;t used Circle&rsquo;s macOS platform, I have used it for Ruby
and Elixir projects both at an employer and personally. Their 2.0 platform works
well and has good documentation, so I would seriously consider it if I needed
that level of control.</p>

<p>Finally there is Bitrise. It doesn&rsquo;t have all the features I&rsquo;d like, but it has
the ones that are most important to me - VCS support, deployment and
extensibility. With 200 builds per month, the free tier should cover the needs
of small or personal projects. I also like that they give a discount for
contributing to their platform. I&rsquo;ll be trying Bitrise out, and I&rsquo;ll capture my
experience there in an upcoming post.</p>
<div class="footnotes">

<hr />

<ol>
<li id="fn:1">I use <a href="https://bitbucket.org/">Bitbucket</a> for private repos.
 <a class="footnote-return" href="#fnref:1">↩</a></li>
<li id="fn:2">via <a href="https://aws.amazon.com/device-farm/">AWS Device Farm</a>
 <a class="footnote-return" href="#fnref:2">↩</a></li>
</ol>
</div>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[MB vs MBP]]></title>
    <link href="http://marcschwieterman.com/blog/mb-vs-mbp/"/>
    <id>http://marcschwieterman.com/blog/mb-vs-mbp</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2017-07-03T12:10:18-07:00</published>
    <updated>2017-07-03T12:10:18-07:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;ve been using a second generation MacBook for a little over a year now, and in
many ways I love it. The performance is good enough most of the time, and the
portability has helped me get a lot more done because of how easy it is to carry
the MacBook and use it in a variety of places.</p>

<p>All that said, I had enough performance and stability issues that I was eager to
upgrade when the third generation model was announced at WWDC. While I have no
issues upgrading my iPhone every year, it&rsquo;s been very unusual for me to want to
upgrade a Mac that often. I decided to try the MacBook Escape<sup class="footnote-ref" id="fnref:1"><a href="#fn:1">1</a></sup> alongside the
latest MacBook because I want to be sure I&rsquo;ll still be happy with my Mac this
time next year.</p>

<p>I tested the following configurations.</p>

<table>
<thead>
<tr>
<th>MacBook (Early 2016)</th>
<th>MacBook (2017)</th>
<th>MacBook Pro (13&rdquo;, 2017, w/o TouchBar)</th>
</tr>
</thead>

<tbody>
<tr>
<td>1.3GHz Dual-Core M7</td>
<td>1.4GHz Dual-Core i7</td>
<td>2.5GHz Dual-core i7</td>
</tr>

<tr>
<td>Intel HD Graphics 515</td>
<td>Intel HD Graphics 615</td>
<td>Intel Iris Plus Graphics 640</td>
</tr>

<tr>
<td>8GB 1866MHz LPDDR3</td>
<td>16GB 1866MHz LPDDR3</td>
<td>16GB 2133MHz LPDDR3 SDRAM</td>
</tr>

<tr>
<td>512GB PCIe SSD</td>
<td>512GB PCIe SSD</td>
<td>512GB PCIe SSD</td>
</tr>
</tbody>
</table>

<h2 id="stability">Stability</h2>

<p>My chief complaint with the 2016 MB was stability. Early on with Sierra, it
would lock up and need to be rebooted about once a week. This most often
happened when connecting or disconnecting from an external monitor, but it would
just happen randomly sometimes too. Stability did improve greatly in later
versions of Sierra, but it was still one of the least reliable Macs I&rsquo;ve owned.</p>

<p>Sometimes the transition into the Spaces selection UI at the top of the screen
would get stuck, requiring either killing the <code>Dock</code> process or rebooting. I
suspect a lot of these stability issues may be related to the meager 8 GB of
memory in the 2016.</p>

<p>I didn&rsquo;t notice any of these issues with the 2017 MB, but I didn&rsquo;t use it very
heavily. The 2017 13&rdquo; MBP has been rock solid.</p>

<h2 id="performance">Performance</h2>

<p>Performance on the 2016 MacBook was often good enough, but it was noticeably
slower at any kind of long running task. Web browsing would sometimes also feel
sluggish, especially on sites with lots of images. A reboot would often improve
things.</p>

<p>The 2017 MacBook feels faster. I think the memory makes the biggest difference.
The first run of Geekbench that I did on the 2016 was almost half of the scores
below, with subsequent runs after a reboot all being around the same. I suspect
that is representative of the general performance hit I would notice if I hadn&rsquo;t
rebooted in a while.</p>

<table>
<thead>
<tr>
<th>&nbsp;</th>
<th>MacBook (Early 2016)</th>
<th>MacBook (2017)</th>
<th>MacBook Pro (13&rdquo;, 2017, w/o TouchBar)</th>
</tr>
</thead>

<tbody>
<tr>
<td>Geekbench Single / Multi</td>
<td><a href="https://browser.geekbench.com/v4/cpu/3164348">3567 / 7080</a></td>
<td><a href="https://browser.geekbench.com/v4/cpu/3164341">4152 / 8080</a></td>
<td><a href="https://browser.geekbench.com/v4/cpu/3173063">4950 / 9735</a></td>
</tr>

<tr>
<td>Unarchive Xcode 9</td>
<td>7:40</td>
<td>5:50</td>
<td>4:16</td>
</tr>

<tr>
<td>Build &amp; Test app<br/>(launching simulator)</td>
<td>1:02</td>
<td>0:59</td>
<td>0:46</td>
</tr>

<tr>
<td>Build &amp; Test app</td>
<td>0:24</td>
<td>0:24</td>
<td>0:17</td>
</tr>
</tbody>
</table>

<h2 id="size">Size</h2>

<p>While I still appreciate the lightness of the MacBook, the size of the 13&rdquo; Pro
works better for me. I&rsquo;m a pretty big guy, and the 12&rdquo; MacBook would often feel
like it was going to slip through my legs, while the 13&rdquo; Pro rests comfortably.
I also appreciate the slight increase in screen size. It&rsquo;s just enough to fit an
editor and web browser side by side when doing web development. Simply put, I
think the 13&rdquo; is small enough. Oddly I found the larger power adapter of the 13&rdquo;
to be more concerning than the larger size of the computer itself.</p>












<figure>
  
    
      <img class="lazyload" data-src="/images/posts/mb-vs-mbp/stacked-macs.jpg"  />
    
  
  
  <figcaption>
    <header><b>2017 12&#34;, 2017 13&#34;, 2015 15&#34;</b></header>
    
  </figcaption>
  
</figure>

<h2 id="final-thoughts">Final Thoughts</h2>

<p>The 2017 MacBook is a solid update. It feels faster, and I think the extra
memory would have resolved most of the performance issues I had with it. The
keyboard has a nicer feel to it, making the 2016 model feel mushy in comparison,
although the original keyboard never bothered me. For some reason the USB port
on the 2017 seemed to stick a little. I&rsquo;m not sure if that was an actual change,
or if the one I got was just on the tighter end of the acceptable range.</p>

<p>Ultimately I still felt like I&rsquo;d be tempted to upgrade again next year, so I&rsquo;m
sending the 2017 MacBook back and keeping the 13&rdquo;. I think it will be better for
the things I use it for, and the second USB port will save me from needing an
additional adapter in all but the rarest of cases. My only real regret is the
extra pound I&rsquo;ll be lugging around with me, but I think the other benefits are
worth it.</p>
<div class="footnotes">

<hr />

<ol>
<li id="fn:1"><a href="https://twitter.com/marcoarment/status/792818935695601664?lang=en">https://twitter.com/marcoarment/status/792818935695601664?lang=en</a>
 <a class="footnote-return" href="#fnref:1">↩</a></li>
</ol>
</div>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Modelines in Git Commit Messages]]></title>
    <link href="http://marcschwieterman.com/blog/modelines-in-git-commit-messages/"/>
    <id>http://marcschwieterman.com/blog/modelines-in-git-commit-messages</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2015-07-22T00:00:00+00:00</published>
    <updated>2015-07-22T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;ve been cleaning up my Vim config this week, and I noticed some strange errors
while doing an interactive rebase in my
<a href="https://github.com/marcisme/dotfiles">dotfiles</a> repository.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">Error detected <span class="k">while</span> processing modelines:
line    <span class="m">1</span>:
E518: Unknown option: &lt;some text from the first commit message&gt; </code></pre></div>
<p>Because of the way I format commit messages for my dotfiles, the first line of
the file presented during an interactive rebase was being interpreted as a
<a href="http://vim.wikia.com/wiki/Modeline_magic">modeline</a>. I was hoping there was a
command line option or something that I could use to disable modelines, but as
far as I can tell, you have to do it in your <code>.vimrc</code>.</p>

<p>This isn&rsquo;t likely to be a problem for most people, as I don&rsquo;t imagine there are
many that have <code>vim:</code> at the beginning of their commit messages. However if you
run into this problem, you can solve it by adding the following to an
appropriate place in your <code>.vimrc</code></p>
<div class="highlight"><pre class="chroma"><code class="language-vim" data-lang="vim"><span class="nx">autocmd</span> <span class="nx">FileType</span> <span class="nx">gitrebase</span> <span class="nx">setlocal</span> <span class="nx">nomodeline</span></code></pre></div>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Return of the Daemon]]></title>
    <link href="http://marcschwieterman.com/blog/return-of-the-daemon/"/>
    <id>http://marcschwieterman.com/blog/return-of-the-daemon</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2015-07-08T00:00:00+00:00</published>
    <updated>2015-07-08T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;ve been enjoying having the new <a href="http://www.apple.com/music/">Apple Music</a>
service in iTunes quite a bit, but one thing has been driving me crazy: the
keyboard controls don&rsquo;t work anymore. Except they do.</p>

<p>Before 12.2, iTunes would infuriatingly launch every time you plugged a set of
headphones into your laptop. I eventually found a
<a href="http://apple.stackexchange.com/questions/86315/prevent-itunes-from-opening-when-connecting-bluetooth-headset">post</a>
that identified the Remote Control Daemon as the culprit for this behavior.
Simply unloading the daemon fixed the problem. No more iTunes launching when it
wasn&rsquo;t wanted, and the keyboard controls still worked. Until now that is.</p>

<p>Fortunately starting the service back up is as easy as:</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">launchctl load /System/Library/LaunchAgents/com.apple.rcd.plist</code></pre></div>
<p>Note that if you disabled the service to make double-sure it&rsquo;d never run again,
you may have to re-enable it by editing the following line in the plist.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34;?&gt;</span>
<span class="cp">&lt;!DOCTYPE plist PUBLIC &#34;-//Apple//DTD PLIST 1.0//EN&#34; &#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&#34;&gt;</span>
<span class="nt">&lt;plist</span> <span class="na">version=</span><span class="s">&#34;1.0&#34;</span><span class="nt">&gt;</span>
<span class="nt">&lt;dict&gt;</span>
    <span class="nt">&lt;key&gt;</span>Disabled<span class="nt">&lt;/key&gt;</span>
    <span class="nt">&lt;false/&gt;</span> <span class="c">&lt;!-- double negate here! --&gt;</span>
    ...
<span class="nt">&lt;/dict&gt;</span>
<span class="nt">&lt;/plist&gt;</span></code></pre></div>
<p>So far my keyboard controls are working again, and iTunes has yet to launch when
plugging in headphones. Let&rsquo;s hope it stays that way.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[The Initiative]]></title>
    <link href="http://marcschwieterman.com/blog/the-initiative/"/>
    <id>http://marcschwieterman.com/blog/the-initiative</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2015-05-15T00:00:00+00:00</published>
    <updated>2015-05-15T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>My friend Bill and I have been working on a podcast about learning iOS
development, and it&rsquo;s finally here. We recorded several episodes before we
figured out enough of the recording and hosting process to release anything, so
there&rsquo;s already a decent backlog. New episodes should continue to come out every
Friday.</p>

<p>Check it out at <a href="http://initiative.fm">The Initiative</a>.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Bypass VPN by Hostname]]></title>
    <link href="http://marcschwieterman.com/blog/bypass-vpn-by-hostname/"/>
    <id>http://marcschwieterman.com/blog/bypass-vpn-by-hostname</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2014-01-20T00:00:00+00:00</published>
    <updated>2014-01-20T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>If you run VPN on your router, you may have had cases where you want Internet
traffic to bypass the VPN. Most solutions I&rsquo;ve found use some form of a
<a href="http://pastebin.com/download.php?i=sxzipj0v">script</a> originally found on
<a href="http://www.linksysinfo.org/index.php?threads/any-way-to-bypass-vpn-selectively.33468/">LinksysInfo</a>.
However these approaches are IP based, which can be a problem if those IPs
change, or if the service you&rsquo;re accessing uses a
<a href="http://en.wikipedia.org/wiki/Content_delivery_network">CDN</a>. If your router is
running firmware that supports
<a href="http://ipset.netfilter.org/ipset.man.html">ipset</a>, you can use
<a href="http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html">dnsmasq</a> and
<a href="http://ipset.netfilter.org/iptables-extensions.man.html">iptables</a> to solve
this problem.</p>

<p>This example uses release 112 of <a href="http://tomato.groov.pl/">Tomato by Shibby</a>.
Some versions of utilities are not the latest available, so syntax may be
slightly different than readily available man pages. The code snippets below
include a commented reference to where they go in the admin GUI, but this is
just what worked for me.</p>

<p>The core of the solution is to create an ipset for hosts of interest, configure
Dnsmasq to populate that ipset and then use iptables rules to route outgoing
traffic to those IPs over the WAN instead of over the VPN.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># Administration &gt; Scripts &gt; Init</span>

ipset --create bypass_vpn iphash
modprobe ipt_set</code></pre></div>
<p>The first thing you need to do is create an ipset and load the <code>ipt_set</code> kernel
module. Here we&rsquo;ve created an ipset named <code>bypass_vpn</code> of type <code>iphash</code>. Note
that newer versions of ipset use a different syntax, <code>hash:ip</code>, for the set
type. If you later get errors from iptables when trying to create rules with the
ipset, you probably forgot to load the kernel module.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># Advanced &gt; DHCP/DNS &gt; Dnsmasq Custom configuration</span>

<span class="nv">server</span><span class="o">=</span>/example.com/192.168.1.1
<span class="nv">ipset</span><span class="o">=</span>/example.com/bypass_vpn

<span class="c1">#log-queries</span></code></pre></div>
<p>Next you need to tell Dnsmasq to route DNS requests to a DNS server that is
going to give you location appropriate results. This is particularly important
if you&rsquo;re trying to get traffic to use a local CDN. In the above example,
<code>example.com</code> is our host of interest, <code>192.168.1.1</code> is the IP of a DNS server
that will resolve that host to a desirable IP and <code>bypass_vpn</code> is the ipset to
store the results in for later use by iptables. You will need a server/ipset
pair for every hostname you wish to bypass the VPN.</p>

<p>When you&rsquo;re first setting things up, you&rsquo;ll probably want to also add
<code>log-queries</code> to the Dnsmasq config, which will log DNS requests to the system
log at <em>/var/log/messages</em>. In addition to hostnames you&rsquo;re already aware of, be
on the lookout for hosts referred to by
<a href="http://en.wikipedia.org/wiki/CNAME_record">CNAME</a> records.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># Administration &gt; Scripts &gt; WAN Up</span>

<span class="c1"># The commands needed to create the routing table for packets marked with a</span>
<span class="c1"># 1 are not shown here. See the aforementioned LinksysInfo thread for more</span>
<span class="c1"># information.</span>

<span class="c1"># MARK = 0; all traffic goes through VPN by default</span>
iptables -t mangle -A PREROUTING -i br0 -j MARK --set-mark <span class="m">0</span>

<span class="c1"># MARK = 1; bypass VPN for bypass_vpn ipset</span>
iptables -t mangle -A PREROUTING -i br0 -m <span class="nb">set</span> --set bypass_vpn dst -j MARK --set-mark <span class="m">1</span></code></pre></div>
<p>Finally you need to create rules to mark packets matching the ipset. In the
above example, <code>br0</code> is the interface the packets are entering through,
<code>bypass_vpn</code> is the ipset containing the IPs to match and <code>1</code> is the mark value
corresponding to a routing table that bypasses the VPN. This is not a complete
iptables configuration. Only the packet marking rules are shown. Note that the
<code>--match-set</code> option mentioned in the iptables man page did not work for me.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Testing in the OSX Sandbox]]></title>
    <link href="http://marcschwieterman.com/blog/testing-in-the-sandbox/"/>
    <id>http://marcschwieterman.com/blog/testing-in-the-sandbox</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2012-11-26T00:00:00+00:00</published>
    <updated>2012-11-26T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>If you&rsquo;re running
<a href="http://developer.apple.com/library/mac/documentation/developertools/Conceptual/UnitTesting/02-Setting_Up_Unit_Tests_in_a_Project/setting_up.html#//apple_ref/doc/uid/TP40002143-CH3-SW6">Application Unit Tests</a>,
and have just enabled <a href="http://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxQuickStart/AppSandboxQuickStart.html#//apple_ref/doc/uid/TP40011183-CH2-SW6">entitlements</a>, you will immediately be greeted with an
error similar to the following.</p>

<p>2012-11-26 20:16:56.352 SandboxFail[25356:303] Error loading /Users/marc/Library/Developer/Xcode/DerivedData/SandboxFail-arfkzlcptzkjqjcqelqwsfsxhasn/Build/Products/Debug/SandboxFailTests.octest/Contents/MacOS/SandboxFailTests:  dlopen(/Users/marc/Library/Developer/Xcode/DerivedData/SandboxFail-arfkzlcptzkjqjcqelqwsfsxhasn/Build/Products/Debug/SandboxFailTests.octest/Contents/MacOS/SandboxFailTests, 262): no suitable image found.  Did find:
        /Users/marc/Library/Developer/Xcode/DerivedData/SandboxFail-arfkzlcptzkjqjcqelqwsfsxhasn/Build/Products/Debug/SandboxFailTests.octest/Contents/MacOS/SandboxFailTests: open() failed with errno=1
    IDEBundleInjection.c: Error loading bundle &lsquo;/Users/marc/Library/Developer/Xcode/DerivedData/SandboxFail-arfkzlcptzkjqjcqelqwsfsxhasn/Build/Products/Debug/SandboxFailTests.octest&rsquo;</p>

<p>It appears that test bundles cannot be injected into a signed application.
After a couple failed attempts to sign the test bundle itself, I found a
Stackoverflow
<a href="http://stackoverflow.com/questions/11035263/cocoa-app-sandbox-error-loading-bundle">post</a>
that recommended disabling code signing in a separate build configuration.  It
was not immediately obvious to me how to do that, so here&rsquo;s what worked for me.</p>

<h2 id="create-build-configuration">Create Build Configuration</h2>

<p>The first thing to do is duplicate the <em>Debug</em> configuration to make one
specifically for testing. This is done under the main project configuration, as
shown below. I named my new configuration <em>Test</em>.</p>

<p><img src="/images/posts/2012-11-26-testing-in-the-sandbox/duplicate-debug-config.png" alt="Duplicate Debug Configuration" /></p>

<h2 id="disable-code-signing">Disable Code Signing</h2>

<p>Code signing can be disabled in the build settings for the main target of the
project. Make sure to expand the disclosure triangle and only clear the
settings for the <em>Test</em> configuration. You don&rsquo;t have to select or type
anything specific in the values column. You can just click on <em>Test</em> and hit
your keyboard&rsquo;s equivalent of delete, which will restore the default values.</p>

<p><img src="/images/posts/2012-11-26-testing-in-the-sandbox/disable-signing.png" alt="Disable Code Signing" /></p>

<h2 id="configure-schemes">Configure Schemes</h2>

<p>After that you need to open the scheme editor (Command-Shift-&lt;) and select the
newly created <em>Test</em> configuration.</p>

<p><img src="/images/posts/2012-11-26-testing-in-the-sandbox/set-scheme-config.png" alt="Update Test Scheme" /></p>

<h2 id="update-dependencies-and-clean">Update Dependencies and Clean</h2>

<p>If you use <a href="http://cocoapods.org/">Cocoapods</a> to manage your dependencies,
you&rsquo;ll want to run <code>pod install</code> to link the pod lib into the new <em>Test</em>
configuration. After that just do a full clean (Command-Option-Shift-K), and
you&rsquo;re ready to run your tests. (Command-U)</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[RubyMotion Functional Tests with Storyboards]]></title>
    <link href="http://marcschwieterman.com/blog/rubymotion-functional-tests-with-storyboards/"/>
    <id>http://marcschwieterman.com/blog/rubymotion-functional-tests-with-storyboards</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2012-07-05T00:00:00+00:00</published>
    <updated>2012-07-05T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>If you&rsquo;ve been using RubyMotion, you probably noticed that some new
<a href="http://blog.rubymotion.com/post/26489000626/functional-view-and-controller-testing-with-rubymotion">testing features</a>
were released today. The video in the announcment post and the
<a href="http://www.rubymotion.com/developer-center/articles/testing">documentation</a>
are pretty good, so I&rsquo;m just going to share a few things that I had to
do to get things working.</p>

<h2 id="main-spec-rb">main_spec.rb</h2>

<p>Both the video and documentation have you add a test environment guard
clause to your <code>application:didFinishLaunchingWithOptions:</code> method in
the application delegate. Be aware that this will likely cause the
window test in the default <code>main_spec.rb</code> to fail, so either delete that
or anticipate some test failures due to the initialization changes.</p>

<h2 id="project-configuration">Project Configuration</h2>

<p><em>Update 2012/07/14: The <code>specs_dir</code> is searched recursively now, so the
workaround that was previously in this section is no longer needed.</em></p>

<h2 id="storyboards">Storyboards</h2>

<p><em>Update 2012/07/21: Storyboards are now supported by passing an <code>:id</code>
option. The
<a href="http://www.rubymotion.com/developer-center/articles/testing">documentation</a>
has not yet been updated, but the pending updates can be found on the
<a href="https://github.com/HipByte/RubyMotionDocumentation/blob/master/articles/testing/index.txt#L109">RubyMotionDocumentation</a>
github page.</em></p>

<p>If you&rsquo;re using Storyboards, you&rsquo;ll have to pass the Xcode identifier of
the controller to the <code>tests</code> method in the <code>:id</code> option.</p>
<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="c1"># list_view_controller_spec.rb</span>
<span class="n">describe</span> <span class="s1">&#39;list view&#39;</span> <span class="k">do</span>

  <span class="c1"># this call also extends the context with the test API methods</span>
  <span class="n">tests</span> <span class="no">ListViewController</span><span class="p">,</span> <span class="ss">:id</span> <span class="o">=&gt;</span> <span class="s1">&#39;list-view-controller&#39;</span>

  <span class="n">it</span> <span class="s1">&#39;should have two cells by default&#39;</span> <span class="k">do</span>
    <span class="n">views</span><span class="p">(</span><span class="no">UITableViewCell</span><span class="p">)</span><span class="o">.</span><span class="n">count</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="mi">2</span>
  <span class="k">end</span>

<span class="k">end</span></code></pre></div>
<h2 id="spurious-errors">Spurious Errors</h2>

<p>You may occasionally see errors like the following.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">...
<span class="m">3</span> specifications <span class="o">(</span><span class="m">3</span> requirements<span class="o">)</span>, <span class="m">0</span> failures, <span class="m">0</span> errors
*** simulator session ended with error: Error <span class="nv">Domain</span><span class="o">=</span>DTiPhoneSimulatorErrorDomain <span class="nv">Code</span><span class="o">=</span><span class="m">1</span> <span class="s2">&#34;The simulated application quit.&#34;</span> <span class="nv">UserInfo</span><span class="o">=</span>0x10014de60 <span class="o">{</span><span class="nv">NSLocalizedDescription</span><span class="o">=</span>The simulated application quit., <span class="nv">DTiPhoneSimulatorUnderlyingErrorCodeKey</span><span class="o">=</span>-1<span class="o">}</span>
rake aborted!
Command failed with status <span class="o">(</span><span class="m">1</span><span class="o">)</span>: <span class="o">[</span><span class="nv">DYLD_FRAMEWORK_PATH</span><span class="o">=</span><span class="s2">&#34;/Applications/Xcode.a...]
</span><span class="s2">
</span><span class="s2">Tasks: TOP =&gt; simulator
</span><span class="s2">(See full trace by running task with --trace)</span></code></pre></div>
<p>I suspect this is the 0.3 second delay condition mentioned in
<a href="https://github.com/HipByte/RubyMotion/commit/5a37c3df38b7e3a759b0897e6c1774a7ed83f488#L5R194">the comments</a>
for the functional test code. Clearly the universe is telling me to get
the new retina MBP.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[OSX Lion Key Repeat in IntelliJ]]></title>
    <link href="http://marcschwieterman.com/blog/osx-lion-key-repeat-in-intellij/"/>
    <id>http://marcschwieterman.com/blog/osx-lion-key-repeat-in-intellij</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2012-05-31T00:00:00+00:00</published>
    <updated>2012-05-31T00:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;m mildly obsessed with Vim, so of course I prefer to use similar input
methods whenever available. I&rsquo;ve been working on a Javaish project lately,
and I ran into the
<a href="http://support.apple.com/kb/HT4896">alternate character feature</a> in OSX
Lion, which does not play nice with the
<a href="https://github.com/JetBrains/ideavim">IdeaVim</a> plugin for IntelliJ.</p>

<p>After getting tired of repeating keystrokes a ridiculous number of
times, I did some searching and came across many explanations of how to
globally disable the feature. While the lack of key repeat is a problem
in IntelliJ, I could imagine alternate character input being useful in
other applications. Fortunately I found a helpful
<a href="http://www.belchak.com/2011/07/23/re-enabling-key-repeat-in-osx-lion/">blog post</a>
with a fix for specific applications in the comments.</p>

<p>Here&rsquo;s the exact terminal command for IntelliJ.</p>

<pre><code>defaults write com.jetbrains.intellij ApplePressAndHoldEnabled -bool false
</code></pre>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Testing Warden-Based Sinatra Apps]]></title>
    <link href="http://marcschwieterman.com/blog/testing-warden-based-sinatra-apps/"/>
    <id>http://marcschwieterman.com/blog/testing-warden-based-sinatra-apps</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2011-03-28T07:06:48+00:00</published>
    <updated>2011-03-28T07:06:48+00:00</updated>
    <content type="html"><![CDATA[<p>I recently integrated <a href="https://github.com/hassox/warden">Warden</a> into a
web service I&rsquo;ve been building with
<a href="http://www.sinatrarb.com/">Sinatra</a>. Unfortunately doing so completely
broke some of my tests. I spent a while trying to figure out how to stub
out the Warden object before I discovered that Warden already
<a href="https://github.com/hassox/warden/wiki/testing">provides support for testing</a>.
Awesome. While I could <a href="http://posterous.timocracy.com/testing-a-rackup-configru-file-with-racktest">load my config.ru in the test</a>,
there are other things in there that I&rsquo;d rather not deal with while
testing. I came up with the following approach, which lets me more or
less test the web service in isolation.</p>

<div class="highlight"><pre class="chroma"><code class="language-ruby" data-lang="ruby"><span class="nb">require</span> <span class="s1">&#39;rack/test&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;sinatra&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;rspec&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;warden&#39;</span>

<span class="c1"># model</span>
<span class="k">class</span> <span class="nc">User</span>
  <span class="kp">attr_reader</span> <span class="ss">:id</span>
  <span class="kp">attr_reader</span> <span class="ss">:name</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
    <span class="vi">@id</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># please don&#39;t really do this</span>
    <span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="c1"># modular sinatra app</span>
<span class="k">class</span> <span class="nc">Greeter</span> <span class="o">&lt;</span> <span class="no">Sinatra</span><span class="o">::</span><span class="no">Base</span>
  <span class="n">get</span> <span class="s1">&#39;/&#39;</span> <span class="k">do</span>
    <span class="s2">&#34;Hello, </span><span class="si">#{</span><span class="n">request</span><span class="o">.</span><span class="n">env</span><span class="o">[</span><span class="s1">&#39;warden&#39;</span><span class="o">].</span><span class="n">user</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&#34;</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="c1"># tests</span>
<span class="n">describe</span> <span class="no">Greeter</span> <span class="k">do</span>
  <span class="kp">include</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Test</span><span class="o">::</span><span class="no">Methods</span>
  <span class="kp">include</span> <span class="no">Warden</span><span class="o">::</span><span class="no">Test</span><span class="o">::</span><span class="no">Helpers</span>

  <span class="n">after</span><span class="p">(</span><span class="ss">:each</span><span class="p">)</span> <span class="k">do</span>
    <span class="no">Warden</span><span class="o">.</span><span class="n">test_reset!</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">app</span>
    <span class="no">Rack</span><span class="o">::</span><span class="no">Builder</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span>
      <span class="c1"># these serialization methods don&#39;t do anything in this example,</span>
      <span class="c1"># but they could be necessary depending on the app you&#39;re testing</span>
      <span class="no">Warden</span><span class="o">::</span><span class="no">Manager</span><span class="o">.</span><span class="n">serialize_into_session</span> <span class="p">{</span> <span class="o">|</span><span class="n">user</span><span class="o">|</span> <span class="n">user</span><span class="o">.</span><span class="n">id</span> <span class="p">}</span>
      <span class="no">Warden</span><span class="o">::</span><span class="no">Manager</span><span class="o">.</span><span class="n">serialize_from_session</span> <span class="p">{</span> <span class="o">|</span><span class="nb">id</span><span class="o">|</span> <span class="no">User</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="p">)</span> <span class="p">}</span>
      <span class="c1"># your session middleware needs to come before warden</span>
      <span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Session</span><span class="o">::</span><span class="no">Cookie</span>
      <span class="n">use</span> <span class="no">Warden</span><span class="o">::</span><span class="no">Manager</span>
      <span class="n">run</span> <span class="no">Greeter</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="n">it</span> <span class="s1">&#39;says hi to me&#39;</span> <span class="k">do</span>
    <span class="n">login_as</span> <span class="no">User</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;Marc&#39;</span><span class="p">)</span>
    <span class="n">get</span> <span class="s1">&#39;/&#39;</span>
    <span class="n">last_response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s1">&#39;Hello, Marc&#39;</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></div>
<p>This is basically just an inline rackup file. Where you would normally
return just the Sinatra app, you instead put together the bits that you
need to exercise the code under test.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Roo-based Jersey Apps on GAE]]></title>
    <link href="http://marcschwieterman.com/blog/roo-based-jersey-apps-on-gae/"/>
    <id>http://marcschwieterman.com/blog/roo-based-jersey-apps-on-gae</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2011-02-24T07:39:42+00:00</published>
    <updated>2011-02-24T07:39:42+00:00</updated>
    <content type="html"><![CDATA[<p>This past weekend I put together an example of a <a href="http://www.springsource.org/roo">Spring Roo</a>-based
<a href="http://jersey.java.net/">Jersey</a> application that can run on <a href="http://code.google.com/appengine/">Google App Engine</a>.
All code in this post is derived from the example project at
<a href="https://github.com/marcisme/jersey-on-gae-example">https://github.com/marcisme/jersey-on-gae-example</a>.
You should be able to get a project up and running by copy and pasting
the snippets in this entry, or you can clone the project and follow
along. This example uses <em>Spring Roo 1.1.1</em>, <em>Jersey 1.5</em> and <em>App
Engine SDK 1.4.0</em>. A basic understanding of the involved technologies is
assumed.</p>

<h1 id="project">Project</h1>

<p>The first step is to create your project. Create a directory for the
project, fire up the Roo shell and then enter the commands below. This
will both create a new project and configure it to use App Engine for
persistence. Make sure to substitute an actual app id for <code>your-appid</code>
if you plan to deploy this example.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">project --topLevelPackage com.example.todo
persistence setup --provider DATANUCLEUS --database GOOGLE_APP_ENGINE --applicationId your-appid</code></pre></div>
<h1 id="dependencies">Dependencies</h1>

<p>Once you&rsquo;ve set up your project for GAE, you&rsquo;ll need to add the
dependencies for Jersey and JAXB. If adding them manually, you can refer
to the <a href="http://jersey.java.net/nonav/documentation/latest/chapter_deps.html">dependencies section</a>
of the Jersey documentation. In either case, you&rsquo;ll need to add the
Jersey repository to your <code>pom.xml</code>.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;repository&gt;</span>
    <span class="nt">&lt;id&gt;</span>maven2-repository.dev.java.net<span class="nt">&lt;/id&gt;</span>
    <span class="nt">&lt;name&gt;</span>Java.net Repository for Maven<span class="nt">&lt;/name&gt;</span>
    <span class="nt">&lt;url&gt;</span>http://download.java.net/maven/2/<span class="nt">&lt;/url&gt;</span>
    <span class="nt">&lt;layout&gt;</span>default<span class="nt">&lt;/layout&gt;</span>
<span class="nt">&lt;/repository&gt;</span></code></pre></div>
<h2 id="jersey">Jersey</h2>

<p>Once you&rsquo;ve added the Jersey repository, you can use these command to
add the dependencies to your project.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">dependency add --groupId com.sun.jersey --artifactId jersey-server --version <span class="m">1</span>.5
dependency add --groupId com.sun.jersey --artifactId jersey-json --version <span class="m">1</span>.5
dependency add --groupId com.sun.jersey --artifactId jersey-client --version <span class="m">1</span>.5
dependency add --groupId com.sun.jersey.contribs --artifactId jersey-spring --version <span class="m">1</span>.5</code></pre></div>
<p>Unfortunately the <em>jersey-spring</em> artifact depends on Spring 2.5.x.
Because Roo is based on Spring 3.0.x, you need to add some exclusions to
prevent pulling in incompatible versions of Spring artifacts.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>com.sun.jersey.contribs<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>jersey-spring<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>1.5<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;exclusions&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>spring<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>spring-core<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>spring-web<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>spring-beans<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>spring-context<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
    <span class="nt">&lt;/exclusions&gt;</span>
<span class="nt">&lt;/dependency&gt;</span></code></pre></div>
<h2 id="jaxb">JAXB</h2>

<p>App Engine has
<a href="http://code.google.com/p/googleappengine/issues/detail?id=1267">issues</a>
with some versions of JAXB. I found <em>2.1.12</em> to work, while <em>2.1.13</em> and
<em>2.2.x</em> versions did not. This will hopefully change in the future. You
can add a dependency on JAXB with the following command.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">dependency add --groupId com.sun.xml.bind --artifactId jaxb-impl --version <span class="m">2</span>.1.12</code></pre></div>
<h2 id="spring">Spring</h2>

<p>If you&rsquo;re adding jersey to a project that uses Roo&rsquo;s web tier, you&rsquo;ll
already have the <em>spring-web</em> dependency in your project. If not, you&rsquo;ll
need to add that too.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">dependency add --groupId org.springframework --artifactId spring-web --version <span class="si">${</span><span class="nv">spring</span><span class="p">.version</span><span class="si">}</span></code></pre></div>
<p>You can specify an explicit version, but if you created your project
with Roo, the <code>spring.version</code> build property should be set. Either way
you&rsquo;ll want to exclude <em>commons-logging</em>.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;dependency&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>org.springframework<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>spring-web<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>${spring.version}<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;exclusions&gt;</span>
        <span class="nt">&lt;exclusion&gt;</span>
            <span class="nt">&lt;groupId&gt;</span>commons-logging<span class="nt">&lt;/groupId&gt;</span>
            <span class="nt">&lt;artifactId&gt;</span>commons-logging<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;/exclusion&gt;</span>
    <span class="nt">&lt;/exclusions&gt;</span>
<span class="nt">&lt;/dependency&gt;</span></code></pre></div>
<h2 id="maven-gae-plugin">Maven GAE Plugin</h2>

<p>For some reason Roo uses a rather old version of the Maven GAE Plugin.
The latest version at the time of this writing is <em>0.8.1</em>. In addition
to what Roo will have created for you, you&rsquo;ll want to bind the <code>start</code>
and <code>stop</code> goals if you plan on running integration tests. See the
<a href="https://github.com/marcisme/jersey-on-gae-example/blob/master/pom.xml#L602-615"><code>pom.xml</code> in the example project</a>
for an example of how to do that.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;plugin&gt;</span>
    <span class="nt">&lt;groupId&gt;</span>net.kindleit<span class="nt">&lt;/groupId&gt;</span>
    <span class="nt">&lt;artifactId&gt;</span>maven-gae-plugin<span class="nt">&lt;/artifactId&gt;</span>
    <span class="nt">&lt;version&gt;</span>0.8.1<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;configuration&gt;</span>
        <span class="nt">&lt;unpackVersion&gt;</span>${gae.version}<span class="nt">&lt;/unpackVersion&gt;</span>
    <span class="nt">&lt;/configuration&gt;</span>
    <span class="nt">&lt;executions&gt;</span>
        <span class="nt">&lt;execution&gt;</span>
            <span class="nt">&lt;phase&gt;</span>validate<span class="nt">&lt;/phase&gt;</span>
            <span class="nt">&lt;goals&gt;</span>
                <span class="nt">&lt;goal&gt;</span>unpack<span class="nt">&lt;/goal&gt;</span>
            <span class="nt">&lt;/goals&gt;</span>
        <span class="nt">&lt;/execution&gt;</span>
    <span class="nt">&lt;/executions&gt;</span>
<span class="nt">&lt;/plugin&gt;</span></code></pre></div>
<h1 id="entity">Entity</h1>

<p>Next you&rsquo;ll want to create an entity, which you can do with the commands
below.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">enum <span class="nb">type</span> --class ~.Status
enum constant --name CREATED
enum constant --name DONE

entity --class ~.Todo --testAutomatically
field string --fieldName description
field enum --fieldName status --type ~.Status</code></pre></div>
<p>In order to leverage Jersey&rsquo;s JAXB serialization features, you&rsquo;ll need
to annotate your entity with <code>@XmlRootElement</code>. Set a default value for
<code>status</code> while you&rsquo;re here.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kn">import</span> <span class="nn">javax.xml.bind.annotation.XmlRootElement</span><span class="o">;</span>

<span class="nd">@RooJavaBean</span>
<span class="nd">@RooToString</span>
<span class="nd">@RooEntity</span>
<span class="nd">@XmlRootElement</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Todo</span> <span class="o">{</span>

    <span class="nd">@Enumerated</span>
    <span class="kd">private</span> <span class="n">Status</span> <span class="n">status</span> <span class="o">=</span> <span class="n">Status</span><span class="o">.</span><span class="na">CREATED</span><span class="o">;</span>

<span class="o">...</span></code></pre></div>
<h1 id="resource">Resource</h1>

<p>Here&rsquo;s a very simple resource for the entity we created earlier. In
addition to the JAX-RS annotations, you also need to annotate the class
with <code>@Service</code>, which makes the class eligible for dependency injection
and other Spring services. This resource will support both XML and JSON.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kn">package</span> <span class="nn">com.example.todo</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">org.springframework.stereotype.Service</span><span class="o">;</span>

<span class="kn">import</span> <span class="nn">javax.ws.rs.*</span><span class="o">;</span>
<span class="kn">import</span> <span class="nn">java.util.List</span><span class="o">;</span>

<span class="nd">@Service</span>
<span class="nd">@Consumes</span><span class="o">({</span><span class="s">&#34;application/xml&#34;</span><span class="o">,</span> <span class="s">&#34;application/json&#34;</span><span class="o">})</span>
<span class="nd">@Produces</span><span class="o">({</span><span class="s">&#34;application/xml&#34;</span><span class="o">,</span> <span class="s">&#34;application/json&#34;</span><span class="o">})</span>
<span class="nd">@Path</span><span class="o">(</span><span class="s">&#34;todo&#34;</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">TodoResource</span> <span class="o">{</span>

    <span class="nd">@GET</span>
    <span class="kd">public</span> <span class="n">List</span><span class="o">&lt;</span><span class="n">Todo</span><span class="o">&gt;</span> <span class="nf">list</span><span class="o">()</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">Todo</span><span class="o">.</span><span class="na">findAllTodoes</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="nd">@GET</span>
    <span class="nd">@Path</span><span class="o">(</span><span class="s">&#34;{id}&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="n">Todo</span> <span class="nf">show</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">&#34;id&#34;</span><span class="o">)</span> <span class="n">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">Todo</span><span class="o">.</span><span class="na">findTodo</span><span class="o">(</span><span class="n">id</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@POST</span>
    <span class="kd">public</span> <span class="n">Todo</span> <span class="nf">create</span><span class="o">(</span><span class="n">Todo</span> <span class="n">todo</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">todo</span><span class="o">.</span><span class="na">persist</span><span class="o">();</span>
        <span class="k">return</span> <span class="n">todo</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@PUT</span>
    <span class="kd">public</span> <span class="n">Todo</span> <span class="nf">update</span><span class="o">(</span><span class="n">Todo</span> <span class="n">todo</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">return</span> <span class="n">todo</span><span class="o">.</span><span class="na">merge</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="nd">@DELETE</span>
    <span class="nd">@Path</span><span class="o">(</span><span class="s">&#34;{id}&#34;</span><span class="o">)</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">delete</span><span class="o">(</span><span class="nd">@PathParam</span><span class="o">(</span><span class="s">&#34;id&#34;</span><span class="o">)</span> <span class="n">Long</span> <span class="n">id</span><span class="o">)</span> <span class="o">{</span>
        <span class="n">Todo</span><span class="o">.</span><span class="na">findTodo</span><span class="o">(</span><span class="n">id</span><span class="o">).</span><span class="na">remove</span><span class="o">();</span>
    <span class="o">}</span>

<span class="o">}</span></code></pre></div>
<h1 id="final-configuration">Final Configuration</h1>

<p>At a minumum, you&rsquo;ll need to have <em>Spring&rsquo;s OpenSessionInView</em> and
<em>Jersey&rsquo;s SpringServlet</em> filters set up in your <code>web.xml</code>. As with the
<em>spring-web</em> module dependency, you will have to create a <code>web.xml</code> in
<em>src/main/webapp/WEB-INF</em> if you don&rsquo;t already have one.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;web-app&gt;</span>

    <span class="c">&lt;!-- Creates the Spring Container shared by all Servlets and Filters --&gt;</span>
    <span class="nt">&lt;listener&gt;</span>
        <span class="nt">&lt;listener-class&gt;</span>org.springframework.web.context.ContextLoaderListener<span class="nt">&lt;/listener-class&gt;</span>
    <span class="nt">&lt;/listener&gt;</span>

    <span class="nt">&lt;context-param&gt;</span>
        <span class="nt">&lt;param-name&gt;</span>contextConfigLocation<span class="nt">&lt;/param-name&gt;</span>
        <span class="nt">&lt;param-value&gt;</span>classpath*:META-INF/spring/applicationContext*.xml<span class="nt">&lt;/param-value&gt;</span>
    <span class="nt">&lt;/context-param&gt;</span>

    <span class="c">&lt;!-- Ensure a Hibernate Session is available to avoid lazy init issues --&gt;</span>
    <span class="nt">&lt;filter&gt;</span>
        <span class="nt">&lt;filter-name&gt;</span>Spring OpenEntityManagerInViewFilter<span class="nt">&lt;/filter-name&gt;</span>
        <span class="nt">&lt;filter-class&gt;</span>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter<span class="nt">&lt;/filter-class&gt;</span>
    <span class="nt">&lt;/filter&gt;</span>

    <span class="nt">&lt;filter-mapping&gt;</span>
        <span class="nt">&lt;filter-name&gt;</span>Spring OpenEntityManagerInViewFilter<span class="nt">&lt;/filter-name&gt;</span>
        <span class="nt">&lt;url-pattern&gt;</span>/*<span class="nt">&lt;/url-pattern&gt;</span>
    <span class="nt">&lt;/filter-mapping&gt;</span>

    <span class="c">&lt;!-- Handles Jersey requests --&gt;</span>
    <span class="nt">&lt;servlet&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>Jersey Spring Web Application<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;servlet-class&gt;</span>com.sun.jersey.spi.spring.container.servlet.SpringServlet<span class="nt">&lt;/servlet-class&gt;</span>
    <span class="nt">&lt;/servlet&gt;</span>

    <span class="nt">&lt;servlet-mapping&gt;</span>
        <span class="nt">&lt;servlet-name&gt;</span>Jersey Spring Web Application<span class="nt">&lt;/servlet-name&gt;</span>
        <span class="nt">&lt;url-pattern&gt;</span>/*<span class="nt">&lt;/url-pattern&gt;</span>
    <span class="nt">&lt;/servlet-mapping&gt;</span>

<span class="nt">&lt;/web-app&gt;</span></code></pre></div>
<p>You may also need to change the project&rsquo;s packaging type to <em>war</em>.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;groupId&gt;</span>com.example.todo<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>todo<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;packaging&gt;</span>war<span class="nt">&lt;/packaging&gt;</span>
<span class="nt">&lt;version&gt;</span>0.1.0.BUILD-SNAPSHOT<span class="nt">&lt;/version&gt;</span></code></pre></div>
<h1 id="testing">Testing</h1>

<p>You can now compile and run the application locally with <code>mvn clean
gae:run</code>.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">&gt; mvn clean gae:run
...
INFO: The server is running at http://localhost:8080/</code></pre></div>
<p>The following curl commands can be used to interact with the running
application.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># list</span>
curl -i -HAccept:application/json http://localhost:8080/todo</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># show</span>
curl -i -HAccept:application/json http://localhost:8080/todo/1</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># create</span>
curl -i -HAccept:application/json -HContent-Type:application/json <span class="se">\
</span><span class="se"></span>  http://localhost:8080/todo -d <span class="s1">&#39;{&#34;description&#34;:&#34;walk the dog&#34;}&#39;</span></code></pre></div><div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># update</span>
curl -i -HAccept:application/json -HContent-Type:application/json <span class="se">\
</span><span class="se"></span>  http://localhost:8080/todo <span class="se">\
</span><span class="se"></span>  -d <span class="s1">&#39;{&#34;description&#34;:&#34;walk the dog&#34;,&#34;id&#34;:&#34;1&#34;,&#34;status&#34;:&#34;DONE&#34;,&#34;version&#34;:&#34;1&#34;}&#39;</span> <span class="se">\
</span><span class="se"></span>  -X PUT</code></pre></div><div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="c1"># delete</span>
curl -i http://localhost:8080/todo/1 -X DELETE</code></pre></div>
<p>Once you&rsquo;re happy with your application, you can upload it to App
Engine. If you download the <a href="https://github.com/marcisme/jersey-on-gae-example">example project</a>
I created, you can build locally with <code>mvn clean install -Dtodo-appid=&lt;your-appid&gt;</code>.
The local App Engine server will be used to run some basic integration
tests during the build. After the app is built, you can deploy it with
<code>mvn gae:deploy</code>. You will be prompted for your login information if you
have not set up your your <a href="http://www.kindleit.net/maven_gae_plugin/examples/passwordPrompt.html">credentials in your settings.xml</a>.
Once deployed, you can run the included integration test against the
live server with <code>mvn failsafe:integration-test -Dgae.host=&lt;your-appid&gt;.appspot.com -Dgae.port=80</code>.
There is also a simple client you can use to write your own tests or
experiment with.</p>

<p>Having some level of integration tests for any GAE apps you write is
very important, as there are things that do not work consistently
between the local development server and the real App Engine servers. Be
aware that you can access the local development server console at
<a href="http://localhost:8080/_ah/admin">http://localhost:8080/_ah/admin</a>,
which will let you browse the datastore amongst a few other things. Once
deployed to the real App Engine, you&rsquo;re best source of information is
the application log. Be sure you&rsquo;re looking at the correct version;
there&rsquo;s a drop-down menu in the upper left area of the screen that will
let you choose the version of the logs you want to examine.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Beware the Empty String]]></title>
    <link href="http://marcschwieterman.com/blog/beware-the-empty-string/"/>
    <id>http://marcschwieterman.com/blog/beware-the-empty-string</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2011-02-03T06:30:14+00:00</published>
    <updated>2011-02-03T06:30:14+00:00</updated>
    <content type="html"><![CDATA[<p>Regardless of <a href="http://stackoverflow.com/questions/2540981/whats-the-purpose-of-the-empty-string">how you feel</a>
about empty strings, you should be aware of the implications of allowing
them on objects that will be persisted. While it seems reasonable to
expect a database to store the exact value that you give it, that is
unfortunately not always the case. If you&rsquo;re going to allow empty
strings on persistent objects, you should take the time to determine the
behavior of the database management system you&rsquo;re using. You should also
assess how likely it is that you are going to either have to support
multiple databases, or that you will switch to another database
management system in the future.</p>

<p>Different database management systems handle empty strings
inconsistently. Some of them will persist and later return an empty
string. Others convert the empty string to a null, and some will even
turn it into a single space. If you&rsquo;re not aware of this behavior, you
may be in for some fun debugging if the object containing the empty
string is used in a set or as a map key. Values that should be unique
may appear to be duplicates or just disappear. Be particularly cautious
of fields used to determine object equality. Below is a table of a few
database management systems and the values that they will persist when
presented with an empty string.</p>

<table class="simple-table" width="400">
  <thead>
    <tr>
      <th>Database</th>
      <th>Persisted Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html">MySQL 5.0</a></td>
      <td>Empty String</td>
    </tr>
    <tr>
      <td><a href="http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/sql_elements005.htm#sthref475">Oracle 11g</a></td>
      <td>Null</td>
    </tr>
    <tr>
      <td><a href="http://infocenter.sybase.com/help/topic/com.sybase.infocenter.dc36271.1550/html/blocks/blocks311.htm">Sybase 15.5</a></td>
      <td>Single Space</td>
    </tr>
  </tbody>
</table>

<p>If you must or want to allow empty strings on persisted objects, you
need to determine how to handle them. The main decision to make is if
you will support both null and empty strings for the same value. Due to
the inconsistent handling across different database management systems,
you&rsquo;ll need to map empty strings into a value that can be persisted
reliably. If you don&rsquo;t need to support null, you can use that. Otherwise
you&rsquo;ll need to use some magic string or an extra field. The most
important thing is to be aware that this issue exists, so you don&rsquo;t
waste your precious time figuring out why your objects aren&rsquo;t given back
to you the way you left them.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Developing Spring Roo Addons]]></title>
    <link href="http://marcschwieterman.com/blog/developing-spring-roo-addons/"/>
    <id>http://marcschwieterman.com/blog/developing-spring-roo-addons</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-12-29T06:42:31+00:00</published>
    <updated>2010-12-29T06:42:31+00:00</updated>
    <content type="html"><![CDATA[<p>As of <a href="http://www.springsource.org/roo">Roo</a> 1.1.0, addons are created
with the addon command. This is slightly different than previous
versions, where addons were created with a template argument to the
project command. If you find documentation referencing this old style,
it&rsquo;s probably out of date.</p>

<p>The first thing you need to do, is checkout the Roo source code. The Git
repository is located at <code>git://git.springsource.org/roo/roo.git</code>. There
are very good instructions explaining how to build Roo in the readme.txt
file at the root of the source tree. Once Roo is built, you&rsquo;ll need to
create a new directory and fire up the Roo shell.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">mkdir roo-addon-example
<span class="nb">cd</span> roo-addon-example
roo-dev</code></pre></div>
<pre><code>    ____  ____  ____  
   / __ \/ __ \/ __ \ 
  / /_/ / / / / / / / 
 / _, _/ /_/ / /_/ /  
/_/ |_|\____/\____/    1.1.1.RELEASE [rev 3057660]

roo&gt;
</code></pre>

<p>With the shell running, you can create either a simple, advanced or i18n
addon.</p>

<pre><code>roo&gt; addon create 

addon create advanced    addon create i18n        addon create simple
</code></pre>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">addon create simple --topLevelPackage com.example.roo.addon.example</code></pre></div>
<pre><code>Created /Users/marc/src/roo-addon-example/pom.xml
Created /Users/marc/src/roo-addon-example/readme.txt
Created /Users/marc/src/roo-addon-example/legal
Created /Users/marc/src/roo-addon-example/legal/LICENSE.TXT
Created SRC_MAIN_JAVA
Created SRC_MAIN_RESOURCES
Created SRC_TEST_JAVA
Created SRC_TEST_RESOURCES
Created SRC_MAIN_WEBAPP
Created SRC_MAIN_RESOURCES/META-INF/spring
Created SRC_MAIN_JAVA/com/example/roo/addon/example
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleCommands.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleOperations.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExampleOperationsImpl.java
Created SRC_MAIN_JAVA/com/example/roo/addon/example/ExamplePropertyName.java
Created ROOT/src/main/assembly
Created ROOT/src/main/assembly/assembly.xml
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example/info.tagx
Created SRC_MAIN_RESOURCES/com/example/roo/addon/example/show.tagx
</code></pre>

<p>After the addon is created, exit the roo shell, then build and install
the addon. You can package the addon from within Roo with <code>perform
package</code>, but you&rsquo;ll see why we installed it shortly.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">quit
mvn clean install</code></pre></div>
<p>Having installed the addon, you&rsquo;re almost ready to use it. There are a
few ways to load your addon into the Roo runtime. The one I like the
best is to set up your local maven repository as an OSGI Bundle
Repository (OBR). The project created with the <code>addon create</code> command is
configured to use the <a href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html">Maven Bundle Plugin</a>,
which will create a <code>repository.xml</code> file in your local Maven
repository. To tell Roo to use your local Maven repository as an OBR,
simply add a line to the <code>config.properties</code> file as shown below, where
<code>ROO_HOME</code> is the Roo source directory.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="c1">// $ROO_HOME/bootstrap/src/main/conf/config.properties
</span><span class="c1"></span><span class="n">obr</span><span class="o">.</span><span class="na">repository</span><span class="o">.</span><span class="na">url</span><span class="o">=</span><span class="nl">file:</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">whoever</span><span class="o">/.</span><span class="na">m2</span><span class="o">/</span><span class="n">repository</span><span class="o">/</span><span class="n">repository</span><span class="o">.</span><span class="na">xml</span></code></pre></div>
<p>If you&rsquo;ve recently built Roo from source, you may want to null out the
<code>repository.xml</code> file before building your addon, as it will be full of
the core Roo addons. Keep in mind that you can use
<a href="http://www.kernel.org/pub/software/scm/git/docs/git-stash.html">git stash</a>
to clean your working directory if you want to pull down the latest
development changes later on. Now that Roo knows where to look for your
addon, you can start the shell back up.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">roo-dev</code></pre></div>
<p>If you set everything up right, your local Maven repository should now
show up as an OBR, and the addon you just installed should be available
within it.</p>

<pre><code>roo&gt; osgi obr url list
file:/home/whoever/.m2/repository/repository.xml

roo&gt; osgi obr list
com-example-roo-addon-example [com.example.roo.addon.example] (0.1.0.BUILD-SNAPSHOT)
</code></pre>

<p>The main advantage of this approach is that you don&rsquo;t have to type the
path to addons when starting them. Roo will tab-complete the addon
bundle name, so you should only have to type enough to make it unique.</p>

<pre><code>roo&gt; osgi obr start --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent INSTALLED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent RESOLVED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent STARTED
roo&gt; Target resource(s):
-------------------
   com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

Deploying...done.

[Thread-2] [com.example.roo.addon.example [73]] ServiceEvent REGISTERED
</code></pre>

<p>Your addon should now show up in the output of <code>osgi ps</code>.</p>

<pre><code>roo&gt; osgi ps
...
[  75] [Active     ] [    1] com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

roo&gt; say hello --name marc
Welcome marc!
Country of origin: None of your business!
It seems you are a running JDK 1.6.0_22
You can use the default JDK logger anywhere in your add-on to send messages to the Roo shell
</code></pre>

<p>You can make changes to your addon and reload it without restarting the
Roo shell. To change the command output for the example addon, you can
modify the <code>ExampleCommands.java</code> file, change the <code>sayHello</code> method,
then reinstall the addon.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">mvn clean install</code></pre></div>
<pre><code>roo&gt; osgi uninstall --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [73]] ServiceEvent UNREGISTERING
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent STOPPED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent UNRESOLVED
[Thread-2] [com.example.roo.addon.example [73]] BundleEvent UNINSTALLED
[Thread-2] [org.apache.felix.framework [0]] FrameworkEvent PACKAGES REFRESHED

roo&gt; osgi obr start --bundleSymbolicName com.example.roo.addon.example
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent INSTALLED
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent RESOLVED
Target resource(s):
-------------------
   com-example-roo-addon-example (0.1.0.BUILD-SNAPSHOT)

Deploying...done.

[Thread-2] [com.example.roo.addon.example [74]] ServiceEvent REGISTERED
[Thread-2] [com.example.roo.addon.example [74]] BundleEvent STARTED
[Thread-2] [com.example.roo.addon.example [74]] ServiceEvent REGISTERED

roo&gt; say hello --name marc                                            
This is my new message
</code></pre>

<p>One downside to the OBR approach, is that you can&rsquo;t just use the <code>osgi
update</code> command to reload your addon. I think this is a bug, as it works
fine if you load the addon from an explicit file system path via <code>osgi
start --url</code>. Until that gets fixed, you need to uninstall and start the
addon to reload it as was shown above.</p>

<p>If you need to debug Roo or your own addon, you can uncomment the DEBUG
line towards the end of the roo-dev script. Roo will suspend on startup
until you connect to it as a remote application with your IDE of choice.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="nv">DEBUG</span><span class="o">=</span><span class="s2">&#34;-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y&#34;</span></code></pre></div>
<p>That&rsquo;s all you need to know to get started. The
<a href="http://forum.springsource.org/forumdisplay.php?f=67">Spring Roo Forum</a>
is a good place to go if you need additional information.
<a href="http://forum.springsource.org/showpost.php?p=328167&amp;postcount=15">This post</a>
in particular has some useful direction. You can also build the project
documentation locally with <code>mvn site</code>, but be prepared to wait a while.
The documentation will be at <code>$ROO_HOME/target/site/reference/html/index.html</code>.
It&rsquo;s still in progress, but the content that&rsquo;s there is good.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Static Content Alongside Jersey Services]]></title>
    <link href="http://marcschwieterman.com/blog/static-content-alongside-jersey-services/"/>
    <id>http://marcschwieterman.com/blog/static-content-alongside-jersey-services</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-10-28T06:00:00+00:00</published>
    <updated>2010-10-28T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>If you&rsquo;ve worked with <a href="https://jersey.dev.java.net/">Jersey</a>, you&rsquo;re
likely familiar with the embedded
<a href="https://grizzly.dev.java.net/">Grizzly</a> server. Though I haven&rsquo;t seen
it mentioned often, Grizzly can indeed serve static content too. The
following snippet is all that&rsquo;s necessary to fire up an embedded web
server. These examples were written with <em>Grizzly 1.9.18-m</em> and <em>Jersey 1.4</em>.</p>

<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="n">GrizzlyWebServer</span> <span class="n">server</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GrizzlyWebServer</span><span class="o">(</span><span class="n">8080</span><span class="o">,</span> <span class="s">&#34;/var/www&#34;</span><span class="o">);</span>

<span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="o">...</span></code></pre></div>
<p>While I&rsquo;ve found some
<a href="http://blogs.sun.com/japod/entry/jersey_aplication_sharing_grizzly_with">evidence</a>
that you should be able to just add a Jersey <code>ServletAdapter</code> to the
Grizzly server, that doesn&rsquo;t appear to work with current versions.
Fortunately there are still a couple options that do work. If you want
to serve both your static pages and Jersey services from the same
context path, you can do something like the following. The key
differences from a regular Jersey adapter are to specify the location to
the static content in the <code>ServletAdapter</code> constructor, and you need to
<code>setHandleStaticResources</code> to true.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="n">GrizzlyWebServer</span> <span class="n">server</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GrizzlyWebServer</span><span class="o">(</span><span class="n">8080</span><span class="o">);</span>

<span class="n">ServletAdapter</span> <span class="n">jerseyAdapter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ServletAdapter</span><span class="o">(</span><span class="s">&#34;/var/www&#34;</span><span class="o">);</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">addInitParameter</span><span class="o">(</span><span class="s">&#34;com.sun.jersey.config.property.packages&#34;</span><span class="o">,</span>
                  <span class="s">&#34;com.yourdomain&#34;</span><span class="o">);</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">setContextPath</span><span class="o">(</span><span class="s">&#34;/&#34;</span><span class="o">);</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">setServletInstance</span><span class="o">(</span><span class="k">new</span> <span class="n">ServletContainer</span><span class="o">());</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">setHandleStaticResources</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>

<span class="n">server</span><span class="o">.</span><span class="na">addGrizzlyAdapter</span><span class="o">(</span><span class="n">jerseyAdapter</span><span class="o">,</span> <span class="k">new</span> <span class="n">String</span><span class="o">[]{</span><span class="s">&#34;/&#34;</span><span class="o">});</span>

<span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="o">...</span></code></pre></div>
<p>If you want to have different context paths for your static content and
services, you can create two adapters like below.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="n">GrizzlyWebServer</span> <span class="n">server</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GrizzlyWebServer</span><span class="o">(</span><span class="n">8080</span><span class="o">);</span>

<span class="n">ServletAdapter</span> <span class="n">staticContentAdapter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ServletAdapter</span><span class="o">(</span><span class="s">&#34;/var/www&#34;</span><span class="o">);</span>
<span class="n">staticContentAdapter</span><span class="o">.</span><span class="na">setContextPath</span><span class="o">(</span><span class="s">&#34;/&#34;</span><span class="o">);</span>
<span class="n">staticContentAdapter</span><span class="o">.</span><span class="na">setHandleStaticResources</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span>

<span class="n">ServletAdapter</span> <span class="n">jerseyAdapter</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ServletAdapter</span><span class="o">();</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">addInitParameter</span><span class="o">(</span><span class="s">&#34;com.sun.jersey.config.property.packages&#34;</span><span class="o">,</span>
                  <span class="s">&#34;com.yourdomain&#34;</span><span class="o">);</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">setContextPath</span><span class="o">(</span><span class="s">&#34;/ws&#34;</span><span class="o">);</span>
<span class="n">jerseyAdapter</span><span class="o">.</span><span class="na">setServletInstance</span><span class="o">(</span><span class="k">new</span> <span class="n">ServletContainer</span><span class="o">());</span>

<span class="n">server</span><span class="o">.</span><span class="na">addGrizzlyAdapter</span><span class="o">(</span><span class="n">staticContentAdapter</span><span class="o">,</span> <span class="k">new</span> <span class="n">String</span><span class="o">[]{</span><span class="s">&#34;/&#34;</span><span class="o">});</span>
<span class="n">server</span><span class="o">.</span><span class="na">addGrizzlyAdapter</span><span class="o">(</span><span class="n">jerseyAdapter</span><span class="o">,</span> <span class="k">new</span> <span class="n">String</span><span class="o">[]{</span><span class="s">&#34;/ws&#34;</span><span class="o">});</span>

<span class="n">server</span><span class="o">.</span><span class="na">start</span><span class="o">();</span>
<span class="o">...</span></code></pre></div>
<p>One limitation to note is that this approach expects the files to be on
the file system, which may not be what you&rsquo;re looking for if you&rsquo;re
trying to create an executable jar type utility.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[GData Objective-C Client]]></title>
    <link href="http://marcschwieterman.com/blog/gdata-objective-c-client/"/>
    <id>http://marcschwieterman.com/blog/gdata-objective-c-client</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-10-21T06:00:00+00:00</published>
    <updated>2010-10-21T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;ve recently been working on an iPhone application that integrates with
Blogger, and as such I have gotten some experience with the GData
Objective-C Client Library. The issues below were all encountered while
working with the <em>GDataServiceGoogleBlogger</em> service, but they should
apply to the other GData services too.</p>

<h3 id="authorization-scope">Authorization Scope</h3>

<p>The GData APIs support <a href="http://oauth.net/core/1.0a/">OAuth</a> for
authorization. One of the first things you need to do when initializing
a GData service is to decide which authorization scope you&rsquo;re going to
use. The various service implementations have a <code>[Service
authorizationScope]</code> method that you can use, but it may not always be
the best option.</p>

<p>The default authorization scope for Blogger is
<code>https://www.blogger.com/feeds/</code>, but the Blogger API does not
consistently return links that use <em>https</em> for the scheme. You have a
few options to deal with this issue. The simplest is to just use a scope
of <code>http://www.blogger.com/feeds/</code>. Another option is to request an
authorization scope for both <em>http</em> and <em>https</em> by specifying them
together, separated by a space. The downside of this approach is that
Blogger will be listed twice when the user is redirected to Google to
authorize your application, which I think looks weird for the user.
Finally you can correct the scheme portion of URLs before submitting
requests with them, but that won&rsquo;t work for all API calls, such as for
deleting entries.</p>

<p>Also note that some links included in responses may not match the
authorization scope at all, for example the
<code>http://your-blog.blogspot.com/feeds/posts/default</code> feed URL. The <a href="http://googlecodesamples.com/oauth_playground/">OAuth Playground</a>
is an excellent tool for experimenting with the various GData APIs.</p>

<p>Update: The latest version of
<a href="http://code.google.com/p/gdata-objectivec-client/source/browse/trunk/Source/Clients/Blogger/GDataServiceGoogleBlogger.m#93">GDataServiceGoogleBlogger</a>
has been updated to make <code>http://www.blogger.com/feeds/</code> the base
service URL until the Blogger <em>https</em> issue is resolved, so things just
work now.</p>

<h3 id="retain-feeds">Retain Feeds</h3>

<p>Something which may not be immediately obvious is that you must retain a
feed if you&rsquo;re going to retain any of its entries. Failing to do so can
result in <code>EXC_BAC_ACCESS</code> errors with a stack trace similar to the
following.</p>
<div class="highlight"><pre class="chroma"><code class="language-objc" data-lang="objc"><span class="cp">#0	0x002c646c in xmlStrdup
</span><span class="cp">#1	0x0027580f in xmlCopyPropList
</span><span class="cp">#2	0x00089ec5 in -[GDataXMLNode XMLNodeCopy] at GDataXMLNode.m:879
</span><span class="cp">#3	0x00089c0c in -[GDataXMLNode copyWithZone:] at GDataXMLNode.m:843
</span><span class="cp"></span><span class="p">...</span></code></pre></div>
<p>The issue here is that a feed&rsquo;s entries refer back to the feed, but they
do not retain it. This can be particularly frustrating to debug, as none
of the usual NSZombie tricks work, presumably because the failure is
occurring down in libxml2 code.</p>

<h3 id="gdatahttpfetcher-logging">GDataHTTPFetcher Logging</h3>

<p>The GData APIs have a very nice logging feature that you can enable with
the following code. You can include it pretty much anywhere in your
project.</p>
<div class="highlight"><pre class="chroma"><code class="language-objc" data-lang="objc"><span class="p">[</span><span class="n">GDataHTTPFetcher</span> <span class="nl">setIsLoggingEnabled</span><span class="p">:</span><span class="nb">YES</span><span class="p">]</span></code></pre></div>
<p>There is currently a <a href="http://developer.apple.com/library/mac/#qa/qa2006/qa1490.html">linker bug</a>
that requires you to add <code>-ObjC</code> and either the <code>-all_load</code> or <code>-force_load</code>
options to the <em>Other Linker Flags</em> section of your build target. Once
you&rsquo;ve done that, you can find the logs deep within your home directory.
Mine showed up in <code>~/Library/Application Support/iPhone Simulator/4.1/Applications/&lt;some UUID&gt;/GDataHTTPDebugLogs</code>.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Simple Backup]]></title>
    <link href="http://marcschwieterman.com/blog/simple-backup/"/>
    <id>http://marcschwieterman.com/blog/simple-backup</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-10-05T06:00:00+00:00</published>
    <updated>2010-10-05T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>I finished putting together my personal website backup script, and it
can be found on my <a href="http://github.com/marcisme/simple-backup">Github page.</a></p>

<p>Simple Backup is a bash script that will backup a single file system
    directory and a mysql database. It is intended to be used for personal
    web sites, hosting smaller amounts of data. You can run the script out
    of cron on the server that hosts your website, and it is recommended
    that you also run a sync process on your personal computer to ensure
    you have a copy of your backup files that is not on the server.</p>

<pre><code>The default options will remove backup files after they are 30 days
old. File system backups are done via tar, with a full backup once a
week and incremental backups for all other days. The database backup
dumps all tables the configured account has access to. You should set
up a read only mysql user just for backups.

This script is a result of my personal desire to back up my blog, and
it is based on my post about [backing up your personal website](http://marcschwieterman.com/blog/backing-up-your-personal-website/).
I didn't see much else out there, so hopefully this is useful for others
as well. I'm happy to fix any bugs that may be encountered, but I can't
guarantee any kind of timeline. I accept absolutely no responsibility
for the integrity of backups created with this script, and I highly
recommend doing a test recovery if you choose to use it.
</code></pre>

<p>I would be happy to hear feedback from anyone who decides to give it a
try.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Moving and Copying Lines in Xcode]]></title>
    <link href="http://marcschwieterman.com/blog/moving-and-copying-lines-in-xcode/"/>
    <id>http://marcschwieterman.com/blog/moving-and-copying-lines-in-xcode</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-09-20T06:00:00+00:00</published>
    <updated>2010-09-20T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>Being a heavy <a href="http://www.eclipse.org/">Eclipse</a> user, I&rsquo;ve grown
accustomed to its keyboard shortcuts for moving and copying lines of
text. <a href="http://developer.apple.com/technologies/tools/xcode.html">Xcode</a>
doesn&rsquo;t have a regular editing command for this, but it does offer
similar functionality via user scripts. The <em>Move Line Up</em> and <em>Move
Line Down</em> scripts are already there, just waiting for you to bind keys
to them. Go to the script menu, which is to the left of the <em>Help</em> menu,
and select the <em>Edit User Scripts&hellip;</em> menu item. Expand the disclosure
triangle next to <em>Text</em>, and you can set keyboard shortcuts by
double-clicking in the column to the right of the script names. Below is
a screenshot of what the dialog will look like if you follow all of the
instructions in this post.</p>

<p><img src="/images/posts/2010-09-20-moving-and-copying-lines-in-xcode/edit-user-scripts.png" alt="edit-user-scripts.png" /></p>

<p>As you can see, I&rsquo;ve also added <em>Copy Line Up</em> and <em>Copy Line Down</em>
scripts. Xcode doesn&rsquo;t come with scripts for these commands, but you can
pretty easily modify the existing move line scripts to create them. I&rsquo;ve
included the scripts I came up with below. These are just the Apple
provided scripts with the delete lines removed and the text selection
offsets changed to highlight the copied text.</p>
<div class="highlight"><pre class="chroma"><code class="language-applescript" data-lang="applescript"><span class="k">using terms from</span> <span class="nb">application</span> <span class="s2">&#34;Xcode&#34;</span>
  <span class="k">tell</span> <span class="nb">first</span> <span class="nb">text</span> <span class="na">document</span>
    <span class="k">set</span> <span class="p">{</span><span class="nv">startLine</span><span class="p">,</span> <span class="nv">endLine</span><span class="p">}</span> <span class="k">to</span> <span class="nv">selected</span> <span class="nb">paragraph</span> <span class="nv">range</span>
    <span class="k">if</span> <span class="nv">startLine</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">then</span>
      <span class="k">set</span> <span class="nv">theText</span> <span class="k">to</span> <span class="p">(</span><span class="nb">paragraphs</span> <span class="nv">startLine</span> <span class="nb">through</span> <span class="nv">endLine</span><span class="p">)</span>
      <span class="k">set</span> <span class="nv">theText</span> <span class="k">to</span> <span class="p">(</span><span class="nv">theText</span> <span class="k">as </span><span class="nc">string</span><span class="p">)</span>
      <span class="nb">make</span> <span class="nb">new</span> <span class="nb">paragraph</span> <span class="nb">at</span> <span class="nv">beginning</span> <span class="k">of</span> <span class="nb">paragraph</span> <span class="p">(</span><span class="nv">startLine</span><span class="p">)</span>
        <span class="nv">with</span> <span class="nb">data</span> <span class="nv">theText</span>
      <span class="k">set</span> <span class="nv">selected</span> <span class="nb">paragraph</span> <span class="nv">range</span> <span class="k">to</span> <span class="p">{</span><span class="nv">startLine</span><span class="p">,</span> <span class="nv">endLine</span><span class="p">}</span>
    <span class="k">else</span>
      <span class="nb">beep</span> <span class="mi">1</span>
    <span class="k">end</span> <span class="k">if</span>
  <span class="k">end</span> <span class="k">tell</span>
<span class="k">end</span> <span class="k">using terms from</span></code></pre></div><div class="highlight"><pre class="chroma"><code class="language-applescript" data-lang="applescript"><span class="k">using terms from</span> <span class="nb">application</span> <span class="s2">&#34;Xcode&#34;</span>
  <span class="k">tell</span> <span class="nb">first</span> <span class="nb">text</span> <span class="na">document</span>
    <span class="k">set</span> <span class="p">{</span><span class="nv">startLine</span><span class="p">,</span> <span class="nv">endLine</span><span class="p">}</span> <span class="k">to</span> <span class="nv">selected</span> <span class="nb">paragraph</span> <span class="nv">range</span>
    <span class="k">if</span> <span class="nv">endLine</span> <span class="o">&lt;</span> <span class="p">(</span><span class="nb">count</span> <span class="nb">paragraphs</span><span class="p">)</span> <span class="k">then</span>
      <span class="k">set</span> <span class="nv">theText</span> <span class="k">to</span> <span class="p">(</span><span class="nb">paragraphs</span> <span class="nv">startLine</span> <span class="nb">through</span> <span class="nv">endLine</span><span class="p">)</span>
      <span class="k">set</span> <span class="nv">theText</span> <span class="k">to</span> <span class="p">(</span><span class="nv">theText</span> <span class="k">as </span><span class="nc">string</span><span class="p">)</span>
      <span class="nb">make</span> <span class="nb">new</span> <span class="nb">paragraph</span> <span class="nb">at</span> <span class="nv">beginning</span> <span class="k">of</span> <span class="nb">paragraph</span> <span class="p">(</span><span class="nv">endLine</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
        <span class="nv">with</span> <span class="nb">data</span> <span class="nv">theText</span>
      <span class="k">set</span> <span class="nv">theSize</span> <span class="k">to</span> <span class="p">(</span><span class="nv">endLine</span> <span class="o">-</span> <span class="nv">startLine</span><span class="p">)</span>
      <span class="k">set</span> <span class="nv">selected</span> <span class="nb">paragraph</span> <span class="nv">range</span>
        <span class="k">to</span> <span class="p">{</span><span class="nv">endLine</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nv">endLine</span> <span class="o">+</span> <span class="nv">theSize</span> <span class="o">+</span> <span class="mi">1</span><span class="p">}</span>
    <span class="k">else</span>
      <span class="nb">beep</span> <span class="mi">1</span>
    <span class="k">end</span> <span class="k">if</span>
  <span class="k">end</span> <span class="k">tell</span>
<span class="k">end</span> <span class="k">using terms from</span></code></pre></div>
<p>You&rsquo;ll need to save these scripts somewhere in your home directory. I
put them in <code>~/Library/Application Support/Developer/Shared/Xcode</code>, as
that&rsquo;s were other Xcode customization files go. You can then add the
scripts by clicking on the plus in the bottom left corner of the <em>Edit
User Scripts</em> window and selecting the <em>Add Script File&hellip;</em> menu item.
You should also change the four drop down options on the right to be the
same as the original move line scripts. Once you&rsquo;ve added the scripts,
you can bind keys to them like any of the other scripts.</p>

<p>If you&rsquo;re going to make further modifications, you need to be sure you
understand the difference between the &ldquo;shell scripts&rdquo; and &ldquo;script
files&rdquo;. Shell scripts will have their contents displayed in the text
view on the right side of the <em>Edit User Scripts</em> window. You can safely
use the <em>Duplicate Script</em> option on them, because you have your own
copy of the content in the <em>XCUserScripts.plist</em> file located in the
previously mentioned directory. Script files on the other hand are
stored in the main Xcode directory, so you need to manually copy and add
them before making any modifications, just like I did for this example.</p>

<p>Finally I&rsquo;ve noticed that the user scripts don&rsquo;t block further input
while they execute. If you&rsquo;re trying to move multiple lines of text
around, you can actually hit keys faster than the scripts finish
executing, which may result in the group of lines being de-selected and
getting jumbled up. Because of this, the user scripts are best suited
for single lines or short range copies.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Reading Two-Up PDFs]]></title>
    <link href="http://marcschwieterman.com/blog/reading-two-up-pdfs/"/>
    <id>http://marcschwieterman.com/blog/reading-two-up-pdfs</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-09-08T06:00:00+00:00</published>
    <updated>2010-09-08T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>Some Two-Up PDFs, such as the new <a href="http://www.pragprog.com/pragmatic-guide-series">Pragmatic Guide Series</a>,
are intended to be read with specific pages on the left or right side of
the screen.  Unfortunately these types of documents don&rsquo;t always display
the way the author intended in every PDF reader. However most PDF
readers do provide features to get the desired presentation.</p>

<p><strong>Preview</strong></p>

<p>If you have a mac, you&rsquo;re familiar with the
<a href="http://support.apple.com/kb/ht2506">Preview</a> application. I prefer
Preview to other options because of the way it maximizes to the full
size of the document you&rsquo;re reading, as opposed to maximizing to take up
the whole screen. It doesn&rsquo;t offer any features that let you directly
control the page presentation of two-up PDFs, but you can insert blank
pages into the document to force the correct display.</p>

<p><img src="/images/posts/2010-09-08-reading-two-up-pdfs/preview-edit-insert-blank-page.png" alt="Preview - Insert Blank Page" /></p>

<p>While this approach seems a bit brute, it does get the job done. It also
has the advantage that you only have to do it once for documents that
would otherwise require you to toggle a setting on subsequent reads. You
can undo (⌘Z) the insert operation if you don&rsquo;t get the placement right
the first time.</p>

<p><strong>Adobe Reader</strong></p>

<p>Everyone who&rsquo;s used a computer has come across <a href="http://get.adobe.com/reader/">Adobe Reader</a>.
Reader offers a_ Show Cover Page During Two-Up_ option that you can
toggle on or off to get the desired results. While this saves you from
having to modify the document you&rsquo;re reading, you have to keep toggling
the setting if you move back and forth within the document.</p>

<p><img src="/images/posts/2010-09-08-reading-two-up-pdfs/acrobat-view-page-display-show-cover-page.png" alt="Adobe Reader - Show Cover Page During Two-Up" /></p>

<p><strong>GoodReader</strong></p>

<p>I wrote about <a href="http://www.goodiware.com/goodreader.html">GoodReader</a> in
my <a href="http://marcschwieterman.com/blog/getting-files-onto-the-ipad/">Getting Files onto the iPad</a>
post. As further support of GoodReader&rsquo;s goodness, it dedicates an
entire menu to two-up PDF presentation. Simply select the appropriate
option from the <em>Pages Layout</em> menu. The menu icon will be the icon for
the current presentation mode, so be prepared to look for a different
icon if you need to change the setting to something else. Both two-up
settings only work in landscape mode.</p>

<p><img src="/images/posts/2010-09-08-reading-two-up-pdfs/goodreader-pages-layout.png" alt="GoodReader - Pages Layout" /></p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Backing Up Your Personal Website]]></title>
    <link href="http://marcschwieterman.com/blog/backing-up-your-personal-website/"/>
    <id>http://marcschwieterman.com/blog/backing-up-your-personal-website</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-09-03T07:02:26+00:00</published>
    <updated>2010-09-03T07:02:26+00:00</updated>
    <content type="html"><![CDATA[<p>Most website hosting companies do their own backups, but they often make
no guarantees about actually recovering your data. If you put any amount
of effort into a website, you really owe it to yourself to have a decent
backup and recovery strategy. You don&rsquo;t have to do anything too fancy or
complicated, but at a minimum you should backup your home directory with
<a href="http://www.gnu.org/software/tar/">tar</a> and any databases that your
website uses.</p>

<p><strong>Recoverability</strong></p>

<p>The first thing you need to do is decide what kind of recoverability you
need. In enterprise environments, you&rsquo;ll often hear terms like <a href="http://en.wikipedia.org/wiki/Recovery_point_objective">Recovery Point Objective</a>
and <a href="http://en.wikipedia.org/wiki/Recovery_time_objective">Recovery Time Objective</a>.
All that really means is how much data you&rsquo;re willing to lose and how
fast you need it to be recovered if something goes wrong. For a personal
website, the volume of data is likely to be small enough that recovery
time is a non-issue. I think the more relevant consideration is whether
you want to be able to do <a href="http://en.wikipedia.org/wiki/Point-in-time_recovery">point in time recovery</a>.
The main questions to ask yourself are listed below.</p>

<ul>
<li>How often are you going to backup your data?</li>
<li>Where are you going to run backups?</li>
<li>How long are you going to keep backup files?</li>
<li>How are you going to know that your backups are working?</li>
</ul>

<p><strong>Do Nothing</strong></p>

<p>While not much of a strategy, this is your default option. If you do
nothing, you&rsquo;ll have whatever level of recoverability your hosting
service provides. The pro of this strategy is that it&rsquo;s easy. You don&rsquo;t
have to do anything. The con is that you will most likely lose some
amount of your work if there is ever a failure.</p>

<p><strong>Manual Backups</strong></p>

<p>My web host provides <a href="http://www.cpanel.net/">cPanel</a>. While I think
it&rsquo;s an impressive piece of software, the backup features leave
something to be desired. There are a few options for specifying what is
backed up, after which you receive an email when the backup is
completed, and you then have a few days to download the backup file from
the server. While better than nothing, I personally don&rsquo;t have the time
or inclination to do a manual backup at some regular interval. The pro
of this strategy is that you don&rsquo;t have to write any scripts. The con is
that you have to remember to do it, and it takes up your time.</p>

<p><strong>Automated Server Side Backups</strong></p>

<p>Ideally you want your backups to run automatically on the server. This
can be as easy as setting up a <a href="http://en.wikipedia.org/wiki/Cron">cron</a>
job to execute a script once a day. One of the challenges when working
with a server that you don&rsquo;t actually own, is that you also have to find
a way to get the backup files to your personal computer or some other
reliable storage location. Having backups files sitting on the server
when its file system gets corrupted isn&rsquo;t going to do much to help you
recover your website. Tools like
<a href="http://en.wikipedia.org/wiki/File_Transfer_Protocol">FTP</a>,
<a href="http://en.wikipedia.org/wiki/Secure_copy">SCP</a> and
<a href="http://en.wikipedia.org/wiki/Rsync">rsync</a> can help you copy backup
files to your local system.</p>

<p><strong>Automated Client Side Backups</strong></p>

<p>If you can&rsquo;t run backups on the server, you can always run them on your
computer. One of the downsides with this approach is that your personal
computer may not always be on or connected to the internet, making the
possibility of a scheduled backup failing more likely. You&rsquo;ll also
probably have to pipe command output back through
<a href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a>, which not all people
are familiar with. On the plus side, you don&rsquo;t have to worry about
copying files to your computer, as they&rsquo;ll just be there once your
backup completes.</p>

<p><strong>Hybrid Backup Strategy</strong></p>

<p>Another option is to run server side backups and have a local job
automatically pull down new backup files. This option offers the
reliability of server side backups, with the risk that something could
happen to the server between the time that your backup completes and the
local process downloads the files.</p>

<p><strong>Notification</strong></p>

<p>Once you&rsquo;ve figured out how to automate your backup process, you should
also make sure that you&rsquo;re notified if something doesn&rsquo;t work. This is
the part that I think many people get wrong. You&rsquo;ll often see scripts
that attempt to build the notification in as part of the backup process.
While that seems like a good idea at first, the problem is that if
anything goes wrong with the backup script, the notification may never
get sent. Recovery time is not when you want to discover a new bug with
your backup code.</p>

<p>My preferred way to handle this is to have scripts do something to
indicate success, and then I have a separate process that checks for
success notifications and reports if any are missing. In a work
environment this could be as simple as a web page with red/green icons
for failure or success. The important thing is that you want something
you look at regularly, where the lack of a recent success message is
going to really stand out to you. On your personal computer, you could
use something like <a href="http://growl.info/extras.php">growlnotify</a> if you&rsquo;re
on a mac.</p>

<p><strong>Offsite Copy</strong></p>

<p>Depending on how paranoid you are, you may want to keep an offsite copy.
 You could burn a CD/DVD once a month and drop it off at a friend&rsquo;s
house, or maybe mail it to a PO box. There are also an ever increasing
number of &ldquo;cloud&rdquo; solutions that let you store files out on the
internet. You could use something like
<a href="https://www.dropbox.com/">Dropbox</a>, although it&rsquo;s not a pure backup
product. I&rsquo;m currently trying out <a href="http://mozy.com/">Mozy</a>, which lets
you encrypt backups with your own key. I haven&rsquo;t used it enough to
recommend it yet, but it does seem to address the confidentiality
concern that many people have about backing up their files with somebody
else.</p>

<p><strong>Do a Recovery</strong></p>

<p>Last but not least, you should really do a test recovery. The last thing
you want is to put all this thought and effort into backing up your
files, only to find out after a problem that your backups are useless.
Most likely all you need is an
<a href="http://projects.apache.org/projects/http_server.html">Apache</a> server
and a <a href="http://www.mysql.com/downloads/mysql/">MySQL</a> database, both of
which are free and extremely easy to find good documentation for.</p>

<p><strong>Conclusion</strong></p>

<p>Backing up your personal website is something you should strongly
consider. If you&rsquo;re familiar with shell scripting and standard UNIX
tools, you should be able to put something simple together in a few
hours. The basic process is to decide what your recoverability
requirements are, choose where to run your backups and create some kind
of notification mechanism. I&rsquo;ve been working on a simple backup script
for my own site, and I plan on making it publicly available in the near
future.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Eclipse Generated Equality]]></title>
    <link href="http://marcschwieterman.com/blog/eclipse-generated-equality/"/>
    <id>http://marcschwieterman.com/blog/eclipse-generated-equality</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-08-25T06:00:00+00:00</published>
    <updated>2010-08-25T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>Most users of <a href="http://www.eclipse.org/">Eclipse</a> are familiar with its
code generation features. One of the more common of these is &ldquo;Generate
hashCode() and equals()&hellip;&rdquo; from the right-click -&gt; Source (⌘-Opt-S)
menu. It roughly follows the recipe on <a href="http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf">page 33</a>
of Joshua Bloch&rsquo;s Effective Java, and it is effective in most situations.
One case where it doesn&rsquo;t work is when the class is proxied.
<a href="http://www.hibernate.org/">Hibernate</a> is just one example of a
framework that generates proxies. If the <em>Person</em> class below were
proxied, the default Eclipse implementation of <code>equals()</code> would break.
In a Hibernate application, this can lead to anything from unnecessary
deletes and inserts to some very frustrating bugs.</p>

<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Person</span> <span class="o">{</span>

  <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span>

  <span class="kd">public</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
    <span class="k">return</span> <span class="n">name</span><span class="o">;</span>
  <span class="o">}</span>
  
<span class="o">}</span></code></pre></div>
<p>The first potential problem with the default Eclipse <code>equals()</code> is
object type. Proxy classes are generally subclasses, but they will never
be the same class as the object they&rsquo;re proxying. As shown here, the
default Eclipse behavior is to check for type compatibility with
<em>getClass()</em>. If one of our <em>Person</em> objects were a proxy, its class
would <strong>not</strong> be <em>Person</em>, and this <code>equals()</code> method would return
false. Fortunately Eclipse offers the option to use <em>instanceof</em> for the
type check, so all you have to do to solve this problem is click the
&ldquo;Use &lsquo;instanceof&rsquo; to compare types&rdquo; checkbox.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">Object</span> <span class="n">obj</span><span class="o">)</span> <span class="o">{</span>
  <span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">obj</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">getClass</span><span class="o">()</span> <span class="o">!=</span> <span class="n">obj</span><span class="o">.</span><span class="na">getClass</span><span class="o">())</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="n">DefaultPerson</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">DefaultPerson</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">name</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">name</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
      <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(!</span><span class="n">name</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">name</span><span class="o">))</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span></code></pre></div>
<p>Let&rsquo;s take a minute to talk about what proxies look like internally. The
proxies generated by both <a href="http://cglib.sourceforge.net/">cglib</a> and
<a href="http://www.csg.is.titech.ac.jp/~chiba/javassist/">Javassist</a> will
contain the same fields as the target class, and an actual instance of
the target class will be held internally. Any method calls on the proxy
are then delegated to this internal instance. Below is conceptually what
a proxy looks like.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">PersonProxy</span> <span class="kd">extends</span> <span class="n">Person</span> <span class="o">{</span>

  <span class="kd">private</span> <span class="n">String</span> <span class="n">name</span><span class="o">;</span> <span class="c1">// &lt;-- always null!
</span><span class="c1"></span>  
  <span class="c1">// the real Person
</span><span class="c1"></span>  <span class="kd">private</span> <span class="n">Person</span> <span class="n">person</span><span class="o">;</span>
  
  <span class="kd">public</span> <span class="n">String</span> <span class="nf">getName</span><span class="o">()</span> <span class="o">{</span>
    <span class="c1">// do some magic to get the real Person instance
</span><span class="c1"></span>    <span class="k">return</span> <span class="n">person</span><span class="o">.</span><span class="na">getName</span><span class="o">();</span>
  <span class="o">}</span>
  
<span class="o">}</span></code></pre></div>
<p>With this in mind, the next problem is the nullness of proxy fields. As
shown above, if a <em>Person</em> proxy were passed into the <code>equals()</code> method
below, its name field would be null, and the method would return false.
The solution to this problem is to use a getter instead of field access.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">Object</span> <span class="n">obj</span><span class="o">)</span> <span class="o">{</span>
  <span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">obj</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(!(</span><span class="n">obj</span> <span class="k">instanceof</span> <span class="n">Person</span><span class="o">))</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="n">Person</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">Person</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">name</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">name</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
      <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(!</span><span class="n">name</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">name</span><span class="o">))</span>
    <span class="c1">//                        ^^^^--- This will always be null!
</span><span class="c1"></span>    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span></code></pre></div>
<p>The best way I&rsquo;ve found to convert an <code>equals()</code> method to use getters
is with the &ldquo;Encapsulate Field&hellip;&rdquo; refactoring. To do this, click on any
of the occurrences of <em>name</em>, then right-click on it (⌘-Opt-T) and
select &ldquo;Encapsulate Field&hellip;&rdquo; from the Refactoring menu. Make sure &ldquo;use
setter and getter&rdquo; is selected, and then click the &ldquo;<strong>Preview</strong>&rdquo; button.
If the class only has one field, you can then select both the
<code>hashCode()</code> and <code>equals()</code> methods from the &ldquo;Refactored Source&rdquo; pane
and copy them to the clipboard. Click the &ldquo;Cancel&rdquo; button and paste the
refactored versions over those currently in the class. If there are
multiple fields, you&rsquo;ll have to encapsulate them all, then undo all of
the changes after copying the final method implementations. This
approach is less error prone than using find and replace, and it lets
you continue to use field access in methods other than <code>hashCode()</code> and
<code>equals()</code>.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Override</span>
<span class="kd">public</span> <span class="kt">boolean</span> <span class="nf">equals</span><span class="o">(</span><span class="n">Object</span> <span class="n">obj</span><span class="o">)</span> <span class="o">{</span>
  <span class="k">if</span> <span class="o">(</span><span class="k">this</span> <span class="o">==</span> <span class="n">obj</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">obj</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(!(</span><span class="n">obj</span> <span class="k">instanceof</span> <span class="n">Person</span><span class="o">))</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="n">Person</span> <span class="n">other</span> <span class="o">=</span> <span class="o">(</span><span class="n">Person</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
  <span class="k">if</span> <span class="o">(</span><span class="n">getName</span><span class="o">()</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">getName</span><span class="o">()</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span>
      <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(!</span><span class="n">getName</span><span class="o">().</span><span class="na">equals</span><span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="na">getName</span><span class="o">()))</span>
    <span class="k">return</span> <span class="kc">false</span><span class="o">;</span>
  <span class="k">return</span> <span class="kc">true</span><span class="o">;</span>
<span class="o">}</span></code></pre></div>
<p>You should now have an <code>equals()</code> method similar to the one above.
Because this version uses getters, the calls will always be delegated to
the real <em>Person</em> object, and you shouldn&rsquo;t get any false equality
failures. You can certainly still have other issues with your <code>equals()</code>
implementation, but these two steps should address the main problems you
encounter when proxies enter the picture.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Liquibase and the modifySql Tag]]></title>
    <link href="http://marcschwieterman.com/blog/liquibase-and-the-modifysql-tag/"/>
    <id>http://marcschwieterman.com/blog/liquibase-and-the-modifysql-tag</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-08-20T06:00:00+00:00</published>
    <updated>2010-08-20T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p><a href="http://www.liquibase.org/">Liquibase</a> is a tool that helps you manage
database changes. It can can be integrated into your build process to
automatically update your database, and it also has a command line
interface that operational staff can use to generate SQL scripts for
production deployment. One of its nice features is database abstraction.
You define your changesets in XML, and Liquibase generates compatible
SQL for you. As with any tool that tries to provide this level of
abstraction over a large number of vendors, it doesn&rsquo;t work 100% with
all <a href="http://en.wikipedia.org/wiki/Database_management_system">DBMS</a>.
Below is a simple changeset.</p>

<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&#34;1.0&#34; encoding=&#34;UTF-8&#34; standalone=&#34;no&#34;?&gt;</span>
<span class="nt">&lt;databaseChangeLog</span> <span class="na">xmlns=</span><span class="s">&#34;http://www.liquibase.org/xml/ns/dbchangelog&#34;</span>
  <span class="na">xmlns:xsi=</span><span class="s">&#34;http://www.w3.org/2001/XMLSchema-instance&#34;</span>
  <span class="na">xsi:schemaLocation=</span><span class="s">&#34;http://www.liquibase.org/xml/ns/dbchangelog
</span><span class="s">  http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd&#34;</span><span class="nt">&gt;</span>

  <span class="nt">&lt;changeSet</span> <span class="na">author=</span><span class="s">&#34;marc&#34;</span> <span class="na">id=</span><span class="s">&#34;1&#34;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;createTable</span> <span class="na">tableName=</span><span class="s">&#34;test&#34;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;column</span> <span class="na">name=</span><span class="s">&#34;id&#34;</span> <span class="na">type=</span><span class="s">&#34;INT&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/createTable&gt;</span>
  <span class="nt">&lt;/changeSet&gt;</span>

  <span class="nt">&lt;changeSet</span> <span class="na">author=</span><span class="s">&#34;marc&#34;</span> <span class="na">id=</span><span class="s">&#34;2&#34;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;createIndex</span> <span class="na">indexName=</span><span class="s">&#34;idx1&#34;</span> <span class="na">tableName=</span><span class="s">&#34;test&#34;</span><span class="nt">&gt;</span>
      <span class="nt">&lt;column</span> <span class="na">name=</span><span class="s">&#34;id&#34;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;/createIndex&gt;</span>
  <span class="nt">&lt;/changeSet&gt;</span>

<span class="nt">&lt;/databaseChangeLog&gt;</span></code></pre></div>
<p>Writing these by hand isn&rsquo;t that bad, especially if you&rsquo;re using an XML
editor that does autocomplete based on the document&rsquo;s XSD, such as
<a href="http://www.eclipse.org/webtools/">Eclipse WTP</a>. Some of the database
compatibility issues you may run into include things like unsupported
constraint options, lack of support for DDL in transactions, metadata
issues, statement formatting and identifier delimitation. These are not
issues with Liquibase, just things that can be incompatible between
different DBMS.</p>

<p>If you find yourself faced with one of these incompatibilities, you have
a few options. You can <a href="http://liquibase.jira.com/secure/Dashboard.jspa">open a bug report</a>
and wait until it&rsquo;s fixed. Better yet, you can fix it yourself and
contribute back to the project. But if neither of those options will
work for you, the <a href="http://www.liquibase.org/manual/modify_sql"><em>modifySql</em></a>
tag may get the job done. This tag lets you modify the SQL that&rsquo;s
generated, so you can do anything from a simple append or character
replacement to regular expressions. The example I&rsquo;m going to cover is
how to do a regular expression replacement. Regular expressions in Java
are bad enough, but they can be a little confusing in Liquibase because
you have to format them for XML. Below is a Java example of what we&rsquo;re
trying to accomplish.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">pattern_replaces_quotes_with_square_brackets</span><span class="o">()</span> <span class="o">{</span>
  <span class="n">String</span> <span class="n">expression</span> <span class="o">=</span> <span class="s">&#34;\&#34;(\\w+)\&#34;&#34;</span><span class="o">;</span>
  <span class="n">Pattern</span> <span class="n">p</span> <span class="o">=</span> <span class="n">Pattern</span><span class="o">.</span><span class="na">compile</span><span class="o">(</span><span class="n">expression</span><span class="o">);</span>
  <span class="n">Matcher</span> <span class="n">m</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="na">matcher</span><span class="o">(</span><span class="s">&#34;create index \&#34;idx1\&#34; on \&#34;test\&#34; (\&#34;id\&#34;)&#34;</span><span class="o">);</span>
  <span class="n">assertThat</span><span class="o">(</span>
    <span class="n">m</span><span class="o">.</span><span class="na">replaceAll</span><span class="o">(</span><span class="s">&#34;[$1]&#34;</span><span class="o">),</span> <span class="n">is</span><span class="o">(</span><span class="s">&#34;create index [idx1] on [test] ([id])&#34;</span><span class="o">));</span>
  <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">expression</span><span class="o">.</span><span class="na">replaceAll</span><span class="o">(</span><span class="s">&#34;\&#34;&#34;</span><span class="o">,</span> <span class="s">&#34;&amp;quot;&#34;</span><span class="o">));</span>
<span class="o">}</span></code></pre></div>
<p>This pattern will find all instances of one or more word characters
<code>([a-zA-Z_0-9])</code> within quotes and replace those quotes with square
brackets. The $1 contains whatever the first thing in parentheses
matched, <code>\w+</code> in this case. We can&rsquo;t just do a simple character
replacement of double quotes because we have to account for left and
right brackets. Note that if you have dashes (-) in your object names,
the <code>\w</code> pattern won&rsquo;t match them. Check out the <a href="http://download-llnw.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html">Javadoc for Pattern</a>
if you need to brush up on your regular expression syntax. The <em>println</em>
at the end of the test will print out the expression formatted for
inclusion in XML, so you can just copy and paste the output into your
changelog file. If you follow these steps, you&rsquo;ll end up with a
<em>modifySql</em> tag like the one below.</p>
<div class="highlight"><pre class="chroma"><code class="language-xml" data-lang="xml"><span class="nt">&lt;changeSet</span> <span class="na">author=</span><span class="s">&#34;marc&#34;</span> <span class="na">id=</span><span class="s">&#34;2&#34;</span><span class="nt">&gt;</span>
  <span class="nt">&lt;createIndex</span> <span class="na">indexName=</span><span class="s">&#34;idx1&#34;</span> <span class="na">tableName=</span><span class="s">&#34;test&#34;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;column</span> <span class="na">name=</span><span class="s">&#34;id&#34;</span> <span class="nt">/&gt;</span>
  <span class="nt">&lt;/createIndex&gt;</span>
  <span class="nt">&lt;modifySql&gt;</span>
    <span class="nt">&lt;regExpReplace</span> <span class="na">replace=</span><span class="s">&#34;&amp;quot;(\w+)&amp;quot;&#34;</span> <span class="na">with=</span><span class="s">&#34;[$1]&#34;</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/modifySql&gt;</span>
<span class="nt">&lt;/changeSet&gt;</span></code></pre></div>
<p>I would highly recommend creating a unit test like I did to ensure that
you have the correct regular expression. You&rsquo;ll save yourself a lot of
time, as doing your verification through Liquibase would require
repeatedly executing the change, checking it, then rolling back if
necessary to try again. If you&rsquo;re not interested in adding more XML to
your build process, but you&rsquo;d like a capable tool to manage your
database changes, Liquibase is supposed to support <a href="http://blog.liquibase.org/2010/05/liquibase-formatted-sql.html">SQL changelogs</a>
in its 2.0 release.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Getting Started with Xcode]]></title>
    <link href="http://marcschwieterman.com/blog/getting-started-with-xcode/"/>
    <id>http://marcschwieterman.com/blog/getting-started-with-xcode</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-08-17T06:54:51+00:00</published>
    <updated>2010-08-17T06:54:51+00:00</updated>
    <content type="html"><![CDATA[<p>I finally spent some quality time with Xcode this past weekend. While I
haven&rsquo;t done any real work with it yet, I think it should be a
serviceable IDE. The current version of Xcode at the time of this
writing is 3.2.3, and it can be <a href="http://developer.apple.com/technologies/xcode.html">downloaded for free</a>
from Apple. You do have to register an account if you don&rsquo;t have one yet,
but you don&rsquo;t have to pay anything until you want to join the
<a href="http://developer.apple.com/programs/iphone/">iPhone Developer Program</a>.
You can&rsquo;t actually install anything on a mobile device until you subscribe,
which mainly gives you a one year certificate that you use to sign your
applications.</p>

<p><strong>Debug Messages</strong></p>

<p>The preferred way to print debug messages is with NSLog. One thing to be
aware of is that NSLog messages in Unit tests will <em>not</em> go to the
debugger console in Xcode. They will however go to the system console,
available via Applications -&gt; Utilities -&gt; Console.app. Personally I
find that Unit tests largely obviate the need for debug statements, but
they do come in handy sometimes. I also stumbled across a
<a href="http://stackoverflow.com/questions/558568/how-do-i-debug-with-nsloginside-of-the-iphone-simulator">Stackoverflow question</a>
that describes what looks like a good technique for using breakpoints to
generate debug output. Assuming those breakpoints aren&rsquo;t in test code.
More on that later.</p>

<p><strong>Target Membership</strong></p>

<p><img src="/images/posts/2010-08-17-getting-started-with-xcode/file-listing2.png" alt="File Listing" /></p>

<p>{% img left /images/posts/2010-08-17-getting-started-with-xcode/compile-sources.png Compile Sources %}</p>

<p>If you get linker errors complaining that the class you&rsquo;re trying to
test isn&rsquo;t found, you most likely just need to add that class to your
test target. Some of the information you come across may say not to do
this, but it&rsquo;s most likely referring to Application tests and not
Logic/Unit tests. The easiest way to see if a given file is part of the
current target is to look for a check mark in the far right column of
the file listing as shown above. You can also check the &ldquo;Compile
Sources&rdquo; folder under the build target itself, or you can examine the
target memberships of a specific file with Get Info -&gt; Targets -&gt; Target
Memberships.</p>

<p><strong>Testing</strong></p>

<p>Xcode comes with the <a href="http://www.sente.ch/?p=535&amp;lang=en">OCUnit</a>
testing framework, which has been around for quite a while. It provides
all the standard equality assertions and setup/teardown stuff that you
would expect from an xUnit testing framework. Here&rsquo;s a very simple
example of testing a property. I don&rsquo;t see a need to maintain separate
header files for Unit tests. The ordering for assertions is <em>actual
value</em>, <em>expected value</em>, <em>description</em>, and the description is
required.</p>
<div class="highlight"><pre class="chroma"><code class="language-objc" data-lang="objc"><span class="cp">#import &lt;SenTestingKit/SenTestingKit.h&gt;
</span><span class="cp">#import &#34;Person.h&#34;
</span><span class="cp"></span>
<span class="k">@interface</span> <span class="nc">PersonTest</span> : <span class="nc">SenTestCase</span> <span class="p">{</span>	
<span class="p">}</span>
<span class="k">@end</span>

<span class="k">@implementation</span> <span class="nc">PersonTest</span>

<span class="p">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">testName</span> <span class="p">{</span>
  <span class="n">Person</span> <span class="o">*</span><span class="n">person</span> <span class="o">=</span> <span class="p">[[</span><span class="n">Person</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
  <span class="n">person</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s">@&#34;marc&#34;</span><span class="p">;</span>
  <span class="n">STAssertEqualObjects</span><span class="p">(</span><span class="n">person</span><span class="p">.</span><span class="n">name</span><span class="p">,</span> <span class="s">@&#34;marc&#34;</span><span class="p">,</span> <span class="s">@&#34;&#34;</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">@end</span></code></pre></div>
<p><a href="http://developer.apple.com/IPhone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html">Apple&rsquo;s documentation</a>
talks about Logic tests and Application tests. One of the key
distinctions is that Logic/Unit tests directly include the code they&rsquo;re
testing, while Application tests are injected into the running
application via a special target. Any project you set up is going to
have at least four targets and two executables for various testing and
debugging use.</p>

<p><strong>Build Results</strong></p>

<p>You can bring up the Build Results window with ⌘ - Shift - B, which will
give you something like the screenshot below if you have a failing test.
With the results window set to &ldquo;By Step&rdquo;, you have to click on the
little horizontal lines button to see what tests failed, and even then
you have to visually filter though all of the test output. Fortunately
there is a better way.</p>

<p><img src="/images/posts/2010-08-17-getting-started-with-xcode/red-bar-by-step.png" alt="By Step" /></p>

<p>If you click on &ldquo;By Issue&rdquo;, you&rsquo;re presented with a much nicer view that
has a line for each failing test.</p>

<p><img src="/images/posts/2010-08-17-getting-started-with-xcode/red-bar-by-issue.png" alt="By Issue" /></p>

<p>If you click on the test failure message, it&rsquo;ll bring up the test file
and highlight the failing assertion line as shown below. You can
see that I just commented out the property setting line in my test to
get it to fail for this example. From what I&rsquo;ve read, Xcode used to
display message bubbles in the main editor, but I haven&rsquo;t been able to
figure out if that behavior is still possible.</p>

<p><img src="/images/posts/2010-08-17-getting-started-with-xcode/failed-assertion.png" alt="Failed Assertion" /></p>

<p>Uncomment the assignment statement, ﻿⌘ - B, and we&rsquo;re all green
again.</p>

<p><img src="/images/posts/2010-08-17-getting-started-with-xcode/green-bar.png" alt="Green Bar" /></p>

<p><strong>Debugging</strong></p>

<p>Debugging is an area that could use some work. Breakpoints in Unit tests
just plain don&rsquo;t work out of the box. Several kind people have written
up guides explaining how to get them to work, and I&rsquo;ve listed some of
the better ones below. The core of the solution is creating a separate
debug executable that you set some flags and environment variables on.
Unfortunately the settings are different depending on if you&rsquo;re
targeting a Mac or iPhone. The options also sometimes change, rendering
some posts you my find invalid. Note that breakpoints in
application code <em>do</em> work, it&rsquo;s just the ones in test code that require
manual configuration. I plan to explore this area more in the future,
but for now I&rsquo;m more interested in getting some applications working.</p>

<p><strong>Testing and Debugging Resources</strong></p>

<ul>
<li><a href="http://developer.apple.com/IPhone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html">http://developer.apple.com/IPhone/library/documentation/Xcode/Conceptual/iphone_development/135-Unit_Testing_Applications/unit_testing_applications.html</a></li>
<li><a href="http://cocoawithlove.com/2009/12/sample-iphone-application-with-complete.html">http://cocoawithlove.com/2009/12/sample-iphone-application-with-complete.html</a></li>
<li><a href="http://chanson.livejournal.com/119097.html">http://chanson.livejournal.com/119097.html</a></li>
<li><a href="http://code.google.com/p/google-toolbox-for-mac/wiki/iPhoneUnitTesting">http://code.google.com/p/google-toolbox-for-mac/wiki/iPhoneUnitTesting</a></li>
<li><a href="http://www.mulle-kybernetik.com/software/OCMock/">http://www.mulle-kybernetik.com/software/OCMock/</a></li>
<li><a href="http://developer.apple.com/mac/articles/tools/unittestingwithxcode3.html">http://developer.apple.com/mac/articles/tools/unittestingwithxcode3.html</a></li>
<li><a href="http://developer.apple.com/tools/unittest.html">http://developer.apple.com/tools/unittest.html</a></li>
</ul>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Maven Transitive Dependency Filtering]]></title>
    <link href="http://marcschwieterman.com/blog/gotcha-maven-transitive-dependency-filtering/"/>
    <id>http://marcschwieterman.com/blog/gotcha-maven-transitive-dependency-filtering</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-08-11T06:00:00+00:00</published>
    <updated>2010-08-11T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>The other day I wrote a post about
<a href="http://marcschwieterman.com/blog/examining-dependencies-in-maven-plugins/">examining dependencies in maven plugins</a>.
Today I was working on a similar project, and I discovered some
non-intuitive behavior with the Maven
<a href="http://maven.apache.org/ref/2.2.1/maven-artifact/apidocs/org/apache/maven/artifact/resolver/ArtifactResolver.html">ArtifactResolver</a>.
Several of the <code>resolveTransitively</code> methods accept an
<a href="http://maven.apache.org/ref/2.2.1/maven-artifact/apidocs/org/apache/maven/artifact/resolver/filter/ArtifactFilter.html">ArtifactFilter</a>,
but the filter gets applied in an odd way.</p>

<p>The bulk of the resolution process takes place in the
<a href="http://svn.apache.org/viewvc/maven/maven-2/branches/maven-2.2.x/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java?view=markup">DefaultArtifactCollector</a>
and
<a href="http://svn.apache.org/viewvc/maven/maven-2/branches/maven-2.2.x/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java?view=markup">ResolutionNode</a>
classes. The collector basically does a breadth first search of the
dependency tree, but it filters <strong>the entire path from the project to
the node</strong>, as opposed to just filtering the final results. This means
that depending on how your filter is defined, there could be
dependencies that meet its criteria, but are <strong>not included</strong> in the
ArtifactResolutionResult. Consider a project with the following
dependency tree.</p>
<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="o">[</span>INFO<span class="o">]</span> <span class="o">[</span>dependency:tree <span class="o">{</span>execution: default-cli<span class="o">}]</span>
<span class="o">[</span>INFO<span class="o">]</span> com.mydomain:module:jar:0.0.1-SNAPSHOT
<span class="o">[</span>INFO<span class="o">]</span> +- com.mydomain:dependency:jar:0.0.1-SNAPSHOT:compile
<span class="o">[</span>INFO<span class="o">]</span> <span class="p">|</span>  <span class="se">\-</span> com.mydomain:transitive-dependency:jar:0.0.1-SNAPSHOT:compile</code></pre></div>
<p>You can filter on a groupId of &ldquo;com.mydomain&rdquo;, and you&rsquo;ll get all of the
artifacts. However if you were to try to filter on an artifactId or a
type other than jar, you&rsquo;d get zero results. I&rsquo;m sure there&rsquo;s a good
reason for the filtering to work this way, but it can take you a while
to figure it out if it&rsquo;s not what you&rsquo;re expecting. If what you really
want to do is filter the final results of the transitive resolution, you
need to do that yourself.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Hibernate: Automatic Versioning]]></title>
    <link href="http://marcschwieterman.com/blog/hibernate-automatic-versioning/"/>
    <id>http://marcschwieterman.com/blog/hibernate-automatic-versioning</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-08-02T06:00:00+00:00</published>
    <updated>2010-08-02T06:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>One of the <a href="http://en.wikipedia.org/wiki/Optimistic_locking">optimistic locking</a>
features that Hibernate provides is <em>automatic versioning</em>. Versioned
objects need to contain either a
<a href="http://docs.jboss.org/hibernate/stable/core/reference/en/html/mapping.html#mapping-declaration-version">version or timestamp</a>
property that Hibernate uses to detect concurrent modifications at flush
time. Hibernate&rsquo;s versioning mechanism works by checking the number of
rows that were affected by an update statement. Consider an accounts
table like the one below.</p>

<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">describe</span> <span class="n">accounts</span><span class="p">;</span>
<span class="o">+</span><span class="c1">---------+---------+------+-----+---------+-------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">Field</span>   <span class="o">|</span> <span class="k">Type</span>    <span class="o">|</span> <span class="k">Null</span> <span class="o">|</span> <span class="k">Key</span> <span class="o">|</span> <span class="k">Default</span> <span class="o">|</span> <span class="n">Extra</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">---------+---------+------+-----+---------+-------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">id</span>      <span class="o">|</span> <span class="nb">int</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span> <span class="o">|</span> <span class="k">NO</span>   <span class="o">|</span> <span class="n">PRI</span> <span class="o">|</span> <span class="mi">0</span>       <span class="o">|</span>       <span class="o">|</span>
<span class="o">|</span> <span class="n">balance</span> <span class="o">|</span> <span class="nb">int</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span> <span class="o">|</span> <span class="k">NO</span>   <span class="o">|</span>     <span class="o">|</span> <span class="k">NULL</span>    <span class="o">|</span>       <span class="o">|</span>
<span class="o">|</span> <span class="k">version</span> <span class="o">|</span> <span class="nb">int</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span> <span class="o">|</span> <span class="k">NO</span>   <span class="o">|</span>     <span class="o">|</span> <span class="k">NULL</span>    <span class="o">|</span>       <span class="o">|</span>
<span class="o">+</span><span class="c1">---------+---------+------+-----+---------+-------+</span></code></pre></div>
<p>For the sake of our example, let&rsquo;s assume that someone has just opened
an account. Their balance is currently $0, so their row in the accounts
table would look something like this.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">accounts</span><span class="p">;</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">id</span> <span class="o">|</span> <span class="n">balance</span> <span class="o">|</span> <span class="k">version</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span>  <span class="mi">1</span> <span class="o">|</span>       <span class="mi">0</span> <span class="o">|</span>       <span class="mi">1</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+</span></code></pre></div>
<p>If our hypothetical user were to make a deposit of $100, Hibernate would
increment the account object&rsquo;s version property, and eventually execute
the following update. Pay close attention to the values used for the
version column. We&rsquo;re setting the new version value to 2, but only if
the row&rsquo;s current value for version is 1.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">update</span> <span class="n">accounts</span>
    <span class="o">-&gt;</span> <span class="k">set</span> <span class="n">balance</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">2</span>
    <span class="o">-&gt;</span> <span class="k">where</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">and</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">Query</span> <span class="n">OK</span><span class="p">,</span> <span class="mi">1</span> <span class="k">row</span> <span class="n">affected</span> <span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">00</span> <span class="n">sec</span><span class="p">)</span></code></pre></div>
<p>After executing the update statement, Hibernate will check the number of
rows that were affected. If nobody else modified the row, then the
version will still be 1, the update will modify exactly 1 row, and the
transaction commits. Our account now has a balance of $100 and a version
of 2.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">accounts</span><span class="p">;</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">id</span> <span class="o">|</span> <span class="n">balance</span> <span class="o">|</span> <span class="k">version</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span>  <span class="mi">1</span> <span class="o">|</span>     <span class="mi">100</span> <span class="o">|</span>       <span class="mi">2</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+</span></code></pre></div>
<p>What would have happened if somebody else had modified the row? Perhaps
our bank offers a $5,000 sign up bonus for new accounts, and the bonus
just happens to post at the exact same moment that we&rsquo;re making our
initial deposit. If the bonus transaction had committed after we read
the account balance, but before we committed the deposit, the table
would look like this.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">accounts</span><span class="p">;</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">id</span> <span class="o">|</span> <span class="n">balance</span> <span class="o">|</span> <span class="k">version</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span>  <span class="mi">1</span> <span class="o">|</span>    <span class="mi">5000</span> <span class="o">|</span>       <span class="mi">2</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+</span></code></pre></div>
<p>Now when our update statement is executed, the account has a balance of
$5,000 and a version of 2. Because we&rsquo;re updating where the version is
1, the update will &ldquo;miss&rdquo;. Zero rows will have been modified, and an
exception is thrown.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">update</span> <span class="n">accounts</span>
    <span class="o">-&gt;</span> <span class="k">set</span> <span class="n">balance</span> <span class="o">=</span> <span class="mi">100</span><span class="p">,</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">2</span>
    <span class="o">-&gt;</span> <span class="k">where</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">and</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">Query</span> <span class="n">OK</span><span class="p">,</span> <span class="mi">0</span> <span class="k">rows</span> <span class="n">affected</span> <span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">00</span> <span class="n">sec</span><span class="p">)</span></code></pre></div>
<p>This is exactly what we want to happen because if our transaction had
succeeded, we would have just lost out on $5,000. At this point, our
application will need to load a fresh instance of our account object and
apply the deposit again.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">update</span> <span class="n">accounts</span>
    <span class="o">-&gt;</span> <span class="k">set</span> <span class="n">balance</span> <span class="o">=</span> <span class="mi">5100</span><span class="p">,</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">3</span>
    <span class="o">-&gt;</span> <span class="k">where</span> <span class="n">id</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">and</span> <span class="k">version</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
<span class="n">Query</span> <span class="n">OK</span><span class="p">,</span> <span class="mi">1</span> <span class="k">row</span> <span class="n">affected</span> <span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">00</span> <span class="n">sec</span><span class="p">)</span></code></pre></div>
<p>This time our update succeeds, and the account has the correct balance
of $5,100, with a version of 3.</p>
<div class="highlight"><pre class="chroma"><code class="language-sql" data-lang="sql"><span class="n">mysql</span><span class="o">&gt;</span> <span class="k">select</span> <span class="o">*</span> <span class="k">from</span> <span class="n">accounts</span><span class="p">;</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span> <span class="n">id</span> <span class="o">|</span> <span class="n">balance</span> <span class="o">|</span> <span class="k">version</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+
</span><span class="c1"></span><span class="o">|</span>  <span class="mi">1</span> <span class="o">|</span>    <span class="mi">5100</span> <span class="o">|</span>       <span class="mi">3</span> <span class="o">|</span>
<span class="o">+</span><span class="c1">----+---------+---------+</span></code></pre></div>
<p>While automatic versioning solves the problem of concurrent
modifications within the boundaries of a database transaction, if your
business transactions span multiple server requests, automatic
versioning alone isn&rsquo;t enough. Hibernate has additional features that
help with this situation, which I&rsquo;ll go into in a future post.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Examining Dependencies in Maven Plugins]]></title>
    <link href="http://marcschwieterman.com/blog/examining-dependencies-in-maven-plugins/"/>
    <id>http://marcschwieterman.com/blog/examining-dependencies-in-maven-plugins</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-07-27T07:00:00+00:00</published>
    <updated>2010-07-27T07:00:00+00:00</updated>
    <content type="html"><![CDATA[<p>After you&rsquo;ve worked with Maven for a while, you&rsquo;ll eventually find a
need to extend it. While there are some means of executing arbitrary
code as part of your build, the best way to handle such needs is to
create a maven plugin. The task may seem a bit daunting at first, but
you&rsquo;ll learn a lot about how maven works by doing it. Listed below are
the properties that you need to define to examine the dependencies of a
maven project from within a plugin. The following code would be placed
inside a Maven
<a href="http://maven.apache.org/guides/plugin/guide-java-plugin-development.html">Mojo</a>.</p>

<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="cm">/** @parameter default-value=&#34;${project}&#34; */</span>
<span class="kd">private</span> <span class="n">MavenProject</span> <span class="n">mavenProject</span><span class="o">;</span>

<span class="cm">/** @parameter default-value=&#34;${localRepository}&#34; */</span>
<span class="kd">private</span> <span class="n">ArtifactRepository</span> <span class="n">localRepository</span><span class="o">;</span>

<span class="cm">/** @component */</span>
<span class="kd">private</span> <span class="n">ArtifactFactory</span> <span class="n">artifactFactory</span><span class="o">;</span>

<span class="cm">/** @component */</span>
<span class="kd">private</span> <span class="n">ArtifactResolver</span> <span class="n">resolver</span><span class="o">;</span>

<span class="cm">/** @component */</span>
<span class="kd">private</span> <span class="n">ArtifactMetadataSource</span> <span class="n">artifactMetadataSource</span><span class="o">;</span></code></pre></div>
<p>The @parameter annotation will bind maven properties to the annotated
property. You can refer to many properties on common Maven interfaces.
The @component annotation binds <a href="http://plexus.codehaus.org/">Plexus</a>
components from maven&rsquo;s DI framework. Unfortunately I&rsquo;ve yet to find a
single, concise documentation source, but the
<a href="http://docs.codehaus.org/display/MAVENUSER/Mojo+Developer+Cookbook">Codehaus Mojo Cookbook</a>
and the <a href="http://maven.apache.org/ref/2.2.1/apidocs/index.html">Maven API</a>
doc will point you in the right direction.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="n">Set</span><span class="o">&lt;</span><span class="n">Artifact</span><span class="o">&gt;</span> <span class="n">artifacts</span> <span class="o">=</span> <span class="n">mavenProject</span><span class="o">.</span><span class="na">createArtifacts</span><span class="o">(</span>
    <span class="n">artifactFactory</span><span class="o">,</span>
    <span class="kc">null</span><span class="o">,</span>
    <span class="k">new</span> <span class="n">GroupIdFilter</span><span class="o">(</span><span class="s">&#34;com.mydomain&#34;</span><span class="o">)</span>
<span class="o">);</span>

<span class="n">ArtifactResolutionResult</span> <span class="n">arr</span> <span class="o">=</span> <span class="n">resolver</span><span class="o">.</span><span class="na">resolveTransitively</span><span class="o">(</span>
    <span class="n">artifacts</span><span class="o">,</span>
    <span class="n">mavenProject</span><span class="o">.</span><span class="na">getArtifact</span><span class="o">(),</span>
    <span class="n">mavenProject</span><span class="o">.</span><span class="na">getRemoteArtifactRepositories</span><span class="o">(),</span>
    <span class="n">localRepository</span><span class="o">,</span>
    <span class="n">artifactMetadataSource</span>
<span class="o">);</span>

<span class="n">Set</span><span class="o">&lt;</span><span class="n">Artifact</span><span class="o">&gt;</span> <span class="n">completeDependencies</span> <span class="o">=</span> <span class="n">arr</span><span class="o">.</span><span class="na">getArtifacts</span><span class="o">();</span>

<span class="k">for</span><span class="o">(</span><span class="n">Artifact</span> <span class="n">art</span> <span class="o">:</span> <span class="n">completeDependencies</span><span class="o">)</span> <span class="o">{</span>
  <span class="c1">// do something interesting
</span><span class="c1"></span><span class="o">}</span></code></pre></div>
<p>Once you have access to all the needed properties, you can use code
similar to the above to examine the dependencies of your project. This
particular snippet will collect all dependencies and transitive
dependencies for artifacts with a group id of &ldquo;com.mydomain&rdquo; into the
<em>completeDependencies</em> set. <em>GroupIdFilter</em> is a simple implementation
of the
<a href="http://maven.apache.org/ref/2.2.1/apidocs/org/apache/maven/artifact/resolver/filter/ArtifactFilter.html">ArtifactFilter</a>
interface. Note that these are the dependencies of the project that the
plugin is executing in, not just those of the plugin itself.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="n">JarFile</span> <span class="n">jar</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JarFile</span><span class="o">(</span><span class="n">artifact</span><span class="o">.</span><span class="na">getFile</span><span class="o">());</span></code></pre></div>
<p>The ability to determine all of the transitive dependencies of your
project like this can be very powerful. Once you get ahold of an
artifact, you can easily create a
<a href="http://java.sun.com/javase/6/docs/api/java/util/jar/JarFile.html">JarFile</a>
and inspect its manifest, entries or whatever you&rsquo;re interested in. This
allows you to do things like create artifacts that contain code or
configuration that feeds into your build process, and automatically
discover and take action merely by adding them as a project dependency.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Getting Files onto the iPad]]></title>
    <link href="http://marcschwieterman.com/blog/getting-files-onto-the-ipad/"/>
    <id>http://marcschwieterman.com/blog/getting-files-onto-the-ipad</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-07-19T06:39:28+00:00</published>
    <updated>2010-07-19T06:39:28+00:00</updated>
    <content type="html"><![CDATA[<p>The lack of a file system on the iPad and other iOS based devices can
sometimes be frustrating. While applications like
<a href="https://www.dropbox.com/">Dropbox</a> make accessing your existing files
trivial, getting new files onto your device directly from the web is not
as easy. If you come across a PDF or other file that you&rsquo;d like to open
in a local application, you may be out of luck.</p>

<p>The best way I&rsquo;ve found to get files onto the iPad without the aid of
your computer is <a href="http://www.goodiware.com/goodreader.html">GoodReader</a>.
In addition to being an excellent PDF reader, GoodReader is also a
robust file manager. It supports about anything you can think of,
including Dropbox, iDisk, USB, FTP and even a web-based interface
accessible via WiFi. Most importantly, you can give it a URL, and it
will download the specified file into its local storage.</p>

<p>The GoodReader manual includes instructions on
<a href="http://www.goodiware.com/gr-man-howto.html#ghttp">how to save a file from Safari into GoodReader</a>.
You have to either add a special prefix to the URL, or you can copy and
paste it into the application. GoodReader supports this feature by
<a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102207">registering a protocol handler</a>
for ghttp, grhttp, and a few others. While I think this is a great
feature, I don&rsquo;t particularly like doing things manually, so I created a
simple bookmarklet to do this for me.</p>
<div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript"><span class="nx">javascript</span><span class="o">:</span> <span class="nx">location</span><span class="p">.</span><span class="nx">assign</span><span class="p">(</span><span class="s1">&#39;gr&#39;</span> <span class="o">+</span> <span class="nx">location</span><span class="p">.</span><span class="nx">href</span><span class="p">);</span>
</code></pre></div>
<p>The bookmarklet uses the <a href="http://www.w3schools.com/jsref/obj_location.asp">Location object</a>
to open a new page to the current URL with &lsquo;gr&rsquo; prepended to it. This
saves you from manually editing or copying the URL of the document you
want to download. You can install the bookmarklet with the instructions
below.</p>

<ol>
<li>Bookmark this page</li>
<li>Copy the bookmarlet script above to your clipboard</li>
<li>Edit the bookmark</li>
<li>Set the name to something appropriate. I use &lsquo;goodreadit&rsquo;.</li>
<li>Paste the code into the address field</li>
</ol>

<p>The easiest way to copy the bookmarklet script on the iPad is to hold
your finger down on it until the copy button pops up. Once the
bookmarlet is installed, all you need to do is click on it, and whatever
document you have open in Safari will automatically start downloading
into GoodReader. According to the GoodReader documentation, the import
feature may not always work correctly with SSL, but I&rsquo;ve yet to have any
trouble with it.</p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[Simple Stub Creation with Mockito Partial Mocks]]></title>
    <link href="http://marcschwieterman.com/blog/simple-stub-creation-with-mockito-partial-mocks/"/>
    <id>http://marcschwieterman.com/blog/simple-stub-creation-with-mockito-partial-mocks</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-07-16T06:50:27+00:00</published>
    <updated>2010-07-16T06:50:27+00:00</updated>
    <content type="html"><![CDATA[<p>When testing code that interacts with lower layers, I often stub out the
lower layer to return objects to the code that I&rsquo;m actually testing. I
mostly use stubs generated by a mocking framework, but I occasionally
come across cases where the stub needs to do something other than just
return a known object. Take the case of a
<a href="http://java.sun.com/blueprints/patterns/DAO.html">DAO</a> that assigns a
generated identifier to a domain object. Here we see a service that
takes a name, creates a <code>User</code> object with it, persists the object and
returns the generated id to the caller.</p>

<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserService</span> <span class="o">{</span>

  <span class="n">Long</span> <span class="nf">create</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">);</span>

<span class="o">}</span></code></pre></div>
<p>In this situation, I would want to test that the following are true.</p>

<ol>
<li>the service calls the <code>persist</code> method on the DAO</li>
<li>the service returns the correct id value</li>
</ol>

<p>Testing the DAO call is easy enough using a mock.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">create_calls_persist</span><span class="o">()</span> <span class="o">{</span>
  <span class="n">UserDao</span> <span class="n">dao</span> <span class="o">=</span> <span class="n">mock</span><span class="o">(</span><span class="n">UserDao</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
  <span class="n">UserService</span> <span class="n">service</span> <span class="o">=</span> <span class="k">new</span> <span class="n">UserServiceImpl</span><span class="o">(</span><span class="n">dao</span><span class="o">);</span>

  <span class="n">service</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">&#34;bob kelso&#34;</span><span class="o">);</span>

  <span class="n">verify</span><span class="o">(</span><span class="n">dao</span><span class="o">).</span><span class="na">persist</span><span class="o">(</span><span class="n">any</span><span class="o">(</span><span class="n">User</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
<span class="o">}</span></code></pre></div>
<p>How do we test that the service returns the correct id? The id will be
null by default because it&rsquo;s a <code>Long</code>. At the very least we should make
sure it&rsquo;s a non-null value, and we would prefer to assert that it&rsquo;s
something specific. We can&rsquo;t stub the domain object because the service
creates it. One option is to create a stub implementation of the DAO
that simply sets the object&rsquo;s id to a known value. Assume that our DAO
interface looks like the one below.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">UserDao</span> <span class="o">{</span>

  <span class="kt">void</span> <span class="nf">persist</span><span class="o">(</span><span class="n">User</span> <span class="n">user</span><span class="o">);</span>
  <span class="kt">void</span> <span class="nf">update</span><span class="o">(</span><span class="n">User</span> <span class="n">user</span><span class="o">);</span>
  <span class="kt">void</span> <span class="nf">delete</span><span class="o">(</span><span class="n">User</span> <span class="n">user</span><span class="o">);</span>
  <span class="n">User</span> <span class="nf">load</span><span class="o">(</span><span class="n">Long</span> <span class="n">id</span><span class="o">);</span>
  <span class="n">User</span> <span class="nf">findByName</span><span class="o">(</span><span class="n">String</span> <span class="n">name</span><span class="o">);</span>

<span class="o">}</span></code></pre></div>
<p>While there aren&rsquo;t too many methods, we really don&rsquo;t care about anything
but <code>persist</code>, so it&rsquo;d be nice if we only had to deal with the things we
do care about. This is where <a href="http://mockito.org/">Mockito</a> comes in.
Using the <a href="http://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#16">partial mocks</a>
feature added in version 1.8.0, we can create an abstract class that
only implements the <code>persist</code> method, and let Mockito supply its useful
default implementations for the rest of the methods.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="kd">public</span> <span class="kd">class</span> <span class="nc">UserServiceTest</span> <span class="o">{</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="n">Long</span> <span class="n">ONE_OF_TYPE_LONG</span> <span class="o">=</span> <span class="n">1L</span><span class="o">;</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">UserDaoStub</span> <span class="kd">implements</span> <span class="n">UserDao</span> <span class="o">{</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">persist</span><span class="o">(</span><span class="n">User</span> <span class="n">user</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">user</span><span class="o">.</span><span class="na">setId</span><span class="o">(</span><span class="n">ONE_OF_TYPE_LONG</span><span class="o">);</span>
    <span class="o">}</span>

  <span class="o">}</span>

<span class="o">}</span></code></pre></div>
<p>We now have an abstract stub for our DAO that will set the id of any
objects it persists to a 1 of type Long. You can obviously do something
more complicated if needed. Next we use Mockito to provide the rest of
the implementation.</p>
<div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java"><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">create_returns_generated_id</span><span class="o">()</span> <span class="o">{</span>
  <span class="n">UserDao</span> <span class="n">dao</span> <span class="o">=</span> <span class="n">mock</span><span class="o">(</span><span class="n">UserDaoStub</span><span class="o">.</span><span class="na">class</span><span class="o">);</span>
  <span class="n">doCallRealMethod</span><span class="o">().</span><span class="na">when</span><span class="o">(</span><span class="n">dao</span><span class="o">).</span><span class="na">persist</span><span class="o">(</span><span class="n">any</span><span class="o">(</span><span class="n">User</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
  <span class="n">UserService</span> <span class="n">service</span> <span class="o">=</span> <span class="k">new</span> <span class="n">UserServiceImpl</span><span class="o">(</span><span class="n">dao</span><span class="o">);</span>

  <span class="n">Long</span> <span class="n">id</span> <span class="o">=</span> <span class="n">service</span><span class="o">.</span><span class="na">create</span><span class="o">(</span><span class="s">&#34;bob kelso&#34;</span><span class="o">);</span>

  <span class="n">assertThat</span><span class="o">(</span><span class="n">id</span><span class="o">,</span> <span class="n">is</span><span class="o">(</span><span class="n">ONE_OF_TYPE_LONG</span><span class="o">));</span>
<span class="o">}</span></code></pre></div>
<p>The only thing different about creating a partial mock, is that you need
to call either <code>thenCallRealMethod()</code> or <code>doCallRealMethod()</code> to
indicate which method calls to delegate to the real object. The example
above uses <code>doCallRealMethod()</code> because <code>persist</code> has a void return
type. I&rsquo;ve found this technique to be a very effective way to create
focused stubs that allow you to specify what you need to, and not worry
about the rest.</p>

<p><strong><em>Update 2012-05-31</em></strong></p>

<p><em>Someone pointed out in the now gone comments that this approach does not
work if the stub class needs to carry state. If this is the case for
you, you may want to consider a
<a href="http://www.martinfowler.com/bliki/TestDouble.html">fake</a>. This may also
be an opportunity to refactor your code to make it easier to test the
desired behavior in isolation.</em></p>]]></content>
  </entry>
  <entry>
    <title type="html"><![CDATA[MarsEdit: Preview with SyntaxHighlighter]]></title>
    <link href="http://marcschwieterman.com/blog/marsedit-preview-with-syntaxhighlighter/"/>
    <id>http://marcschwieterman.com/blog/marsedit-preview-with-syntaxhighlighter</id>
    <author>
      <name>Marc Schwieterman</name>
    </author>
    <published>2010-07-06T21:24:07+00:00</published>
    <updated>2010-07-06T21:24:07+00:00</updated>
    <content type="html"><![CDATA[<p>I&rsquo;ve recently been trying out the
<a href="http://www.red-sweater.com/marsedit/">MarsEdit</a> blog editor. One issue
I&rsquo;ve run into is that
<a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a>
doesn&rsquo;t work with the preview feature because the page in the preview
window <a href="http://www.red-sweater.com/forums/viewtopic.php?pid=6746#p6746">only gets loaded once</a>.
Fortunately there is a workaround. A typical SyntaxHighlighter
configuration will look similar to the code fragment below.</p>

<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span><span class="p">&gt;</span>
  <span class="p">...</span>

  <span class="nx">SyntaxHighlighter</span><span class="p">.</span><span class="nx">all</span><span class="p">();</span>

<span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span></code></pre></div>
<p>To get SyntaxHighliter to work in the preview pane, you need to write a
javascript function to execute the highlighting code repeatedly at some
interval. The following code will highlight the page once, then
highlight it again every second. The main difference is that you must
call <code>SyntaxHighlighter.highlight()</code>, as <code>SyntaxHighlighter.all()</code> will
only highlight your text when the page&rsquo;s onLoad event is executed.</p>
<div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/javascript&#34;</span><span class="p">&gt;</span>
  <span class="p">...</span>

  <span class="kd">function</span> <span class="nx">refreshHighlighting</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">SyntaxHighlighter</span><span class="p">.</span><span class="nx">highlight</span><span class="p">();</span>
    <span class="nx">setTimeout</span><span class="p">(</span><span class="s2">&#34;refreshHighlighting()&#34;</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nx">refreshHighlighting</span><span class="p">();</span>

<span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span></code></pre></div>
<p>That&rsquo;s all there is to it. The timeout is in milliseconds, and I haven&rsquo;t
noticed any appreciable load at 1 second. You can set the refresh
interval to something higher, but be aware that you&rsquo;ll have to wait that
long for your code to be highlighted again in the preview window. Refer
to the <a href="http://www.w3schools.com/js/js_timing.asp">setTimeout reference</a>
if you have more robust refresh timing needs.</p>]]></content>
  </entry>
</feed>
