<?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>Les Hazlewood</title>
	<atom:link href="http://leshazlewood.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://leshazlewood.com</link>
	<description>Where Les is More</description>
	<lastBuildDate>Wed, 08 Sep 2010 23:35:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>OSGi, Maven, Pax, and web applications</title>
		<link>http://leshazlewood.com/2010/09/08/osgi-maven-pax-and-web-applications/</link>
		<comments>http://leshazlewood.com/2010/09/08/osgi-maven-pax-and-web-applications/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 23:26:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[OSGi]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://leshazlewood.com/?p=71</guid>
		<description><![CDATA[This post is written for developers that are trying to deploy a .war file inside of an OSGi runtime environment.  I experienced a lot of pain along the way to making my solution work, so hopefully this will alleviate any pain that you might have.
The Scenario
This post primarily reflects the environment in which I am [...]]]></description>
			<content:encoded><![CDATA[<p>This post is written for developers that are trying to deploy a .war file inside of an OSGi runtime environment.  I experienced a lot of pain along the way to making my solution work, so hopefully this will alleviate any pain that you might have.</p>
<h2>The Scenario</h2>
<p>This post primarily reflects the environment in which I am writing and deploying my application.  Here are the key points that led me up to my course of action:</p>
<ul>
<li>I use Maven to manage my project.</li>
<li>I already had an existing web application .war that had no 'knowledge' of OSGi.</li>
<li>I knew I would need to 'OSGi-ify' the .war and turn it into a bundle, since this is required by the OSGi 4.2 Enterprise specification</li>
<li>Once I had the new OSGi-compatible .war, I would need to quickly and easily start it up in an OSGi environment to test it.</li>
</ul>
<h2>The Setup</h2>
<p>Based on my above environment/needs, I decided on the following:</p>
<ul>
<li>Because I use maven and I have created plain (non-web) OSGi bundles with the <a title="Maven Bundle Plugin" href="http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html" target="_blank">Maven Bundle Plugin</a> in the past, it would make sense for me to use it again to make my .war into a bundle.</li>
<li>Again, because I use maven, I want to launch my 'OSGi-ified' .war in an OSGi environment directly from maven.  I didn't want to do anything painful like manually copy and install the .war into an OSGi container installed elsewhere.  That would be a pain that would frustrate me and infringe on my productivity.The <a title="Maven Pax Plugin" href="http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/" target="_blank">Maven Pax Plugin</a> looked like it could easily start an OSGi runtime (Felix, Equinox, etc)  as well as provide the additional web support that is required to launch .war files.  So, I decided to give that a go.</li>
</ul>
<h2>The Solution</h2>
<h3>Step 1: Make your .war OSGi-compatible</h3>
<p>This was actually pretty easy, but there were two major problems I encountered along the way that caused me hours of suffering.  May my pain be your salvation! <img src='http://leshazlewood.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Using the <code>maven-bundle-plugin</code>, you essentially tell it to create a <code>MANIFEST.MF</code> file with OSGi entries, and then you tell the <code>maven-war-plugin</code> to use that generated file.  All it takes is adding the following two plugins to your war project's <code>&lt;plugins&gt;</code> section:</p>
<p>[xml]</p>
<plugin>
  <artifactId>maven-war-plugin</artifactId><br />
  <configuration><br />
    <archive><br />
      <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile><br />
    </archive><br />
  </configuration>
</plugin>
<!--<br />
    Enable support for non-bundle packaging types<br />
    See: http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html<br />
--></p>
<plugin>
  <groupId>org.apache.felix</groupId><br />
  <artifactId>maven-bundle-plugin</artifactId><br />
  <extensions>true</extensions><br />
  <executions><br />
    <execution><br />
      <id>bundle-manifest</id></p>
<phase>process-classes</phase>
      <goals><br />
        <goal>manifest</goal><br />
      </goals><br />
      <configuration><br />
        <instructions><br />
          <Bundle-SymbolicName>CHANGEME</Bundle-SymbolicName><br />
          <Export-Package/><br />
          <Import-Package>javax.servlet,javax.servlet.http,javax.servlet.*,javax.servlet.jsp.*,javax.servlet.jsp.jstl.*</Import-Package><br />
          <DynamicImport-Package>javax.*, org.xml.sax, org.xml.sax.*, org.w3c.*</DynamicImport-Package><br />
          <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath><br />
          <Embed-Directory>WEB-INF/lib</Embed-Directory><br />
          <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency><br />
          <Embed-Transitive>true</Embed-Transitive><br />
          <Web-ContextPath>CHANGEME</Web-ContextPath><br />
          <Webapp-Context>CHANGEME</Webapp-Context><br />
        </instructions><br />
      </configuration><br />
    </execution><br />
  </executions><br />
  <configuration><br />
    <supportedProjectTypes><br />
      <supportedProjectType>jar</supportedProjectType><br />
      <supportedProjectType>bundle</supportedProjectType><br />
      <supportedProjectType>war</supportedProjectType><br />
    </supportedProjectTypes><br />
    <instructions><br />
      <!-- ... etc ... --><br />
    </instructions><br />
  </configuration>
</plugin>
[/xml]</p>
<p>Just remember to set the values appropriate to your application, namely those for the <code>&lt;Bundle-SymbolicName&gt;</code> and <code>&lt;Web-ContextPath&gt;</code> and <code>&lt;Webapp-Context&gt;</code> entries (we'll discuss the latter two shortly).</p>
<p>After you've added the plugins and changed the appropriate values, a normal maven build (e.g. <code>mvn package</code> or <code>mvn install</code>) will produce your OSGi-compatible .war!</p>
<p>But what you see is deceptively simple - there are two things that prevented me from deploying successfully for hours.  Make sure you avoid them:</p>
<h4>Manifest Entries: <code>&lt;Web-ContextPath&gt;</code> or <code>&lt;Webapp-Context&gt;</code>?</h4>
<p>Notice the two following lines in the <code>maven-bundle-plugin</code>'s <code>&lt;instructions&gt;</code> element:<br />
[xml]<br />
<Web-ContextPath>CHANGEME</Web-ContextPath><br />
<Webapp-Context>CHANGEME</Webapp-Context><br />
[/xml]<br />
Doesn't that look annoyingly repetitive to you?  Why do we need two?</p>
<p>Well, let's cover what they are.  As you might have guessed by looking at either one individually, they specify the context path under which your web app will be accessible, for example <code>http://localhost:8080/myContextPath</code>.  If you don't specify them, most OSGi web container implementations will default your context path to your .war's <code>Bundle-SymbolicName</code>,  For example, servicing your webapp from <code>http://localhost:8080/com.company.my.bundle.symbolicName</code>.  That's just plain ugly, so you really want to specify them to ensure your urls look sane.  But why are there two entries?</p>
<p>When I originally added the manifest entries, the only one I specified was the <code>&lt;Web-ContextPath&gt;</code> entry.  This is after all the correct Manifest entry as mandated by the OSGi 4.2 Web Applications Specification (Chapter 128 in the OSGi Compendium document).  I read the specification and added that entry accordingly.  All should work fine then, right?</p>
<p>Well, it would have if the Pax Web support used by the <code>maven-pax-plugin</code> used to launch the .war (covered below), was 100% OSGi 4.2 compliant.  It's not.  I sat at my desk for hours, running various tests until 3:30 in the morning, swearing at myself that I couldn't believe I was screwing things up, when all the documentation said it should be right!</p>
<p>Much to my early-morning chagrin, I discovered that the existing Pax Web support (0.7.2 at the time of this writing), does not yet understand the OSGi standard <code>&lt;Web-ContextPath&gt;</code> entry.  There is currently an outstanding <a title="Jira issue" href="http://issues.ops4j.org/browse/PAXWEB-206" target="_blank">Jira issue</a> for them to fix this.  Until that is fixed, we'll need to add both: the OSGi standard one to ensure it works in your standard OSGi deployment environment and the Pax Web-specific <code>&lt;Webapp-Context&gt;</code> one to make Pax happy while you're testing with Maven.  When that Jira issue is fixed, you can remove it and keep the standard one.</p>
<p>But what if you don't want to launch your .war using the <code>maven-pax-plugin</code>?  You can remove the non-standard entry, right?  </p>
<p>Well, not so fast - there are OSGi container distributions, such as <a title="Apache Karaf"  href="http://karaf.apache.org/" _target="_blank">Apache Karaf</a> (which is the Felix OSGi runtime + a lot of nice enterprise features), that use the same exact Pax Web mechanism as their implementation to support .war deployments.  That means if you deploy your .war to Apache Karaf as your production environment, because Karaf uses the same Pax Web mechanisms, the non-standard <code>&lt;Webapp-Context&gt;</code> entry must still be specified.</p>
<p>Its safest to keep both entries and have them both reference a maven property that you can set once to avoid repeating yourself:</p>
<p>[xml]</p>
<properties>
    <web.contextPath>foo</web.contextPath><br />
    ...
</properties>
<p>...<br />
    <instructions><br />
        ...<br />
        <Web-ContextPath>${web.contextPath}</Web-ContextPath><br />
        <Webapp-Context>${web.contextPath}</Webapp-Context><br />
    </instructions><br />
...<br />
[/xml]</p>
<h4>web.xml: use a <code>&lt;welcome-file-list&gt;</code></h4>
<p>Now that we got the Manifest entries out of the way, there's one final issue that caused me grief: welcome files.</p>
<p>My web app has an <code>index.jsp</code> file at the root of the war file.  It is incredibly simple - all it does is redirect the user to a nice 'home' landing page:</p>
<p>[php]<br />
<%@ page session="false" %><br />
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><br />
<%-- Redirect to the home page --%><br />
<c:redirect url="/home/"/><br />
[/php]</p>
<p>Trivial, right?</p>
<p>Well, my <code>web.xml</code> in my pre-OSGi .war did NOT have a <code>&lt;welcome-file-list&gt;</code> entry in it.  Tomcat and Jetty don't care about this - they have a list of sensible defaults.  Because of that, I haven't specified a welcome-file-list in years - I just didn't think about it.</p>
<p>However, the  the OSGi war deployer mechanism I was using (Pax Web's war extender) does require it.  It was not able to handle a request coming in to <code>http://localhost:8080/myapp</code>.  It didn't know to automatically use the <code>http://localhost:8080/myapp/index.jsp</code> file.</p>
<p>This was equally as frustrating as the non-standard Manifest entry discussed above and further contributed to my hours-long "shoot me now, I hate OSGi" session - there were no error messages explaining why the request failed (terribly frustrating).  But I eventually figured it out by going through the arduous process of setting up an entirely separate 'clean room' .war project and trying different things from scratch.</p>
<p>I added the following XML snippet at the bottom of my web.xml file, and all was well again:</p>
<p>[xml]<br />
<web-app ...><br />
    ...<br />
    <welcome-file-list><br />
        <welcome-file>index.jsp</welcome-file><br />
    </welcome-file-list></p>
<p></web-app><br />
[/xml]</p>
<h3>Step 2: Launch your OSGi .war from Maven</h3>
<p>Now that you have an OSGi-compatible .war, ideally you want to be able to launch it and test it immediately.  It would be a major pain to have to build your .war and manually copy it or install it into your OSGi deployment environment (e.g. Apache Karaf, Eclipse Virgo, Apache Geronimo, etc...).  We want instant gratification with no setup!!!</p>
<p>It's the <code>maven-pax-plugin</code> to the rescue! (with the exception of the manifest entry and welcome-file-list complaints above)</p>
<p>Once you've completed both parts of step 1 above, the rest is smooth sailing.  Add the following plugin to your .war project's <code>&lt;plugins&gt;</code> section:</p>
<p>[xml]</p>
<plugin>
    <groupId>org.ops4j</groupId><br />
    <artifactId>maven-pax-plugin</artifactId><br />
    <configuration></p>
<provision>
<param>--platform=felix</param>
<param>--profiles=compendium,web,war</param>
        </provision>
    </configuration>
</plugin>
[/xml]</p>
<p>Notice that the first <code>&lt;param&gt;</code>, <code>--platform=felix</code>,  reflects my personal test environment.  You could specify <code>--platform=equinox</code> to use the Eclipse Equinox OSGi framework instead.  You could also specify other platforms as well.  See the <a href="http://www.ops4j.org/projects/pax/construct/maven-pax-plugin/index.html">maven-pax-plugin</a> and <a title="Pax Runner" href="http://paxrunner.ops4j.org/display/paxrunner/Pax+Runner" target="_blank">Pax Runner</a> documentation for more options.  You'll naturally choose settings that will best reflect your production runtime environment.</p>
<p>The second <code>&lt;param&gt;</code> is what is important for testing .wars.  It specifies Pax Runner profiles that enable .wars to be deployed.  You can add other profiles as necessary, but those three are required for deploying .wars.</p>
<p>To run your web app, just execute the following:</p>
<p><code>mvn install pax:run</code></p>
<p>Super easy!</p>
<h2>Success!</h2>
<p>Once the two issues above were taken care of, and I could launch my new OSGi .war, it was accessible via <code>http://localhost:8080/myapp</code> and everything worked as expected.</p>
<p>But I hope this helps you, weary-eyed OSGi blog-searcher.  Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2010/09/08/osgi-maven-pax-and-web-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Born to Run</title>
		<link>http://leshazlewood.com/2010/04/26/born-to-run/</link>
		<comments>http://leshazlewood.com/2010/04/26/born-to-run/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 17:15:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=58</guid>
		<description><![CDATA[Because I finished reading Cryptonomicon a few days ago, I was looking for the next book I wanted to read on my Kindle.  I downloaded some classics - Swiss Family Robinson, Treasure Island, Count of Monte Cristo - all of which cost me $0.00. But I wanted to read something current as well, so [...]]]></description>
			<content:encoded><![CDATA[<p>Because I finished reading <a href="http://www.amazon.com/gp/product/B001S36X2W?ie=UTF8&#038;tag=leshazlewoodc-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B001S36X2W">Cryptonomicon</a> a few days ago, I was looking for the next book I wanted to read on my <a href="http://www.amazon.com/gp/product/B0015T963C?ie=UTF8&#038;tag=leshazlewoodc-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B0015T963C">Kindle</a>.  I downloaded some classics - Swiss Family Robinson, Treasure Island, Count of Monte Cristo - all of which cost me $0.00. But I wanted to read something current as well, so I browsed through the best-selling Kindle books and came across this one which had a very high user rating relative to many others:</p>
<p><a href="http://www.amazon.com/gp/product/0307266303?ie=UTF8&#038;tag=leshazlewoodc-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0307266303"><img border="0" src="http://ecx.images-amazon.com/images/I/41fpSM7oO2L._SL160_.jpg"/></a></p>
<p>So, I jumped on it - I was curious about the world of super-endurance and wondered if it would inspire me to one day check off "Run a Marathon" from my bucket list.  I bought it and started reading.</p>
<p>I can't put it down!  I'm so fascinated by the Tarahumara tribe - a Mexican tribe, not African like I thought they might be at first glance.  The author was a previous writer for Men's Health and Running World magazine, and provides good backstory for the running-uninitiated like me.  So far so great!</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2010/04/26/born-to-run/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>4.3 Hours of Streaming Flash Video on the Google Phone (Nexus One)</title>
		<link>http://leshazlewood.com/2010/02/26/43-hours-of-streaming-flash-video-on-the-google-phone-nexus-one/</link>
		<comments>http://leshazlewood.com/2010/02/26/43-hours-of-streaming-flash-video-on-the-google-phone-nexus-one/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 01:51:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=57</guid>
		<description><![CDATA[Here's a great (but kinda long) video.
Short story - Apple (as we already knew) was full of shit when they said that Flash couldn't be used on mobile devices, claiming that it would destroy battery life.  But then again, if things were up to Apple, we'd all be stuck using QuickTime Video.  *shudder*.
4.3 [...]]]></description>
			<content:encoded><![CDATA[<p>Here's a great (but kinda long) <a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/elixir/?lang=en">video</a>.</p>
<p>Short story - Apple (as we already knew) was full of shit when they said that Flash couldn't be used on mobile devices, claiming that it would destroy battery life.  But then again, if things were up to Apple, we'd all be stuck using QuickTime Video.  *shudder*.</p>
<p>4.3 hours of streaming video over the web on only battery power is pretty damn good.  The video was demonstrating the Flash 10.1 player, which is still in beta, but it looks like the performance improvements are a big success.</p>
<p>I still don't think we'll see flash on the iPhone in less than a year<br />
- or maybe even 2 (if ever).  Mr. Jobs, this is one area where you're clearly wrong.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2010/02/26/43-hours-of-streaming-flash-video-on-the-google-phone-nexus-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java.net Maven Users Have Hope!</title>
		<link>http://leshazlewood.com/2010/02/25/javanet-maven-users-have-hope/</link>
		<comments>http://leshazlewood.com/2010/02/25/javanet-maven-users-have-hope/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 21:18:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=56</guid>
		<description><![CDATA[It is no stretch to say that Java.net's Maven infrastructure (or lack thereof) is the worst I've encountered in a project hosting environment.
It looks like the boys from Sonatype are willing to help out on this front by offering Maven repository hosting on their own public Nexus instance for any Java.net project that wants it. [...]]]></description>
			<content:encoded><![CDATA[<p>It is no stretch to say that Java.net's Maven infrastructure (or lack thereof) is the worst I've encountered in a project hosting environment.</p>
<p>It looks like the boys from Sonatype are willing to help out on this front by offering Maven repository hosting on their own <a href="http://oss.sonatype.org">public Nexus instance</a> for any Java.net project that wants it.  That's a big benefit to those projects - jump on it!</p>
<p>Read more about their <a href="http://www.sonatype.com/people/2010/02/java-net-maven-repository-rescue-mission-on-march-5th/">rescue mission on March 5th, 2010</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2010/02/25/javanet-maven-users-have-hope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Maven 2 vs Ant+Ivy: Revisited</title>
		<link>http://leshazlewood.com/2010/01/13/maven-2-vs-antivy-revisited/</link>
		<comments>http://leshazlewood.com/2010/01/13/maven-2-vs-antivy-revisited/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 21:59:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=55</guid>
		<description><![CDATA[I've received a lot of hits and discussion concerning my previous post regarding Maven 2 vs Ant+Ivy, and I'm writing a follow up post to clarify some things.
I now firmly believe that Maven 2 is a better build and project management tool than Ant+Ivy.  I was wrong.
Yep, I said it.  I'm man enough [...]]]></description>
			<content:encoded><![CDATA[<p>I've received a lot of hits and discussion concerning my <a href="http://www.leshazlewood.com/?p=44">previous post regarding Maven 2 vs Ant+Ivy</a>, and I'm writing a follow up post to clarify some things.</p>
<p>I now firmly believe that Maven 2 is a better build and project management tool than Ant+Ivy.  I was wrong.</p>
<p>Yep, I said it.  I'm man enough to admit when I've made mistakes and that I've learned from my experiences.  And this is coming from the guy that wrote a (still popular) <a href="http://onjava.com/pub/a/onjava/2005/06/22/modularant.html">On Java article for Ant in the enterprise</a>.</p>
<p>I almost always touted Ant + Ivy as a better solution in all cases compared to Maven 2, citing:</p>
<ul>
<li>Maven 2 has a steep learning curve and is a pain to come up to speed</li>
<li>You can't customize it easily if you just need to get stuff done</li>
<li>It requires installation of a tool other than Ant</li>
<li>It just doesn't work well for very large enterprise projects</li>
</ul>
<p>...<br />
And a few other things.</p>
<p>I tried Maven 2 just for kicks one or two times and ran away screaming, "I don't have the power that Ant gives me!  I can thrash out anything I wanted in Ant, but I can't do this easily in Maven!  It takes longer! Maven sucks!  God I hate Maven!"</p>
<p>Blah, Blah, Blah.  Boy was that an ignorant viewpoint.  The truth was that yes, I had tried maven a few times, but I never actually used it longer than a few days and reverted to my beloved Ant.  I never truly experienced what it was like over a long period of time in a real working development environment, with other developers and other projects.  So I honestly couldn't judge Maven fairly, especially in the environment where Maven really shines - multiple project teams.  Let me explain:</p>
<p>The thing that I loved, and what many others love about Ant is its absolute control.  I can do almost _anything_ I want in Ant.  Same with the newer script-like build systems like <a href="http://www.gradle.org/">Gradle</a>.  It is uber flexible, and I know that if I needed to do something down 'n dirty, I could hash it out in Ant in a couple of minutes.</p>
<p>If you're a control freak, Ant is comforting.  It allows you to hack out whatever you want whenever you want.  But this ability is actually the very thing that makes Ant a poor choice in a team environment.  It makes it a <em>really</em> poor choice in an enterprise environment with multiple teams, and here's why:</p>
<p>Even the most intellegent, super-smart, uber genius-geek that knows <em>everything</em> about Ant will still do things in a way that fits their personal mental model.  Even worse, the same uber genius-geek god-of-all-developers is apt to continually insist that their way is the best way, and that they've worked out all the kinks, and that everyone should use their oh-so-elegant and super slick Ant build setup.</p>
<p>This is something I see all too often across teams and companies.  This mentality actually hurts a team and has a bigger negative impact on multiple teams.  The reality is is that one guy (maybe 2 if you're lucky) is the brains behind the build system.  They're the only one who knows how do things cleanly.  They know the best practices, and their environment, no matter how elegant, is often confusing to many people.  Their mental model is not always the best one for everyone.</p>
<p>So, you end up having this one (or two) nazi-build-master(s) maintaining a bunch of ant scripts, making them more complex over time (breaking them into separate files because it makes sense to them, but harder to trace for everyone else), and getting upset if other people try to modify them.  Then team members that <em>should</em> be allowed to modify the build to meet a new need can't or are afraid to.</p>
<p>In any event, the overall team productivity related to builds and continuous integration often slows to a trickle.  This trickle causes frustration, alienates people and discourages their interest and help, and costs the company money.  It is clearly a bad, bad thing.</p>
<p>Maven remedies this all too common situation and many others.  Once a few developers use the Maven XML structure and understand what those tags do, they can jump from project to project, as business requirements deem necessary and <em>immediately</em> understand another project's build environment.  That means they can build the software and start testing it right away.  This efficiency translates into enhanced developer and team productivity and that means real money saved for the company.</p>
<p> And guess what?  Newer developers hired in to the company that have Maven experience can also jump right in on a project and understand its build environment for the most part.  <em>That</em> is a big benefit.  At my workplace it used to take a new hire almost a week to feel comfortable understanding and building a very large project.  After converting to Maven, new hires are literally up and running in under an hour.</p>
<p>But this efficiency is not just valuable for the company.  It is valuable for developers' sanity.  I am comforted now by knowing that I can jump from projects at work to a few hosted Apache projects to some other 3rd party projects and, if they use Maven, I am right at home and understand exactly what is going on.  I know immediately how to</p>
<ul>
<li>download dependency source code</li>
<li>run tests</li>
<li>generate JavaDoc and other documentation</li>
<li>Start up a test web environment if it is a web product</li>
<li>view a continuous integration environment</li>
<li>see source control repository details</li>
<li>understand how the project is broken up into modules</li>
</ul>
<p>...<br />
and <em>so</em> much more.  That I no longer have to think about these things, things that were very very time consuming when having to manage yourself, even with Ant, is a big load off of my mind.  I just don't want to <em>mess</em> with this stuff anymore.  I want to have it all work, not waste my time, and allow me to have my piece of mind so I can go crazy worrying about other things like deadlines.  That I can get this piece of mind from project to project and team to team when Maven is employed is a real benefit.</p>
<p>And to my previous comments about Maven not working well in very large enterprise projects because of the possibility for a lot of 'one off' custom logic?  That didn't hold.  I'm working with a very large codebase at work that sometimes takes over 30 minutes to build, <em>not including integration tests</em>, and Maven fits the bill beautifully.  Sure, there are those few 'custom' things that we needed done, but we learned to write a Maven plugin or two (as you <em>should</em>) and use them extensively.  Sure, I couldn't thrash out an Ant hack to get what I needed done, but so what - the team understands what these custom plugins do, they are self documenting, and easily maintained and managed in source control by other developers because Maven plugins themselves are fairly conventional and easy to understand once you learn about them.  This goes back to continued efficiency...</p>
<p>Don't get me wrong - there are some gripes I have with Maven, but they're not really a big deal compared to all the benefits we receive.  It is not a silver bullet - nothing is - so you take those few frustrations and set them aside, knowing the alternatives are much more painful.  So maybe I'll call it a bronze bullet? <img src='http://leshazlewood.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>And so, as JSecurity has moved to <a href="http://www.apache.org">Apache</a> and has been renamed to Apache <a href="http://incubator.apache.org/shiro/">Shiro</a>, we too have moved to Maven 2.  We have also moved to Maven 2 at work as well, and we now benefit from some other amazing tools like <a href="http://nexus.sonatype.org/">Nexus</a> that integrate well in a Maven ecosystem.</p>
<p>Overall, life with Maven is good.  I'm glad that I was able to swallow my pride, really give it a chance, and in turn reap the benefits.  I haven't used Ant in over a year since switching, nor have I ever felt the need to go back.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2010/01/13/maven-2-vs-antivy-revisited/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Free as in Speach or Free as in Beer?</title>
		<link>http://leshazlewood.com/2009/12/21/free-as-in-beer/</link>
		<comments>http://leshazlewood.com/2009/12/21/free-as-in-beer/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 19:17:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=54</guid>
		<description><![CDATA[I never understood this line when discussing Open-Source Software.  Richard Stallman attempted to clarify the differences in Open-Source distribution models by saying "Free as in speach, not free as in beer".
"Free as in beer" is meant to signify a gratis, or no-cost (no money) distribution (but it is not necessarily free to do with [...]]]></description>
			<content:encoded><![CDATA[<p>I never understood this line when discussing Open-Source Software.  Richard Stallman attempted to clarify the differences in Open-Source distribution models by saying "Free as in speach, not free as in beer".</p>
<p>"Free as in beer" is meant to signify a gratis, or no-cost (no money) distribution (but it is not necessarily free to do with as you please), while "Free as in speach" is meant to represent freedom of use - with little or no restrictions.</p>
<p>When was the last time you received free beer?</p>
<p>And if you did receive a free beer, couldn't you do with it as you pleased?  Like drink it or maybe even give it to another friend because you know if you drink more, you'll have no cognitive functions left to try and understand what the stupid phrase "Free as in speach, but not free as in beer" means?</p>
<p>I think we shud shtop wif fis analogie.  It surtanly onli cnfsed me mur. Hiccup.</p>
<p>Wikipedia explains it well enough by saying <a href="http://en.wikipedia.org/wiki/Gratis_versus_Libre">Gratis vs Libre</a></p>
<p>See?  Latin <em>is</em> still useful!</p>
<p>Hiccup.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2009/12/21/free-as-in-beer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IntelliJ IDEA Performance : A Big Boost</title>
		<link>http://leshazlewood.com/2009/11/17/intellij-idea-performance-a-big-boost/</link>
		<comments>http://leshazlewood.com/2009/11/17/intellij-idea-performance-a-big-boost/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 03:17:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=53</guid>
		<description><![CDATA[Just jotting down some recommendations from a friend:

Create an EXE4J_JAVA_HOME environment variable that points to your JDK installation (i.e. export EXE4J_JAVA_HOME=$JAVA_HOME).
Delete the &#60;idea install dir&#62;/jre directory
Add the following JVM options to what you may already have in Idea's JVM config (&#60;idea install dir&#62;/bin/idea.exe.vmoptions on Windows):
-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode

]]></description>
			<content:encoded><![CDATA[<p>Just jotting down some recommendations from a friend:</p>
<ol>
<li>Create an <code>EXE4J_JAVA_HOME</code> environment variable that points to your JDK installation (i.e. <code>export EXE4J_JAVA_HOME=$JAVA_HOME</code>).</li>
<li>Delete the &lt;idea install dir&gt;<code>/jre</code> directory</li>
<li>Add the following JVM options to what you may already have in Idea's JVM config (&lt;idea install dir&gt;/bin/idea.exe.vmoptions on Windows):
<p><code>-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode</code></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2009/11/17/intellij-idea-performance-a-big-boost/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux, java.awt.headless and the DISPLAY environment variable</title>
		<link>http://leshazlewood.com/2009/08/26/linux-javaawtheadless-and-the-display-environment-variable/</link>
		<comments>http://leshazlewood.com/2009/08/26/linux-javaawtheadless-and-the-display-environment-variable/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 18:28:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=52</guid>
		<description><![CDATA[Just a quick note to self:
After looking at the JDK source code today, we found that even when setting -Djava.awt.headless=true, if a script executes with the DISPLAY environment variable set, the AWT graphics environment will still use a GraphicsEnvironment representing that DISPLAY.
A major problem with this is if the shell that launched the script that [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick note to self:</p>
<p>After looking at the JDK source code today, we found that even when setting <code>-Djava.awt.headless=true</code>, if a script executes with the <code>DISPLAY</code> environment variable set, the AWT graphics environment will still use a GraphicsEnvironment representing that <code>DISPLAY</code>.</p>
<p>A major problem with this is if the shell that launched the script that started the java process ever executes, the GraphicsEnvironment reflecting the DISPLAY will be removed and any Object instances reflecting that environment would be invalidated or Classes once available will no longer be available. resulting in a NoClassDefFoundException.</p>
<p>Bottom line: on Linux, if setting <code>-Djava.awt.headless=true</code> in a script, ensure that you <code>unset DISPLAY</code> in the script before starting the <code>java</code> process.  It will save some headaches in debugging.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2009/08/26/linux-javaawtheadless-and-the-display-environment-variable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BMW Paddle Shifters</title>
		<link>http://leshazlewood.com/2009/05/27/bmw-paddle-shifters/</link>
		<comments>http://leshazlewood.com/2009/05/27/bmw-paddle-shifters/#comments</comments>
		<pubDate>Wed, 27 May 2009 14:33:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=50</guid>
		<description><![CDATA[A friend of mine recently pointed me to this forum thread, and I'd like to add my thoughts, based on actual long-term experience in driving a 535i with the Steptronic transmission with paddle shifters for over a year.
The BMW's paddle shifters don't work like Ferrari or Formula 1 cars, where the right paddle up-shifts and [...]]]></description>
			<content:encoded><![CDATA[<p>A friend of mine recently pointed me to this <a href="http://www.e90post.com/forums/showthread.php?t=263758">forum thread</a>, and I'd like to add my thoughts, based on actual long-term experience in driving a 535i with the Steptronic transmission with paddle shifters for over a year.</p>
<p>The BMW's paddle shifters don't work like Ferrari or Formula 1 cars, where the right paddle up-shifts and the left paddle down-shifts.  In the BMW, <em>both</em> paddles can both up and down-shift:  when you pull back on either paddle, you up-shift and when you push forward on either paddle, you down-shift.</p>
<p>Therefore, when I received <a href="http://www.flickr.com/photos/lhazlewood/sets/72157602398703086/">my 2008 535i</a> and started using the paddles, I was rather confused and frustrated because the only experience I had with paddle-shifting was playing GranTurismo where paddle-shifting was modeled after Ferrari/Formula 1 - myself never having been fortunate enough to drive a Ferrari or Formula 1 car <img src='http://leshazlewood.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> .  This is what I, and probably a whole generation of game and racing enthusiasts became used to and comfortable with.</p>
<p>However, now that I've been using my paddles for a while, I'm convinced that BMW got it right.  Technically there is no right or wrong on this issue since it is purely preferential, but I think they are "more right".  I think I was, and the majority of other video-gamers-who-drive-sporty-cars are "less right".  I believe BMW broke convention for a better solution relevant to their target audience.</p>
<p>F1 cars can do the right=downshift/left=upshift paradigm because they don't often turn hard corners that requires a tremendous amount of turn in the steering wheel.  Even hair-pin corners don't require much hand deviation around the circle compared to mass-produced vehicles (of course there are tracks where this isn't the case, but it doesn't happen all that often).  That's because the steering mechanisms are far 'tighter' and don't require as much movement.</p>
<p>Contrast this with mass-produced vehicles, where even in precision vehicles like BMWs, the degree in hand movement around the circle is more significant - the steering wheels are much larger than the yoke-style steering wheels of an F1 car, and they are not as 'tight' - there is still significant traversal around a circle.  Your hands have to move much further away from the 'home' position compared to a F1 car.</p>
<p>So, when you're pushing this type of car with more give in the steering wheel around a turn, the left paddle will become the right paddle and vice-versa, depending on how sharp the corner is.</p>
<p>Think about that for a second:  in tight corners at higher speeds, you actually have to move your hands from the home position and situate them around the steering wheel as it moves to corner properly.  If it is a sharp enough corner, you don't <em>want</em> to remember which paddle is the one you're supposed to use.  You should be focusing on cornering and exiting the turn efficiently.</p>
<p>With BMW's paddle design, you can choose whichever paddle the <em>situation</em> deems as most efficient, not your preconception.  This allows you to more easily focus on the road and cornering, rather than where your hands should be for optimal shifting.</p>
<p>So, like I was required to, I ask the many nay-sayers to actually try it for a while and try to ignore your preconceptions of what it should be based on video games or cars that we may never get to drive.  Instead, just trust the BMW engineers, who, except for probably a very small number of readers of this post, know their craft (with a F1 heritage to boot!) far better than we do.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2009/05/27/bmw-paddle-shifters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java Class Naming Conventions</title>
		<link>http://leshazlewood.com/2009/03/03/java-class-naming-conventions/</link>
		<comments>http://leshazlewood.com/2009/03/03/java-class-naming-conventions/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 17:42:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.leshazlewood.com/?p=49</guid>
		<description><![CDATA[Ok, I'm about to go on a rant, because I come across something regularly that really, really, REALLY irritates me:
Whenever you see a class that implements an interface SomeName, and the name of that class is SomeNameImpl.
Guess what folks, EVERY implementation of an interface is an 'Impl'.  If you suffix 'Impl' at the end [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, I'm about to go on a rant, because I come across something regularly that really, really, <em>REALLY</em> irritates me:</p>
<p>Whenever you see a class that implements an interface <em>SomeName</em>, and the name of that class is <em>SomeName</em><strong>Impl</strong>.</p>
<p>Guess what folks, <strong>EVERY</strong> implementation of an interface is an 'Impl'.  If you suffix 'Impl' at the end of your class name, you're being short sighted and portraying a potential lack of understanding of Interface-Driven Design:  that you can have more than one implementation.</p>
<p>What if you ever create a new implementation?  What if, when testing other components, you create a Test<em>SomeName</em> implementation or a Mock<em>SomeName</em> implementation?  Then the <em>SomeName</em>Impl doesn't make much sense anymore, does it?  It could be a cause of confusion as to why you have more than one 'Impl', or, worse, perhaps it might make people think that you should <em>only</em> ever have one 'Impl'.</p>
<p>Instead, if you need a default implementation, and can't yet think of other cases where you might have other implementations, just call it Default<em>SomeName</em>.  Then you're telling the world, "Hey, this is our default implementation of this interface, and if any more ever are needed, we can create them, <em>prefixed</em> with a more meaningful name.".</p>
<p>Yes, I'm an OO naming zealot, but you'd be surprised at how this little change, in conjunction with other 'trivial' changes, make code more readable, easy to understand, and most important, adaptable to change over time.</p>
]]></content:encoded>
			<wfw:commentRss>http://leshazlewood.com/2009/03/03/java-class-naming-conventions/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
