How many lines of Java?


You need to open a web connection to some site and post some binary data from a local file. You need to validate that the site returns data that matches byte for byte the contents of another file stored on your hard drive. You need to return pass or fail depending on whether or not the data matched. Sounds simple enough, right? I’m setting my stop watch… you have 10 minutes to scroll to the comment section below and code the logic in Java… Ready? Go!

What does it look like? (Did you hit the submit button when you were done?) Did you get it right on the first go? No, we don’t have a back-end compiler and test engine on this site so you wouldn’t get a green bar when you hit submit. The point here is to find the bug. You got a bug somewhere in that logic! First ask yourself, what’s it doing with the streams? Are you closing them all properly or leaving them to Roc, the garbage collector? Did you side step all of the try/catch ugliness with the big oogly try/catch generic Exception that squelches your NullPointer issues? That’s a big bug, believe it or not, because it hides the real problems for you and sends you on wild goose chases. (Who chases wild geese anywayz? What happens when you catch one? Is there a prize? Do you become a wild goose in turn with other hungry savages chasing your tail wielding fork and knife?)

The other point is why bother? Look at the code. I bet there’s a lot of bloat, unless you’re reaching out to some 3rd party API or framework. If you are then you get an F for cheating cuz you can’t submit binary jar includes in the comment section which means you stuff won’t run anyway. Here’s a breif snip of the very same requirement using Groovy:

def runTest(url, reqMethod, requestBinFile, responseBinFile) {
    def con = url.openConnection()
    con.requestMethod = reqMethod
    con.doOutput = true
    requestBinFile.withInputStream { input ->
        con.outputStream.withStream { output -> output << input }
    }
    assert HttpURLConnection.HTTP_OK == con.responseCode
    responseBinFile.withInputStream { input-> input.eachByte {theByte -> assert theByte == con.inputStream.read().byteValue()} }
    con.inputStream.close()
}
    try { runTest(new URL("http://myremotesite.com"), "POST", new File(resourceDir, "typicalRequest.bin"), new File(resourceDir, "expectedResponse.bin")) }
    catch(AssertionError e) { return "fail: $e"}
    finally { println "Done!" }
    return "pass"

While there is a dangling close on the input stream the entire thing could be written without explicitly calling to close anything. The magic comes from the callback pattern as you’ll see in this walk through.

But that’s not Java!
Look again. We are using standard Java API objects URL and File.
new URL("http://myremotesite.com")
new File(resourceDir, "typicalRequest.bin")

We just didn’t have to import them. Our variables are untyped and we dropped semi colons because it’s unnecessary.
def con = url.openConnection()
All of our get/set methods become accessible using properties syntax. We also have auxiliary helper methods, more on that below.

Decorated Objects
Groovy comes as the Amaretto creamer in your cup of Java. It decorates standard Java objects with additional capabilities. For example, there’s an execute method added to java.lang.String that turns any string into an instant command line. You can do stuff like:
"cmd /c explorer C:\\myscreenshot.png".execute()
to open up an image on your hard drive. They’ve also added goodies like plus(int days) to the java.sql.Date object. All of the stuff you would normally break out into a util component has been tucked neatly inside the Groovy enhanced Java API.

New Style
If you’re still for looping and switch casing your way through development you need to get with the program. There’s a new style of programming and either ya’ with it or yer’ slackin’! My example shows off the power of closures and call backs. Let’s talk about what they are and the things they bring to the table. Typical programming requires iteration which results in the loop. In tasks like the example above you need to acquire some resource iterate and dispose of the resource. Since Java uses checked exceptions in a lot of it’s low level API calls you’re forced to deal with them at every turn. The actual thing you are trying to accomplish gets lost in a flurry of noise code dealing with the state of indexes or counters, loop constructs and exception handling. With the callback pattern (which is also possible in pure Java) the iteration, state management, and exception handling is dealt with by some object that you call. This object calls back the code that invoked it on each step of iteration. (You can use callbacks for more than just iteration.) You write logic that looks like so:
networkThingIterator.iterateNetworkThings(this);
instead of:

