<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>movw $0x1f01,0xb8000; hlt;</title>
	
	<link>http://pub.mouraf.org/blog</link>
	<description>by Pierre-Alexandre Meyer</description>
	<lastBuildDate>Sun, 22 May 2011 16:53:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Movw0x1f010xb8000Hlt" /><feedburner:info uri="movw0x1f010xb8000hlt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Movw0x1f010xb8000Hlt</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Tech Talk: Realtime Analytics at Ning</title>
		<link>http://feedproxy.google.com/~r/Movw0x1f010xb8000Hlt/~3/Bbi7QhhuY50/</link>
		<comments>http://pub.mouraf.org/blog/2011/04/tech-talk-realtime-analytics-at-ning/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 14:37:27 +0000</pubDate>
		<dc:creator>pierre</dc:creator>
				<category><![CDATA[misc.]]></category>
		<category><![CDATA[analytics]]></category>

		<guid isPermaLink="false">http://pub.mouraf.org/blog/?p=388</guid>
		<description><![CDATA[Update: the video is online! I will be speaking at Ning next Wednesday, April 27, on our approach to Realtime Analytics. Details here: http://www.meetup.com/Ning-Tech-Talks/events/17221783/. If you&#8217;d like to give a lightning talk, let me know and I&#8217;ll put you on the schedule (it doesn&#8217;t have to be Analytics related). For those who can&#8217;t make it [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> the video is online!</p>
<p><iframe src="http://player.vimeo.com/video/23323294" width="500" height="281" frameborder="0"></iframe></p>
<p>I will be speaking at Ning next Wednesday, April 27, on our approach to Realtime Analytics.</p>
<p>Details here: <a href="http://www.meetup.com/Ning-Tech-Talks/events/17221783/" target="_blank">http://www.meetup.com/Ning-Tech-Talks/events/17221783/</a>.</p>
<p>If you&#8217;d like to give a lightning talk, let me know and I&#8217;ll put you on the schedule (it doesn&#8217;t have to be Analytics related).</p>
<p>For those who can&#8217;t make it (any French reader willing to fly-in just for the talk?), the video will be posted online the following week.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/uR4eXx-vOM_gmgfmMY9SSX4BVxI/0/da"><img src="http://feedads.g.doubleclick.net/~a/uR4eXx-vOM_gmgfmMY9SSX4BVxI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/uR4eXx-vOM_gmgfmMY9SSX4BVxI/1/da"><img src="http://feedads.g.doubleclick.net/~a/uR4eXx-vOM_gmgfmMY9SSX4BVxI/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=Bbi7QhhuY50:thDiPSwkUxo:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=Bbi7QhhuY50:thDiPSwkUxo:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=Bbi7QhhuY50:thDiPSwkUxo:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?i=Bbi7QhhuY50:thDiPSwkUxo:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Movw0x1f010xb8000Hlt/~4/Bbi7QhhuY50" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pub.mouraf.org/blog/2011/04/tech-talk-realtime-analytics-at-ning/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pub.mouraf.org/blog/2011/04/tech-talk-realtime-analytics-at-ning/</feedburner:origLink></item>
		<item>
		<title>ActiveMQ: java.lang.IllegalArgumentException: port out of range:-1</title>
		<link>http://feedproxy.google.com/~r/Movw0x1f010xb8000Hlt/~3/VMEMD8xx3Vk/</link>
		<comments>http://pub.mouraf.org/blog/2011/03/activemq-java-lang-illegalargumentexception-port-out-of-range-1/#comments</comments>
		<pubDate>Fri, 11 Mar 2011 17:40:01 +0000</pubDate>
		<dc:creator>pierre</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[activemq]]></category>

		<guid isPermaLink="false">http://pub.mouraf.org/blog/?p=381</guid>
		<description><![CDATA[I came across an interesting error when starting an ActiveMQ client the other day: It turns out to be related to the DNS: java.net.URI.getHost() returns null if the DNS contains an underscore. The following JRuby snippet demonstrates it: Hostnames are supposed to contain only letters, numbers and the hyphen. From rfc952: 1. A &#8220;name&#8221; (Net, [...]]]></description>
			<content:encoded><![CDATA[<p>I came across an interesting error when starting an ActiveMQ client the other day:</p>
<pre class="brush: plain; title: ; notranslate">
Could not connect to broker URL: tcp://activemq_qa.company.com:35000. Reason: java.lang.IllegalArgumentException: port out of range:-1
</pre>
<p>It turns out to be related to the DNS: java.net.URI.getHost() returns null if the DNS contains an underscore. The following JRuby snippet demonstrates it:</p>
<pre class="brush: ruby; title: ; notranslate">
pierre % cat dns.rb
require &quot;java&quot;
include_class &quot;java.net.URI&quot;

INVALID_URI = &quot;tcp://dns_foo.company.com:35000&quot;
VALID_URI   = &quot;tcp://dns-foo.company.com:35000&quot;

u = URI.new(INVALID_URI)
puts u.getHost, u.getPort

v = URI.new(VALID_URI)
puts v.getHost, v.getPort

pierre % jruby dns.rb
nil
-1
dns-foo.company.com
35000
</pre>
<p>Hostnames are supposed to contain only letters, numbers and the hyphen. From <a href="http://tools.ietf.org/html/rfc952" target=_blank>rfc952</a>:</p>
<blockquote><p>
 1. A &#8220;name&#8221; (Net, Host, Gateway, or Domain name) is a text string up<br />
   to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus<br />
   sign (-), and period (.).
</p></blockquote>
<p>I just wished the error was a bit more meaningful.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/BUrTiyP-wrEoI22DGrrdtqrNqo4/0/da"><img src="http://feedads.g.doubleclick.net/~a/BUrTiyP-wrEoI22DGrrdtqrNqo4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/BUrTiyP-wrEoI22DGrrdtqrNqo4/1/da"><img src="http://feedads.g.doubleclick.net/~a/BUrTiyP-wrEoI22DGrrdtqrNqo4/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=VMEMD8xx3Vk:2qO7kZl5Sk8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=VMEMD8xx3Vk:2qO7kZl5Sk8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=VMEMD8xx3Vk:2qO7kZl5Sk8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?i=VMEMD8xx3Vk:2qO7kZl5Sk8:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Movw0x1f010xb8000Hlt/~4/VMEMD8xx3Vk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pub.mouraf.org/blog/2011/03/activemq-java-lang-illegalargumentexception-port-out-of-range-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://pub.mouraf.org/blog/2011/03/activemq-java-lang-illegalargumentexception-port-out-of-range-1/</feedburner:origLink></item>
		<item>
		<title>Low latency analytics at Ning</title>
		<link>http://feedproxy.google.com/~r/Movw0x1f010xb8000Hlt/~3/AcdRusM2Uvs/</link>
		<comments>http://pub.mouraf.org/blog/2011/02/low-latency-analytics-at-ning/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 18:42:09 +0000</pubDate>
		<dc:creator>pierre</dc:creator>
				<category><![CDATA[open-source]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[netezza]]></category>
		<category><![CDATA[ning]]></category>

		<guid isPermaLink="false">http://pub.mouraf.org/blog/?p=369</guid>
		<description><![CDATA[[This post was originally featured on the Ning code blog.] The Analytics team at Ning has recently been working on a low latency feed from our platform. With more and more features being offered to our Network Creators, we need to be able to get quick feedback from our products and systems: if a deployment [...]]]></description>
			<content:encoded><![CDATA[<p>[This post was originally featured on the <a href="http://code.ning.com/2011/01/low-latency-analytics-at-ning/" target="_blank">Ning code blog</a>.]</p>
<p>The Analytics team at Ning has recently been working on a low latency feed from our platform. With more and more <a href="http://creators.ning.com/page/product-roadmap" target="_blank">features</a> being offered to our Network Creators, we need to be able to get quick feedback from our products and systems: if a deployment introduces an overall page rendering slowdown across Ning networks for instance, we want to know about it in a matter of minutes, not hours.</p>
<p>Our platform is instrumented using our open-source <a href="http://github.com/pierre/collector/" target="_blank">Thrift collectors</a> which aggregate and dump data into HDFS. A periodic process imports the data from Hadoop to our Data Warehouse (Netezza), and we’ve built a variety of dashboards to visualize trends over time.</p>
<p>Historically, this pipeline had about an hour of delay, meaning that our dashboards were usually an hour stale. The reason is twofold. First of all, collectors are configured to buffer events locally, in order to create larger files in HDFS (we don’t use file append): larger files means less bookkeeping needed by the namenode. Second, the event loader from HDFS to Netezza is scheduled to run on an hourly basis.</p>
<p>To understand this second point, let’s recall how the collector writes events to HDFS. When events are written to Hadoop, the final path name is determined by the timestamp when the event was fired: each of our Thrift event has an <strong>eventDate</strong> property, either set by the client sending the message, or automatically generated by the receiving collector. For instance, if an event was fired at 11:52:12am on 01/12/11, it will end up in <em>/events/&lt;MyEvent&gt;/2011/01/12/11/&lt;some unique name&gt;.thrift</em>.</p>
<p>Back to the Netezza loader, we implemented it as follow: it gets a list of files from HDFS, reads it (and decode it from Thrift), and pipes it into <strong>nzload</strong> – Netezza’s standard import tool. These decoded events end up in a stage table during the import process, and are atomically loaded into our production tables when all files have been read.</p>
<p>The tricky part here is to avoid loading duplicates. Two events can be exactly the same but not necessarily be duplicates. How do you detect it? One way would be to do some bookkeeping on the file names that have been processed. Unfortunately, this is tricky as external processes may be modifying these files: for instance, we have a combiner script, that runs on a daily basis and look for small files to combine into larger ones.<br />
One easy way to go around this problem is to load only complete hours (e.g. <em>/events/&lt;MyEvent&gt;/2011/01/12/11</em>), as you are guaranteed (assuming you take into account any other delay in the platform) that no new files are added to this directory after 12:00 or so (we give a bit of room for miscellaneous delays and retries).</p>
<p>In such a world, how can we reuse this pipeline for a more real-time feed? One option is to use the ActiveMQ hook that the collectors have. Unfortunately, our internal customers want to use Netezza, as our BI infrastructure is already hooked into it.<br />
We came up with solution by optimizing the current pipeline piece by piece.</p>
<p>First, we created a new pool of real-time collectors which buffer events locally for a very short period of time. We configured the threshold to be one minute, meaning that the events will sit locally on the disk for at most 60 seconds. On the client side, we use the open-source <a href="http://github.com/pierre/eventtracker" target="_blank">eventtracker library</a> (which shares the same persistent queue library under the hood) and configured it to send events asynchronously every 60 seconds as well. With such a configuration, events end up in HDFS at most two minutes after they have been fired. In practice, we’ve seen a shorter delay on average.</p>
<p>The image below is a screenshot from the <a href="http://github.com/pierre/action-core" target="”_blank”">action-core</a>, our open-source HDFS browser. It displays one event, with 21 fields, the first one being the date when the event was fired. The file name indicates when the file was written to HDFS: 01:48:21. The total delay is about 27 seconds.</p>
<div id="attachment_160" class="wp-caption aligncenter" style="width: 543px"><a href="http://pub.mouraf.org/blog/wp-content/uploads/2011/01/delayToHDFS.png"><img class="size-full wp-image-160  " src="http://pub.mouraf.org/blog/wp-content/uploads/2011/01/delayToHDFS.png" alt="" width="533" height="239" /></a><p class="wp-caption-text">Browsing events via the action-core</p></div>
<p>Second, we had to optimize the Netezza loader. We kept the same approach by working on hours, but instead of waiting for an hour to complete, we load the current hour every three minutes in a stage table. A transaction will then delete every event in the current hour in the production table and will then load the stage. This loading step takes about two minutes.<br />
This works (and is fast) for relatively low volume events feeds. It wouldn’t work for other feeds we have that generate a few hundred million events a day, as deletes in Netezza are slow.<br />
A potential optimization would be to use Netezza materialized views, which combine old and fresh data in an optimized way. We are currently investigating it, in order to generalize this approach to larger feeds.</p>
<p>The screenshot below shows a query to Netezza. The <strong>eventDate</strong> field in the event maps to an <strong>event_date</strong> column.</p>
<div id="attachment_161" class="wp-caption aligncenter" style="width: 571px"><a href="http://pub.mouraf.org/blog/wp-content/uploads/2011/01/delayNetezza.png"><img class="size-full wp-image-161  " src="http://pub.mouraf.org/blog/wp-content/uploads/2011/01/delayNetezza.png" alt="Netezza query" width="561" height="50" /></a><p class="wp-caption-text">Netezza query showing the latest event</p></div>
<p>Finally, we use Tableau as our visualization tool. Tableau can issue live queries directly to Netezza to fetch the latest records. The query is blazingly fast, as we leverage Netezza zonemaps (the dashboard issues queries bounded by timestamps) to stream only a few blocks out of the disk.</p>
<p>The result of these optimizations: a feed of events which is about 3-7 minutes stale. That’s of course only the beginning, and we are actively working on further improving this process, as Ning is growing fast, and the Analytics team needs to accommodate more and more requests from our internal and external customers.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/KJfiNdmDkubGzum3U-d15LPrsPE/0/da"><img src="http://feedads.g.doubleclick.net/~a/KJfiNdmDkubGzum3U-d15LPrsPE/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/KJfiNdmDkubGzum3U-d15LPrsPE/1/da"><img src="http://feedads.g.doubleclick.net/~a/KJfiNdmDkubGzum3U-d15LPrsPE/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=AcdRusM2Uvs:B6qSR54N_CU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=AcdRusM2Uvs:B6qSR54N_CU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=AcdRusM2Uvs:B6qSR54N_CU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?i=AcdRusM2Uvs:B6qSR54N_CU:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Movw0x1f010xb8000Hlt/~4/AcdRusM2Uvs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pub.mouraf.org/blog/2011/02/low-latency-analytics-at-ning/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://pub.mouraf.org/blog/2011/02/low-latency-analytics-at-ning/</feedburner:origLink></item>
		<item>
		<title>maven: fix for ClassCastException with Javadoc plugin</title>
		<link>http://feedproxy.google.com/~r/Movw0x1f010xb8000Hlt/~3/TKMJkDgGaE4/</link>
		<comments>http://pub.mouraf.org/blog/2010/11/maven-fix-for-classcastexception-with-javadoc-plugin/#comments</comments>
		<pubDate>Mon, 15 Nov 2010 15:09:33 +0000</pubDate>
		<dc:creator>pierre</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://pub.mouraf.org/blog/?p=358</guid>
		<description><![CDATA[If the Javadoc plugin triggers a java.lang.ClassCastException when running the maven site plugin, you&#8217;re likely to hit http://jira.codehaus.org/browse/MSITE-432. In a nutshell, the Javadoc command line isn&#8217;t populated properly when run as part of the site reports generation. test-jar dependencies are to blame. If you depend on artifact A:jar and A:test-jar, the former is not added [...]]]></description>
			<content:encoded><![CDATA[<p>If the Javadoc plugin triggers a java.lang.ClassCastException when running the maven site plugin, you&#8217;re likely to hit <a href="http://jira.codehaus.org/browse/MSITE-432" target="_blank">http://jira.codehaus.org/browse/MSITE-432</a>.</p>
<p>In a nutshell, the Javadoc command line isn&#8217;t populated properly when run as part of the site reports generation. test-jar dependencies are to blame. If you depend on artifact A:jar and A:test-jar, the former is not added to the classpath of Javadoc.</p>
<p>A workaround is to declare test-jar first (to make sources Javadocs work), before the jar dependency, and skip generation of tests Javadocs (since the tests Javadocs will now fail), i.e. transform</p>
<pre class="brush: plain; title: ; notranslate">
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;...&lt;/groupId&gt;
            &lt;artifactId&gt;...&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;...&lt;/groupId&gt;
            &lt;artifactId&gt;...&lt;/artifactId&gt;
            &lt;type&gt;test-jar&lt;/type&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;reporting&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/reporting&gt;
</pre>
<p>into </p>
<pre class="brush: plain; title: ; notranslate">
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;...&lt;/groupId&gt;
            &lt;artifactId&gt;...&lt;/artifactId&gt;
            &lt;type&gt;test-jar&lt;/type&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;...&lt;/groupId&gt;
            &lt;artifactId&gt;...&lt;/artifactId&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;reporting&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-javadoc-plugin&lt;/artifactId&gt;
                &lt;reportSets&gt;
                    &lt;reportSet&gt;
                        &lt;id&gt;html&lt;/id&gt;
                        &lt;reports&gt;
                            &lt;report&gt;javadoc&lt;/report&gt;
                            &lt;!-- No test-javadoc See http://jira.codehaus.org/browse/MSITE-432 --&gt;
                        &lt;/reports&gt;
                    &lt;/reportSet&gt;
                &lt;/reportSets&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/reporting&gt;
</pre>
<p>See the fix implemented for the Dwarf serialization library <a href="http://github.com/pierre/serialization/commit/71557169d91d3ee1a06d60881b5bd9de7832e227#L3R16" target="_blank">here</a>.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/7EcsJb1tsK4EnT9EjLw14ER9nZk/0/da"><img src="http://feedads.g.doubleclick.net/~a/7EcsJb1tsK4EnT9EjLw14ER9nZk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/7EcsJb1tsK4EnT9EjLw14ER9nZk/1/da"><img src="http://feedads.g.doubleclick.net/~a/7EcsJb1tsK4EnT9EjLw14ER9nZk/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=TKMJkDgGaE4:91motL0TjPk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=TKMJkDgGaE4:91motL0TjPk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=TKMJkDgGaE4:91motL0TjPk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?i=TKMJkDgGaE4:91motL0TjPk:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Movw0x1f010xb8000Hlt/~4/TKMJkDgGaE4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pub.mouraf.org/blog/2010/11/maven-fix-for-classcastexception-with-javadoc-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://pub.mouraf.org/blog/2010/11/maven-fix-for-classcastexception-with-javadoc-plugin/</feedburner:origLink></item>
		<item>
		<title>Maven Shade plugin and multimodule project</title>
		<link>http://feedproxy.google.com/~r/Movw0x1f010xb8000Hlt/~3/KFDHF62B8MU/</link>
		<comments>http://pub.mouraf.org/blog/2010/11/maven-shade-plugin-and-multimodule-project/#comments</comments>
		<pubDate>Mon, 08 Nov 2010 15:01:49 +0000</pubDate>
		<dc:creator>pierre</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[shade]]></category>

		<guid isPermaLink="false">http://pub.mouraf.org/blog/?p=347</guid>
		<description><![CDATA[If you add the Maven Shade plugin in the top pom.xml of a multimodule project, mvn deploy will fail in the following way: Nexus is actually complaining that you are trying to upload a 0-byte pom.xml (you&#8217;ll have to resort to Wireshark to debug the issue, as the plugin won&#8217;t be more verbose about the [...]]]></description>
			<content:encoded><![CDATA[<p>If you add the Maven Shade plugin in the top pom.xml of a multimodule project, mvn deploy will fail in the following way:</p>
<pre class="brush: plain; title: ; notranslate">
------------------------------------------------------------------------
[ERROR] BUILD ERROR
------------------------------------------------------------------------
[INFO] Error deploying artifact: Failed to transfer file:

http://mavenrepo/nexus/content/repositories/libs-snapshots-local/com/ning/metrics.serialization/1.0.2-SNAPSHOT/metrics.serialization-1.0.2-20101103.193531-5-jar-with-dependencies.pom.

Return code is: 400
</pre>
<p>Nexus is actually complaining that you are trying to upload a 0-byte pom.xml (you&#8217;ll have to resort to Wireshark to debug the issue, as the plugin won&#8217;t be more verbose about the error).</p>
<p>The problem comes from trying to assemble the final artifact from the parent pom. As mentioned in <a href="http://jira.codehaus.org/browse/MASSEMBLY-420" target="_blank">http://jira.codehaus.org/browse/MASSEMBLY-420</a> (covers the Assembly plugin, but it&#8217;s the same behavior for Shade), this introduces a circular dependency in the build:</p>
<blockquote><p>In a multimodule hierarchy, when a child module declares the parent POM in its &lt;parent/&gt; section, Maven interprets this to mean that the parent project&#8217;s build must be completed before the child build can start. This ensures that the parent project is in its final form by the time the child needs access to its POM information.</p>
<p>In cases where the Assembly Plugin is included as part of that parent project&#8217;s build process, it will execute along with everything else as part of the parent build &#8211; before the child build can start. If the assembly descriptor used in that parent build references module binaries, it effectively expects the child build to be completed before the assembly is processed. This leads to a recursive dependency situation, where the child build depends on the parent build to complete before it can start, while the parent build depends on the presence of child-module artifacts to complete successfully.</p></blockquote>
<p>The solution is to create a dummy maven submodule which depends on all submodules of the project (so it is built last) and which executes the Shade plugin (i.e. move the Shade plugin configuration to a submodule pom.xml, instead of having it in the parent pom).</p>
<p>Checkout the Dwarf serialization library for a practical example: <a href="http://github.com/pierre/serialization/blob/master/pom.xml" target="_blank">parent pom.xml</a>, <a href="http://github.com/pierre/serialization/blob/master/all/pom.xml" target="_blank">dummy module</a>.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/0dCe43wzVIy1ZxqD8WBBsBUw390/0/da"><img src="http://feedads.g.doubleclick.net/~a/0dCe43wzVIy1ZxqD8WBBsBUw390/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/0dCe43wzVIy1ZxqD8WBBsBUw390/1/da"><img src="http://feedads.g.doubleclick.net/~a/0dCe43wzVIy1ZxqD8WBBsBUw390/1/di" border="0" ismap="true"></img></a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=KFDHF62B8MU:gcOHPSGqnzY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=KFDHF62B8MU:gcOHPSGqnzY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?a=KFDHF62B8MU:gcOHPSGqnzY:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Movw0x1f010xb8000Hlt?i=KFDHF62B8MU:gcOHPSGqnzY:gIN9vFwOqvQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Movw0x1f010xb8000Hlt/~4/KFDHF62B8MU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://pub.mouraf.org/blog/2010/11/maven-shade-plugin-and-multimodule-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://pub.mouraf.org/blog/2010/11/maven-shade-plugin-and-multimodule-project/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.371 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-04-07 01:06:27 --><!-- Compression = gzip -->

