<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Structured Procrastination &#187; xml</title>
	<atom:link href="http://blog.adamspiers.org/tag/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.adamspiers.org</link>
	<description>because there's always something more interesting than what you should be doing</description>
	<lastBuildDate>Sat, 05 May 2012 16:47:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Maven fail</title>
		<link>http://blog.adamspiers.org/2010/10/07/maven-fail/</link>
		<comments>http://blog.adamspiers.org/2010/10/07/maven-fail/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 19:18:37 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[hidden]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.adamspiers.org/?p=277</guid>
		<description><![CDATA[In my recent work I have encountered Apache Maven, and I think the following snippet of real-world Maven code nicely sums up why Maven is not the idea replacement for the horror that is ant: Dear god. 34 lines and a plug-in, just to change the permissions on a file in a platform-specific way?? I [...]]]></description>
			<content:encoded><![CDATA[<p>In my recent work I have encountered <a href="http://maven.apache.org/">Apache Maven</a>, and I think the following snippet of real-world Maven code nicely sums up why Maven is <strong>not</strong> the idea replacement for <a href="http://blog.adamspiers.org/ant-dependency-fail/">the horror that is ant</a>:</p>
<pre class="brush: xml; title: ; notranslate">
  &lt;profiles&gt;
    &lt;profile&gt;
      &lt;id&gt;unix&lt;/id&gt;
      &lt;activation&gt;
        &lt;os&gt;
          &lt;family&gt;unix&lt;/family&gt;
        &lt;/os&gt;
      &lt;/activation&gt;
      &lt;build&gt;
        &lt;plugins&gt;
          &lt;plugin&gt;
            &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
            &lt;artifactId&gt;exec-maven-plugin&lt;/artifactId&gt;
            &lt;executions&gt;
              &lt;execution&gt;
                &lt;id&gt;set-run-file-perms&lt;/id&gt;
                &lt;phase&gt;generate-resources&lt;/phase&gt;
                &lt;goals&gt;
                  &lt;goal&gt;exec&lt;/goal&gt;
                &lt;/goals&gt;
                &lt;configuration&gt;
                  &lt;executable&gt;chmod&lt;/executable&gt;
                  &lt;arguments&gt;
                    &lt;argument&gt;0755&lt;/argument&gt;
                    &lt;argument&gt;${project.build.directory}/foo.sh&lt;/argument&gt;
                  &lt;/arguments&gt;
                &lt;/configuration&gt;
              &lt;/execution&gt;
            &lt;/executions&gt;
          &lt;/plugin&gt;
        &lt;/plugins&gt;
      &lt;/build&gt;
    &lt;/profile&gt;
  &lt;/profiles&gt;
</pre>
<p>Dear god.  34 lines and a plug-in, just to change the permissions on a file in a platform-specific way??</p>
<p>I should add that the above was written by an extremely smart guy who is a top-notch programmer; no, I don&#8217;t think the author is at fault here.  Even if there&#8217;s a more concise/portable way of achieving the same result in Maven (and there might well be &#8211; I admit I&#8217;m still a Maven newbie), there&#8217;s still the undeniable fact that XML is horrendously verbose, and any code written in it is by nature unnecessarily difficult to maintain.  To this end I applaud the <a href="http://github.com/mrdon/maven-yamlpom-plugin/wiki">ongoing efforts supporting the use of YAML to implement the Maven POM</a>.</p>
<p>It&#8217;s worth seeing what the above would look like if we wrote it in <a href="http://rake.rubyforge.org/">rake</a>:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'pathname'

desc &quot;Make binary executable&quot;
task :chmod do
  File.new(Pathname.new(build_dir) + &quot;foo.sh&quot;).chmod(0755)
end
</pre>
<p>I don&#8217;t think I need to make a case for which is more legible or maintainable.  Oh, <em>and</em> the Ruby version is cross-platform.</p>
<p>To continue an anti-XML rant which has been made <a href="http://www.google.co.uk/search?q=xml+sucks">countless times already</a>: what the ant and Maven people don&#8217;t seem to realise is that XML is not a real programming language and is therefore not expressive enough to deal with many cases that a build system needs.  The clue&#8217;s <a href="http://en.wikipedia.org/wiki/Xml">in the name</a>, guys!  &#8220;M&#8221; is for &#8220;markup&#8221; not &#8220;<a href="http://en.wikipedia.org/wiki/Turing_completeness">Turing-complete</a>&#8220;.  That&#8217;s why every time you need to do something vaguely unusual for which there isn&#8217;t an ant <code>taskdef</code> or Maven plugin, you have to write hundreds of lines more Java/XML just to cope with that case.  That&#8217;s why Maven needs so many damn plugins.</p>
<p>The accidental silver lining to this is that because it takes so much effort to accomplish simple tasks, Maven developers find themselves compelled to reuse and share plugins, and to be fair, Maven has some good ideas on how to do this, even if the implementation isn&#8217;t always the best.  For example, the built-in <a href="http://maven.apache.org/repository-management.html">plug-in repository management</a> and <a href="http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">plug-in dependency management</a> seem to work nicely, but unfortunately for some reason it has a propensity to download plug-ins on most runs, far more frequently than any sensible caching layer should.</p>
<p><a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSL</a> issues aside, I&#8217;m not convinced by <a href="http://en.wikipedia.org/wiki/Apache_Maven#Build_Lifecycles">the fixed lifecycle philosophy behind Maven</a> either.  I wonder if it was borne out of frustration with <a href="http://blog.adamspiers.org/ant-dependency-fail/">the lack of proper dependency checking in ant</a>.</p>
<p>That said, I do like how Maven encourages standardization of the build lifecycle and phase namespace thereof, since newcomers to a project immediately know some familiar entry points.  But the same could be said of 99% of projects which use Make and use standard rule target names such as <code>install</code> and <code>clean</code>.  And I suspect that many developers suffer when they try to shoe-horn their own project&#8217;s build requirements into Maven&#8217;s standard lifecycle.</p>
<p>My concern with this phased approach is that it is too linear.  The expectation is that a build process is a one-dimensional sequence of steps, and you get to choose your starting point but not much else.  This seems fundamentally wrong to me.  A build dependency tree is well understood to be a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">DAG</a>, and any build system which doesn&#8217;t model this properly seems to me to be burying its head in the sand.  On the other hand, if it does model it properly, which includes implementing proper dependency resolution, the required build lifecycle should emerge naturally without having to dictate that <code>generate-sources</code> comes before <code>compile</code> which comes before <code>test</code> and so on.</p>
<p>I&#8217;ve had some ideas of what the ideal build system looks like, and how to get there from the conventional Java world.  More on that soon.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.adamspiers.org%2F2010%2F10%2F07%2Fmaven-fail%2F&amp;title=Maven%20fail" id="wpa2a_2"><img src="http://blog.adamspiers.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.adamspiers.org/2010/10/07/maven-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ant dependency FAIL</title>
		<link>http://blog.adamspiers.org/2010/01/05/ant-dependency-fail/</link>
		<comments>http://blog.adamspiers.org/2010/01/05/ant-dependency-fail/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 01:28:03 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[hidden]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.adamspiers.org/?p=196</guid>
		<description><![CDATA[Oh wow, that&#8217;s four hours of my life I won&#8217;t get back. Four hours trying to figure out why the hell my changes to .java source files weren&#8217;t showing up in the compiled binaries, debugging an unholy mess of ant XML files, before I finally realised how badly ant&#8217;s dependency checking sucks &#8230; Then 5 [...]]]></description>
			<content:encoded><![CDATA[<p>Oh wow, that&#8217;s four hours of my life I won&#8217;t get back.</p>
<p>Four hours trying to figure out why the hell my changes to .java source files weren&#8217;t showing up in the compiled binaries, debugging an unholy mess of ant XML files, before I finally realised how badly ant&#8217;s dependency checking sucks &#8230; Then 5 minutes of googling for &#8216;ant sucks&#8217; and I find two <a href="http://andreas-krey.blogspot.com/2009/01/ant-bad.html">excellently written</a> <a href="http://olsner.se/2008/03/29/ant-sucks/">rants</a> which confirm my discovery (you might need to consult google&#8217;s cache for the latter).</p>
<p>I shouldn&#8217;t have been surprised.  Anything which uses XML as a domain-specific language should have already set the alarm bells ringing, but my excitement at learning something new initially blotted out the dull headache caused by hacking in XML.  Bah!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.adamspiers.org%2F2010%2F01%2F05%2Fant-dependency-fail%2F&amp;title=ant%20dependency%20FAIL" id="wpa2a_4"><img src="http://blog.adamspiers.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.adamspiers.org/2010/01/05/ant-dependency-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hacking Blogger templates</title>
		<link>http://blog.adamspiers.org/2009/04/19/hacking-blogger-templates/</link>
		<comments>http://blog.adamspiers.org/2009/04/19/hacking-blogger-templates/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 16:20:00 +0000</pubDate>
		<dc:creator>Adam</dc:creator>
				<category><![CDATA[geek]]></category>
		<category><![CDATA[hidden]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://wp.adamspiers.org/?p=9</guid>
		<description><![CDATA[The ultimate goal here was filtering of posts based on inclusion (or even better, exclusion) of posts with certain labels. (Read this post first for context.) [Update: before you think about imitating the following approach, you should know that I gave up with Blogger and switched to WordPress which is far more flexible and easy [...]]]></description>
			<content:encoded><![CDATA[<p>The ultimate goal here was filtering of posts based on inclusion (or even better, exclusion) of posts with certain labels.  (Read <a href="http://blog.adamspiers.org/2009/04/two-blogs-or-not-two-blogs.html">this post</a> first for context.)</p>
<p>[<strong>Update:</strong> before you think about imitating the following approach, you should know that <a href="http://blog.adamspiers.org/2009/05/03/goodbye-blogger-hello-wordpress/">I gave up with Blogger and switched to WordPress</a> which is far more flexible and easy to hack.]</p>
<p>Unfortunately it turns out that <a href="http://help.blogger.com/bin/topic.py?topic=12488">Blogger&#8217;s XML-based template layout system</a> is not quite as flexible as it first seems.  It&#8217;s almost superb, but has some key omissions:</p>
<ul>
<li>Flow control is limited to <code>&lt;b:if&gt;</code>, <code>&lt;b:else&gt;</code>, and <code>&lt;b:loop&gt;</code>.  Crucially, you can&#8217;t break out of a loop.</li>
<li>No writable variables of any kind.</li>
<li>Conditional testing via <code>&lt;b:cond&gt;</code> is extremely limited.  I kept expecting to find some comprehensive documentation for the <code>xmlns:expr</code> namespace (which is used via things like <code>&lt;a expr:href='data:blog.homepageUrl + "search/label/foo"'&gt;</code>), but it doesn&#8217;t exist, simply because all you can really do is simple comparisons using <a href="http://help.blogger.com/bin/answer.py?hl=en&amp;answer=47270">a limited set of data</a> and hardcoded strings.</li>
<li>There are no string-handling functions, and you can&#8217;t get access to the current <code>QUERY_STRING</code> to do any kind of parametrisation (for example, show some HTML saying which label you are currently viewing based on what comes after <code>/search/label/</code> in the current URL).</li>
<li>The box generated by the status-message includable is hardcoded to either be invisible or say &#8220;Showing label <span style="font-style: italic;">foo</span>. Show all posts&#8221;.  It cannot be customised.</li>
</ul>
<p><span id="more-9"></span>I briefly considered ditching the idea of fiddling with this XML, and just using Javascript and CSS to hide the posts I wanted hidden, but persevered and came up with a solution with the following ingredients:</p>
<ul>
<li>I will label all posts with at least one of &#8216;geek&#8217; or &#8216;main&#8217;, or possibly both.  Posts labelled &#8216;main&#8217; will appear on the default home page view.  This is unfortunately necessary since there is no general way of <span style="font-style: italic;">excluding</span> posts with a particular label, only <span style="font-style: italic;">including</span>.  The reason for this is that the only way to test for membership in a set of labels is by looping over all the post&#8217;s labels, and when you find the one you are including for, you output the post&#8217;s contents.  If you were trying to exclude, you&#8217;d need a temporary variable to flag when you&#8217;d found the excluded label, then use that outside the loop.</li>
<li>I used a <a href="http://groups.google.com/group/blogger-help-customizing/browse_frm/thread/9b7eb58b82305426?tvc=1&amp;q=filtering">standard</a> template modification <a href="http://blog.mobocracy.net/2007/06/filtering-blogger-by-label.html">trick</a> to limit visible posts on the home page to those labelled &#8216;main&#8217;.</li>
<li>I wrapped my custom code in stuff like <code>&lt;b:if cond='data:blog.pageType != "item"'&gt;</code> so that it wouldn&#8217;t mess with single-post views.</li>
<li>I figured out that <a href="http://blogs.adamspiers.org/search/label/">http://blogs.adamspiers.org/search/label/</a> is a URL which will yield a view containing all posts, circumventing the <code>&lt;b:if cond='data:blog.url == data:blog.homepageUrl'&gt;</code> equality test in my default view (<a href="http://blogs.adamspiers.org/search/">http://blogs.adamspiers.org/search/</a> also works)</li>
<li>I reimplemented the status-message box from scratch, using Javascript:
<pre class="brush: jscript; title: ; notranslate">
var labelsel = document.URL.match(/\/search\/label\/(.*)/);
var view = 'unknown';
if (document.URL == &quot;&amp;lt;data:blog.homepageUrl/&amp;gt;&quot;) {
view = 'default';
} else if (labelsel) {
switch (labelsel[1]) {
case &quot;&quot;: view = 'all';     break
case &quot;main&quot;:       view = 'default'; break
case &quot;geek&quot;:       view = 'geek';    break
default:           view = 'label';
}
} else if (document.URL.match(/\/search.*updated-min/)) {
view = 'time range';
} else {
view = 'unknown';
}

switch (view) {
case 'all':
document.write(&quot;Showing all posts.  &amp;lt;a href='/search/label/main'&amp;gt;Hide the geek stuff&amp;lt;/a&amp;gt; or &amp;lt;a href='/search/label/geek'&amp;gt;hide the non-geek stuff&amp;lt;/a&amp;gt;&quot;);
break;
case 'default':
document.write(&quot;Not showing computer stuff.  You can see &amp;lt;a href='/search/label/geek'&amp;gt;the geek stuff&amp;lt;/a&amp;gt;, &amp;lt;a href='/search/label/music'&amp;gt;music stuff&amp;lt;/a&amp;gt;, or &amp;lt;a href='/search/label/'&amp;gt;all posts together&amp;lt;/a&amp;gt;.&quot;);
break;
case 'geek':
document.write(&quot;Only showing computer stuff.&amp;lt;br/&amp;gt;&amp;lt;a href='/search/label/'&amp;gt;See all posts&amp;lt;/a&amp;gt; or &amp;lt;a href='/search/label/main'&amp;gt;just the non-geek stuff&amp;lt;/a&amp;gt;&quot;);
break;
case 'label':
document.write(&quot;Only showing posts labelled &amp;lt;strong&amp;gt;&quot; + labelsel[1] + &quot;&amp;lt;/strong&amp;gt;.&amp;lt;br/&amp;gt;&amp;lt;a href='/'&amp;gt;Go to default view&amp;lt;/a&amp;gt;&quot;);
break;
case 'time range':
document.write(&quot;Showing posts within a time range.&amp;lt;br/&amp;gt;&amp;lt;a href='/'&amp;gt;Go to default view&amp;lt;/a&amp;gt;&quot;);
break;
case 'unknown':
document.write(&quot;Unknown viewing mode, but don't panic.&quot;);
break;
default:
document.write(&quot;BUG: Don't know how to handle viewing mode &quot; + view);
}
</pre>
</li>
<li>I replaced the non-item part of the feedLinks includable with a hardcoded version.</li>
<li>I altered the label-listing widget to exclude the &#8216;main&#8217; label from being displayed.</li>
</ul>
<p>If you want to look at my complete layout template, it&#8217;s <a href="http://adamspiers.org/blogger/layout.xml">here</a>.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.adamspiers.org%2F2009%2F04%2F19%2Fhacking-blogger-templates%2F&amp;title=Hacking%20Blogger%20templates" id="wpa2a_6"><img src="http://blog.adamspiers.org/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.adamspiers.org/2009/04/19/hacking-blogger-templates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