Connection con = null;
try{
   con = networkThing.connectToNetwork();
   int count = con.getCountOfThingsToDealWith();
}
catch(NetworkException e) { /*I dunno what to do here, I never do so...*/}
for(int i = 0; i < count; i++){
   try{ networkThing.doNetworkStuffWith(localVariable); }
   catch(NetWorkException e) {/*I dunno what to do here, I never do so...*/}
}
finally {
   if(null!=con) try{con.close();} catch(Exception e) {/*Ooooh... I'm squelching!!!*/}
}

We do this in plain old Java but we have to implement an interface which many would inline turning the above example to:
networkThingIterator.iterateNetworkThings(new NetworkThingHandler() {
public void handleNetworkThing(NetworkFooBar foo) {
//The innards of your for loop goes here!
}
});

Not too bad but there’s a little bit of noise here. The syntax of Anonymous inner classes mandates you write an entire class definition where all you really want to write is the method to handle the iteration.

Enter closures
With closures you write what looks, works, and smells like a method but can be grabbed hold of like an object. It removes the cruft of anonymous inner classes and adds the ability to pass a method or an action, or a thing to do (i.e. verb) to an object that does callbacks. Our above networkThing iteration would look like:
networkThingIterator.eachNetworkThing( {
//handle network thing here
}//End of closure defitnition
);//end of method call

Back to the example
In our initial Groovy snip we see closures being passed to what looks like magic methods added to the OutputStream and File objects. These withStream methods contain callback logic that opens the stream, passes it to the closure, and closes the stream. We also have another piece of magic in the left shift operator [<<] that pipes or reads the contents of an InputStream to an OutputStream. The net result is code that focuses on the real task of connecting to streams without the noise of try to open, catch exception, blibbidy-blobbidy, try to close. Look closer. There’s another call back decorated onto InputStream that performs iteration on eachByte and passes it to the given closure. It’s named eachByte. Self explanatory enough? I’d write more but I’ve become way to verbose on the topic so hit me up with any finer details or points of interest.

IIOException can’t create cache file


Tomcat + ImageIO

What do you get? Trouble! Who would guess that doing PNG conversion with JDK APIs requires you to have a temp folder off of $CATALINA_BASE? After being labeled the build master unofficially, I took the initiative (if you can call totally screwing up a quasi-production deployment initiative) to prune what looked like cruft from a template tarball. Among this cruft was our precious temp folder. Let me explain better.

We use a deployment template for production builds. You know how this stuff goes when one developer gets something working and management says something like, “can you make yours work like his?” Thus begins the binary hand-off. A binary archive of the stuff he did bequeathed unto you to bring identical magic to your project. You then hand it down to the next developer that needs to do something similar. And so on and so forth. The entire idea is crazy but it’s the stuff major companies run on. by the time it gets handed to the 5th or 12th person down the line nobody remembers or understands anything from the original project only that this thing is what’s supposed to make everything else work just like it.

So I get this tarball, and I’ve got plenty others that look sorta like it that I tried creating from scratch. Some of mine half work while others just flop. I loose track because all correspondences with the deployment team and myself happens in a loosely coupled chain of random emails and secure copies to locked down servers that I have no business touching. I finally get something working that I can actually automate but I feel dirty because this binary template is checked into our version control system. So I begin cleaning the cruft, extracting the true thing that our project needs… structure not binary data. Everything begins to work. Everything except for a few execution paths that I have not had time to QA due to my tight schedule. I ask for QA from the QA team but I’ve been so tied up in performance tests that I can’t let the team anywhere near the deployment. I find other issues due to my not following certain design patterns. I fix issues. But the entire thing takes sooo much effort because I work in a highly secured environment. I work with one guy that’s been a blessing giving me higher than usual access rights as if I truly knew what I was doing on a Linux box. (Wasn’t I losing my Linux touch just days ago?)

The end of my plight is today. After hitting the “IIOException can’t create cache file” thing I Googled and found some info hinting to some more detailed discussion that only hints that you need a temp folder configured for Tomcat. I examined the startup script and plugged in the missing temp folder and voila! Everything worked as it should.

Moral to story
If you get: IIOException: can’t create cache file!
And you’re running in Tomcat
Then you need to make sure $CATALINA_BASE/temp actually exists and is writable.

By default Tomcat’s startup scripts set java.io.tmpdir to $CATALINA_BASE/temp but this could be overriden by a number of different ways. It is the java.io.tmpdir that is used by ImageIO and possibly numerous of other 3rd party APIs and open source components for cache files and other temporary stuff.

Get’cha Groove On


I’ve been slowly getting back into my Groovy state of mind after immersing in Maven2, Servlets, and J2ME for over a year. If you’re one of those people who can’t stand yet another programming language then this topic is for you. If you’re one of those who think “My language grammar suites me just fine” then step off! I ain’t even tryin’ to holler at you. If you’re one of those people who don’t understand why a language is so important than allow me to elaborate.

Modern languages are about high level expressiveness, getting things done by mirroring the thought more closely which requires less specific steps. For instance: The loop has been done many times over. We don’t want to think loop until I get my desired result. in my variable which is a value equal to the number of files in a directory. We want to express that we are taking some action on each file in a folder. Older style languages pay little if any attention to the need to express the thought of a developer. Rather they organize the mechanics of the syntax to allow re-use of common constructs. if/select/while constructs are being replaced with closures. Code generation and reflection are giving way to Meta Object Protocols. The new thing in town is DSL, which focuses on how easy it is to express the intent of the logic by massaging and bending the syntax of the language.

That said, you can probably tell that I’m going to speak about Groovy for a minute. If you don’t want to learn another language then Groovy is perfect for you! You most likely already know it. Take the following snip for example:

import java.io.File;
import java.util.*;

public List getNamesOfMusicInFolder(File folder) {
   List names = new ArrayList();
   File files = folder.listFiles();
   for(int i = 0; i < files.length(); i++)
      if(files&#91;i&#93;.getName().toLowerCase().endsWith(".mp3")) names.add(files&#91;i&#93;.getName());
   return names;
}
&#91;/sourcecode&#93;

If you can write or figure out code like that then you're already a Groovy programmer. Expert points if you happen to know the Java API. Now why is that so interesting? Because we can groove it up by doing Ruby like stuff with the same familiar programming constructs, APIs and platform that we've been using for years. Start by removing semi colons, Variable declararations and import statements because Groovy makes them unnecessary. 

&#91;sourcecode language="java"&#93;
def getNamesOfMusicInFolder(folder) {
   def names = new ArrayList()
   def files = folder.listFiles()
   for(int i = 0; i < files.length; i++)
      if(files&#91;i&#93;.getName().toLowerCase().endsWith(".mp3")) names.add(files&#91;i&#93;.getName())
   return names
}
&#91;/sourcecode&#93;

Now let's pretend getter and setter methods are properties, because Groovy doesn't care about the difference. And while we're at it we'll use the left shift operator which also doubles as an append operator:

&#91;sourcecode language="java"&#93;
def getNamesOfMusicInFolder(folder) {
   def names = new ArrayList()
   def files = folder.listFiles()
   for(int i = 0; i < files.length(); i++)
      if(file&#91;i&#93;.name.toLowerCase().endsWith(".mp3")) names << file&#91;i&#93;.name
   return names
}
&#91;/sourcecode&#93;

Now use a more modern loop construct:

&#91;sourcecode language="java"&#93;
def getNamesOfMusicInFolder(folder) {
   def names = new ArrayList()
   for(file in folder)
      if(file.name.toLowerCase().endsWith(".mp3")) names << file.name
   return names
}
&#91;/sourcecode&#93;

Wait! Why are we looping at all? Let's pass a closure to the each method. A closure is a chunk of code that the each method executes on each thing:

&#91;sourcecode language="java"&#93;
def getNamesOfMusicInFolder(folder) {
   def names = new ArrayList()
   folder.each( { file -> if(file.name.toLowerCase().endsWith(".mp3")) names << file.name } )
   return names
}
&#91;/sourcecode&#93;

Kinda ugly but remember that parenthisis are optional in Groovy
&#91;sourcecode language="java"&#93;
def getNamesOfMusicInFolder(folder) {
   def names = new ArrayList()
   folder.each { file -> if(file.name.toLowerCase().endsWith(".mp3")) names << file.name } 
   return names
}
&#91;/sourcecode&#93;

And on and on and on, till the break of dawn or at least until we get it down to the beautiful one liner that would cause your average gear head to brag more than <a href="http://tv.yahoo.com/seinfeld/show/the-parking-space/episode/167176">George Castanza grabbing the first parking spot</a>.


new File(dir).listFiles( { dir, file -> file.toLowerCase().endsWith( ".mp3" )  } as FilenameFilter )*.name

What about bindings? Where are the bindings? What are bindings? Bindings are interfaces or APIs that a given platform or framework offers for programmers that use a given language. Groovy is just Java with flava. That means anywhere there’s Java bindings there’s groovy bindings. And since any interface or API can be grooved up that means you can actually modify or add flava to those bindings. More on that in another post.

That’s a small example of what you can do with Groovy. There is a much bigger picture here, the Java platform. Groovy compiles to, runs on, plays well with, the JVM. You don’t need a separate skill set to take advantage of what people from other camps brag about. Java already has several GUI builders, Mattisse being among the best. Java has what I believe is some of the best IDEs ever thought of. (IntelliJ Idea and Eclipse though many complain about Eclipse memory issues.) Java supports presentation engines that regurgitate Flash or AJAX. Java is the king of server deployment simplicity… just plug a spec compliant archive in and go. JVMs are on midranges mainframes, browsers, and mobile devices. (I’m not to crazy about mobile JVMs.) To coin a phrase, “Java is everywhere you wanna be.”

Taking that idea even further, the Groovy camp offers features such as “.Net” interoperability, Windows binaries, and COM scripting that means even on Windows platforms you aren’t that far from native behavior while leveraging the same familiar syntax and VM that uncle Otis grew up with. I could go on forever but I’m gonna take a break now and actually do some Groovy coding. I’ll come back with something we can all admire.

I don’t know what I’m talking about but he does…


Tonight was the open space discussion meeting on technology at MapQuest. I’ve never been to one of these before. I didn’t know how to act. I was one of the facilitators there and as such I was expected to speak intelligently on any technologies, topics of interest to the overall group. I have a crazy love/fear of public speaking. Basically I suck at it. I’m a shy person in general and not a good conversationalist. I suck at conversation. I’m terrible at on the fly thinking but yet I love to thrust myself into situations where I have no choice but to come up with material on the fly because I love being the center of attention but I hate planning. So tonight was another one of those situations, only I did do a fair amount of planning. You can’t plan for the unexpected so whatever planning I thought I did was in vain.

At my company I happen to work with some of the top developers in the state. These are likely the top developers in America and like in top in the world, some of them. Those developers who know their stuff know who they are. We got a lot of great guys who are much better at things like organization, public speaking, and engaging the audience. I wish I were as cool as them. Tonight wasn’t too bad, though. I met an old friend and made some new friends. I spoke as smartly as I couldn’t on things that are still brand new to me. I held my tongue on topics that were considered company hush hush. And I gave an overall marginal speech on Java mobile technology. Of course I focused heavily on software development life cycle which lead into discussion on how we use Maven.

What I’ve learned is that I tend to present too technical to people who would otherwise be interested in the high level ideas above the frameworks. As a gear head (and I am the most hardcore gear head you’ll ever meet, if you ever actually meet me… most of you know me solely from my blabbering on this site) I can’t help but obsess over the nuts and bolts behind the thing that people care most about. but enough about me because I don’t know what I’m talking about. Mobile is still new to me and I learn new things each day.

I want to speak on some cool cats in my company. One guy in particular really had me engaged in another recent developer gathering we had about a week ago. He conducted an open find-the-bug detective thing where we as a group were all invited to go through an exercise of tracking down a thread deadlock condition on a Java server application. (Simplified, a deadlock is when the computer is trying to do “thing A” and “thing B” at the same time but “thing A” is waiting for “thing B” to complete while “thing B” is actually waiting for “thing A”. It’s kinda like those awkward moments on the news where the anchor man starts to speak over the interviewee phoned in over satellite but pauses because of the delay while the interviewee interrupts his speech to let the anchor man finish talking, or even better described in this uncomfortable dance situation.) The concept was brilliant, the presentation was engaging, and the guy really knows his stuff. As a result I want to lay out what I think is essential for a good presentation or tech talk.

Content
Make sure the meat of what you say is applicable, relevant to things your audience deals with or needs to deal with, and full of good information. I screwed this up on a Maven talk I gave where I focused sooo heavily on live demos and pretty slideshows with razzle dazzle that I lost focus of giving out meaningful information.

Forget Razzle Dazzle
It’s cool to have text fly in from the lower left with a slight spiral using PowerPoint or key note but what it takes away from the actual content (see above) actually hurts the overall presentation. Unless your presenting a stellar new UI framework, interior decoration idea, art project, or other visual product where razzle in the key ingredient leave this crap out of your slideshows. Your audience will appreciate it and it will leave you more time to focus on content (see above).

Delivery
I don’t care how chock full of goodness your content is if your delivery suffers (as mine always does due to nervousness caused by not being prepared) then your message wil never get across. Delivery is actually more important than content because even a presentation with no relevant content will be received well and entice return vistors when delivered correctly. Delivery has nothing to do with razzle dazzle and special effects. you can have vanilla all white slides with black text but deliver it in such a way that the audience will swear that you used every eye candy feature in Power Point. Delivery is how you speak to the audience and how well you get them engaged.

Eye contact
Speaks to delivery. If you maintain eye contact with not just one but every member of the audience your message will be well received. Don’t make the mistake I always make of having a friend in the audience and focusing your message to the one person that appears engaged. The rest of the audience will feel ignored and that friend will feel singled out or stared at. If your eyes dance from one audience member to another everyone will feel included even if they aren’t interested.

Listen
As a presenter you have to be able to listen to your audience. Allow questions to interrupt but be careful not to get distracted by too many interim questions. the classic “hold all questions to the end” makes your audience (especially programmers like myself who love to ask what they believe are tough thought-provoking questions but are actually carefully self-crafted to make themselves sound more intelligent than the presenter) feel less a part of the overall presentation. Allow 1-3 interim questions whith brief answers while leaving the full elaboration for the end. Something like, “is it hard to target different types of phones?” can be quickly answered with, “we do face a number of challenges” while continuing with the current topic. At the end you can reflect with, “now someone asked about porting. Here’s some specifics that do do to ease our pain…” that shows both that you considered the questioneer and that you thought their concern was relevant enough to remember at the conclusion.

Fonts And amount of text
Use big and non-fancy fonts in any of your slides. Your audience needs to read your content. Sans serif works best and 24 point should be the smallest unless you have a small room full of people already familiar with the material. Also pay attention that your slides include only general topics and not full stories. Paragraphs are for word processors and people don’t come to your presentation to learn to speed read. The less text you put up the better.

These are tips that apply to any presentation that you give. They are coming from a person who has yet to give what I feel to be an adequate or above average presentation to take it with a grain of salt (and a sip of beer). One of these days I’ll actually follow some of the advice I give to others, but until then you are all stuck being my guinea pigs. Hit me up party people.

Synergy doesn’t forget


I was playing with Synergy the other day. As a matter of fact I dunno if the post ever made it to my front page. Let me go release it… there! It’ll show right under this one. At any rate, I’ve been using Synergy for the past couple of days and I gotta say it’s nice! I love being able to drag my mouse across three screens as if they were one big display. I’m a little disappointed that I can’t drag windows off my Mac onto my Dell but that’s cool. Today I found something slick with Synergy. See, I’m accustom to trying to prevent computer problems by properly closing certain programs and logging off of remote servers at the end of the day. I know all too well how dumb a piece of software gets when you sever a network connection that it’s expecting to be persistent. The guys (and gals? were their any gals?) that created Synergy must have thought about this. I say that because I forgot to kill my Synergy client running on my Mac yesterday. I forgot to kill the server running on my Dell. I ran out in a hurry to try to find the right lever to pull in the Democratic primaries without even considering what potential drama would await me the following day. Completely ignorant of my prior ignorance, I connected my Mac to the office intranet and went on about my business. I thought, “in a few minutes I’ll restart Synergy on my machines but I gotta finish some other stuff first.” Without even realizing it I had dragged my mouse pointer onto my Mac revealing both my forgetfullness from the other day and a pleasant surprise from a development team who never bragged about such a killer feature. There is something to be said about software that just works the way you’d expect without constant tweaking and intervention.

Synergy


Walked in, saw my desk was a mess, realized I have two 19″ flat panel monitors so why aren’t they glued together? I knew I had both monitors. I’d planned it that way ever since I sneaked into the cube of a recently departed co-worker. (I said recently departed, not dearly departed!) One had been welded to my Dell from the start of my MapQuest ventures whil the other had been hanging free on my desk serving as a secondary screen for my Macbook. So the question still was why aren’t the two identical looking monitors serving as a combined 40″ horizontal panel? The first reason was that I’d been told the Macpro doesn’t support dual DVI output. That leads into my second reason which is my preference for OS X and *Nix based systems over Windows. While I’m forced by fire to use Windows to satisfy the powers that created the world of mobile development (apparently every mainstream mobile technology must have been born and raised on Windows) I still use my Mac for most of everything. I even use it to remote into my Dell Windows box and do development.

A buddy at work told me about this thing called Synergy a while back. It’s a software package that lets you share a keyboard between systems. As usual I was arrogant and blew off the idea, because I’d already found a friend in RDC and it seemed to remote Windows better than anything else on the Mac. Why do I now need to consider another remoting solution? Yes my idea was waaaay more John Blaze than his or anyone else’s because RDC was way cool. Be gone random idea contributed from co-worker who was clearly below my level of Mac remoting experience! Who cares if you live and breathe OS X and have worn a hat with the Apple logo since your tender years?

This morning the idea had seeped from the back of my neck into the core of my grey matter as I thought, “wouldn’t it be cool if I could continue to use Windows with the dual screen but remote into my Mac instead?” MyDeskActually I was thinking, “I need to use these monitors side by side so I can bring my IDE up in one monitor and my Mac in the other. What other remoting solutions are available?” Whatever the root cause the end story was my completely re-working the way my desk had been set up and installing Synergy. I’d show the before shot but it looked pitiful and the work is already done. So now I give you the after glow of my efforts. Dual screen display only for windows for now. But notice the 3rd Mac screen off to the left. If I drag my cursor far enough left it falls directly onto the Mac screen and I’m instantly controlling it. It’s a different kind of remoting but it’s off the chains when you get used to it.

Dynamic Language Syntax


It’s late and I’m working on my 2nd Budweiser (16oz cans). I got no business posting some in depth technical artical. But I gotta tell you how easy it is to build a dynamic language with Groovy. Tonight I took literally 10 minutes to build a basic GSpec like example using the ExpandoMetaClass in Groovy 1.5. I know you don’t know what an expando meta class is. Neither do I. I just grabbed the example from the docs on the Groovy site and ran with it.

In this example I’m adding methods at runtime to a BarPatron object. The net result is an oogly behavior test that specifies that if you set a BarPtron’s favorite drink to a value then that value should be what you set it to. No lie, I put this together in 15 minutes after 2 Buds. And it’s now 11:25pm!

class BarPatron {
    def favoriteDrink
}

BarPatron.metaClass.invokeMethod = { String name, args ->
    if(name.toLowerCase().endsWith("shouldbe")) {
        def propertyName = name.substring(0, name.toLowerCase().indexOf("shouldbe"))
        assert args[0] == BarPatron.metaClass.getMetaProperty(propertyName).getProperty(delegate)
        return
    }
    def metaMethod = BarPatron.metaClass.getMetaMethod(name, args)
    def result
    if(metaMethod) result = metaMethod.invoke(delegate,args)
    else {
       result = "bar"
    }
    result
}

obj = new BarPatron()
obj.favoriteDrink = 'Bud Light'
obj.favoriteDrinkShouldBe 'Bud Light'

Now go over here


I did something very generous the a few weeks ago. I took note of how much Neopoleon.com had been suffering in the ratings department (using a highly accurate algorithm written in I think either Java or Groovy) and decided to route all of my incoming traffic to his site. Y’know… gotta help cuz out because his site’s like John Blaze and y’all just ain’t reckognizin’! I tried but for whatever reason my audience was being stubborn and they actually increased visitation to my pages by a whopping 0.5%! So then I was all like, “nah, not here, go over there” to the peoples and I don’t rememberize what actually happened because I stopped looking at my hit counter. I think they went over there. I dunno, I guess I gotta run one of my JUnit program things to do an assertVisitedRorySite() or something.

Today I’d like to make another traffic donation. This time it’s not because this other site is hurting. It’s actually a cool hang out spot. Y’all gotz to peep Astrid on the http://pocketsizedcinematographer.blogspot.com site. I found this spot a while ago reading Rory’s stuff. He was all like, “check out my girl Astrid” in one of his linky things. I hit the spot a few times with the Fox and then I was like, “Yeah I’m feelin’ this”. So head over to Astrid’s for a minute and drop a line. And if you’re into filmy type stuff then check the home page too. She got some John Blaze professional looking clips there.

Get yer deployment on, watch out!


I’m becoming sort of a Mavenvangelist or whaddever-yuh-call-it. Even as such I have to admit the tool has some rough edges. This morning I wanna point out one of these rough-edge-I’m-going-to-get-you things that you might not be aware of or maybe you are. Even if you are read up because it bites even when you do know completely what you’re dealing with. I call it configuration spillage.

In Maven you have this awesome ability to point your build to any repository you wish. The repos can be virtual, chained-together, or whatever crazy idea you can come up with. (I’ve dreamed up a couple of wild ideas here.) The problem here starts with where the repository management ends and where the project management begins. Configuring an internal repository for deployment seems to require entries in both the settings.xml which should be shared across team members and also the project descriptor, pom.xml file. The crazy part that I can never get straight is how the majority of these configs go in the pom file leaving only the most critical piece sitting in the settings.xml file. For example, consider an Artifactory deployment repository. In the pom.xml you put something like this:

    <distributionManagement>
        <repository>
            <id>artifactory-webdav-on-server1</id>
            <url>dav:http://myrepo:8080/artifactory/libs-releases@repo</url>
        </repository>
        <snapshotRepository>
            <id>artifactory-webdav-on-server1</id>
            <url>dav:http://myrepo:8080/artifactory/libs-snapshots@repo</url>
        </snapshotRepository>
    </distributionManagement>

Then you authenticate the deployment repository using these tags in settings.xml:

  <servers>
    <server>
    	<id>artifactory-webdav-on-server1</id>
    	<username>user</username>
    	<password>password</password>
    </server>
  </servers>

This morning I worked on relocating our deployment repository and because I got bit by the split config thing in the past I spent a good twenty minutes trying to identify all of the tricky configuration. It’s hard to put into words but I knew that I needed to update the deployment settings but I couldn’t figure out how the pieces tied together even as I had been down this path before. I got mad work to finish and just wanted to tip anybody out there. If you got a Maven repo setup and you think you got all your pieces in place check again. The other problem you’ll hit is referencing server names in the ids. It feels perfectly natural to add configs with ids like artifactory-webdav-on-server1 and proximity-ssh-on-server2 especially when you’re experimenting with two or more kinds of repos trying to settle on a best fit. but later when you say, “ok we’re going with Archiva” and release both pom.xml and settings files with both Archiva and server names littered everywhere installing new machines, changing DNS names and/or deploying something like Artifactory becomes a pain. A better approach would be to use something like this:

    <distributionManagement>
        <repository>
            <id>artifactory-webdav</id>
            <url>dav:http://myrepo:8080/artifactory/libs-releases@repo</url>
        </repository>
        <snapshotRepository>
            <id>artifactory-webdav</id>
            <url>dav:http://myrepo:8080/artifactory/libs-snapshots@repo</url>
        </snapshotRepository>
    </distributionManagement>

Then you authenticate the deployment repository using these tags in settings.xml:

  <servers>
    <server>
    	<id>artifactory-webdav</id>
    	<username>user</username>
    	<password>password</password>
    </server>
  </servers>

Hit me up people!