Monday, June 29, 2009

Java Dependency Management with Apache Ivy

Not wanting to ditch your already built well working ant scripts for the plugin-centric view of Maven, especially if your project structure doesn't line up quite right with Maven's point of view? Enter Apache Ivy which like Maven can automatically download and resolve all of your dependencies and their dependencies for you with just a few simple lines of XML (if only I could get rid of the XML Part).

Pros

Integrates with Ant, but can still be run standalone.

By default dumps all dependencies into your lib folder which makes it super easy to use with most IDE's.

Works with existing Maven 2 repositories, allowing you to leverage work already done by the Maven community.

Cons

Despite lots of documentation, too much focus on theory with little practical example of how to do simple things. Maybe I'm missing something but I did waste a fair amount of time trying to get a custom 3rd party repository working without crippling the defaults for Ivy. Again I may be just dense, but this was harder for me than either Gradle or Maven to do, and I ran into a couple of hiccups from there.

Limited IDE support compared to say Maven at least in the case of Intellij. Part of this is Maven has some pretty snazzy integration with Maven and I know on more than a couple of occasions I've just started projects with Maven because Intelij makes it super simple and gives me lots of nice integration for adding dependencies with the classic alt+enter .

I decided to include the default scripts I start with. This should get you up and running and give you a template for solving some of the hassle I went through. Just place next to each other in your top level project directory, ivy.xml, ivysettings.xml, and build.xml if you plan on using Ant integration. Also for ant integration make sure you have ivy-2.1.0.jar in "$ANT_HOME/lib" and all should be well. Please ask for clarification on anything, I'll do another post if I get enough questions.

Friday, May 22, 2009

Over at los techies now

I got a wonderful opportunity to blog over at Los Techies . I'm not too worried about losing my independence as I see eye to eye with a lot of that community and its a good place to get my idea's kicked around and adjusted by others experiences.

Thursday, May 21, 2009

Context/Spec style testing and my approach to BDD

I borrow heavily my approach to testing from a combination of Ayende's Rhino Tools tests, and my reading of the Rspec beta book. But I think I've stumbled onto something I'm happy with and I can generate reports out of. Let's go over some basic rules first:

  1. Move as much common setup logic to a base class as possible.
  2. Use your class name as the context
  3. methods are rules beginning with "should"
  4. create a new subclass of the base context every time you have a new scenario
Code ends up looking like so:


public class BaseAddVacationContext
{
protected AddVacationRequest submission;
protected IEmailSender _sender;
protected IUserInformation _information;
protected ICrudRepo<LeaveRequest> _leaverepo;
protected LeaveRequest request;
[SetUp]
public virtual void SetUp()
{
_sender = MockRepository.GenerateMock<IEmailSender>();
_information = MockRepository.GenerateMock<IUserInformation>();
_leaverepo= MockRepository.GenerateMock<ICrudRepo<LeaveRequest>>();
submission = new AddVacationRequest(_sender, _information, _emprepo);
request = new LeaveRequest() { UserName = "james" };


}
}
[TestFixture]
public class SpecAddVacationRequestWhenHappyPathOccurs : BaseAddVacationContext
{


[SetUp]
public override void SetUp()
{
base.SetUp();
_information.Stub(x => x.GetManagersEmailAddresses("james")).Return(new[]{"jacob@jonbank.com", "johnny@jonbank.com"});
_information.Stub(x => x.GetUserEmail("james")).Return("james@jonbank.com");
submission.Execute(request);

}
[Test]
public void should_email_all_managers()
{
_sender.AssertWasCalled(x => x.Send(Arg
<Message>.Matches(y => y.To == "jacob@jonbank.com")));
_sender.AssertWasCalled(x=>x.Send(Arg
<Message>.Matches(y=>y.To =="johnny@jonbank.com")));
}

[Test]
public void should_send_email_to_user()
{
_sender.AssertWasCalled(x => x.Send(Arg
<Message>.Matches(y => y.To == "james@jonbank.com")));
}

[Test]
public void should_store_leave_request_in_database()
{
_emprepo.AssertWasCalled(x=>x.Create(Arg
<LeaveRequest>.Matches(u=>u == request)));
}
}



So here we have:
  • A setup that you need to override and call to setup context specific behavior
  • small small tests and asserts.
  • limited setup on mocks, you can use handrolled mocks or the real classes if you prefer (which I do often).
  • Use AssertWasCalled instead of .Expect() on my mocks
I'll post more examples of this as they come up.

Monorail ActiveRecord and NHibernate

Ran into this at work yesterday and wanted to save others some aggravation:

Scenario: Need To query a value on a page repeatedly. Another 3rd party program is modifying the data you are querying. (in my case to generate new account numbers, could be anything)

Bad Result: 3rd Party Program changes data in background your page does not update the new value.

So my ActiveRecord query before looked something like so:


ActiveRecordMediator.FindAll(Restrictions//you don't really care do you)


now instead grab the underlying session object:


ISession session =ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(DpAcct))
var query = session.CreateQuery(//again you dont care)
var list = query.List()
session.Close()


This may not be the best way and my Nhibernate knowledge is rudimentary once you start getting into Sessions, Scopes and Flushing, but it worked to get an ActiveRecord user by.

It seems the cache doesn't know when to refresh when a third party application is involved. This is logical as the caching would be more expensive if it did.

Typemock Isolater and ASP.net Bundle -FREE

Pretty obvious marketing, but this is an awesome deal so I wanted you my readers in on it too. What kind of irresponsible blogger would I be? So without further ado:

Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.

Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.

The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.

Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.

The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.

Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.

Go ahead, click the following link for more information on how to get your free license.

Sunday, April 26, 2009

Hudson, NDepend and OSS - The Good, The Bad, and The Useful

Patrick Smacchia was kind enough to give me a copy of NDepend so I could give it a good test drive. While we do use NDepend at work, we primarily use it for finding low hanging fruit for refactoring with our legacy software. I decided this would be a wonderful opportunity to see what NDepends story is with OSS and CI.

To facilitate this demo, I used my fresh new BDD Framework Specmaker and Hudson CI server. Normally for CI at work I'd include a copy of whatever software I need in the actual source tree to make it easy to deploy. Obviously, since NDepend is a commercial product and Specmaker is Apache 2.0 license and hosted on Google Code, this was not a viable approach.

So I did the following:

  1. Installed Ndepend on my CI Server
  2. Created a directory to store results
  3. Created a VisualNDepend project. To be able to find my dlls I had to edit the NDependProject.xml file by hand to point to the correct locations. I'd like some nant style Fileset matching instead here. Makes it feel very much like MSBuild.
  4. Setup 2 batch command steps in my build process to run AFTER my normal nant build (seen below, click to view closely) that called ndepend.console.exe and then copied the results to my build folder so they could be archived by Hudson.
  5. Setup the archival rules for my build to grab all of the results that I'd copied to "build\NDependOut" so I could easily reference them after a successful build.



This took quite a bit of fiddling to get working my primary issues were related to Hudson's NAnt plugin (if you reference two nant calls, the first one ends up overwriting your second one so you just do step 1 twice). However once, I got it working my reward was the scolding finger of NDepend. Apparently I have a class teetering on the verge of Cyclomatic Complexity limits (SpecDescription), looks like I have some review to work out some kinks.

Overall Review

  • The Good - Nice UI for Visual NDepend, GOBS of information, CQL is really well thoughtout dsl for finding what you want so far.
  • The Bad - Hard Referencing dlls in xml is bad, rule matching is badly needed here. Causes friction when setting up the project for automation. Custom Nant Task it comes with is very limited according to included documents.
  • The Useful - when combined with CI the comparitive analysis is brilliant. This lets you catch when codebases are declining in quality in an automated fashion. See here for one such example.
Final words, I have to be honest here, I had fallen out of love with NDepend largely, finding it mostly useful only when initially touching a codebase, or when I was first learning SOLID principles. This was of course amazingly useful to my growth, and refactoring efforts, but I was finding less and less need for it with new projects. Looking over Patrick's blog at some of the examples he's come up with using CQL I do not think I've come close to tapping the usefulness possible with this tool. I'll be working more and more towards bending the tool to keep existing codebases in check, and will definitely be using it at home on my OSS work.

Friday, April 10, 2009

Deployment automation and adventures in stupid

At work we currently do not have a ton of order to software releases and requests. I've worked hard to try to bring more there but it's just not part of the way things have been done in the past and that type of change in particular takes a lot of work and persuasion.
Summary we're better than we were but we're not perfect yet.

I have a confession to make...I was being a hypocrite yesterday. I've been preaching since shortly after I got there "you can automate deployment", "manual deployment is error prone and slow", "integrate regularly, release often". With my background as a sysadmin it didn't take me long to get every at least newer software release auto deployed in some fashion or another. The other push was towards not implementing software in chunks but slowly in front to back layers.

However, about a month and a half ago, me and my co-worker were making changes that would require us to change two products at once. I had stupidly gone off on an unecessarily bold refactoring to modularity of one of those products...so I just let things fall behind and stopped pushing frequent releases.

Month and a half goes by and now the trunk has :
  1. a TON of changes to a variety of processes. Including fixes to things that were major current maintenance time sinks
  2. I had not yet successfully moved all my unit tests around to the different modules so I had managed to eliminate my hard won safety net.
  3. Several database changes that I haven't scripted.
  4. Worst of all code that was behind schedule that had been done for 4 weeks.
So yesterday I finally have had enough of excuses why I wasn't pushing this build out. I manually do everything I had not yet had time to automate, and without all my tests in the proper location!

Finding several stupid kinks, multiple bonehead "I forgot" things, and 15 hours later (with only two hours of sleep) with a process that was supposed to take 30 seconds I had both products released.

I'm quite happy to say now I have an in sync code base, and a big list of fixes to implement which I will release one at a time!

Release Frequently, do not push off things till later, and do things in small small layers.

Monday, March 23, 2009

Update

It's been awhile since I added anything, but I want to update myself or any future readers on what I've actually been doing with myself the past month.

  1. Got a commiter to Pinsor in Carlos Ble. Very smart fellow and very helpful.
  2. Got plugin support finally worked out for a project at work (but done at home). Will sanitize the code concepts and post here shortly.
  3. Did a presentation of Castle Windsor and IoC at alamocoders that I think went pretty well (need to work on my material and demos a bit, but the talk went well).
  4. Ayende made my head explode with the following post http://ayende.com/Blog/archive/2009/03/20/nhibernate-avoid-identity-generator-when-possible.aspx. Gonna take me a few days to process that one.
  5. Did San Antonio Book Club meet and greet. Was a lot of fun and i think we're going to start working lean into the mix.
Short update I'll try to get more details out of those into another series of posts. I'd like to start putting my windsor material on the blog and hopefully suss out some of the weaker areas.

Saturday, February 28, 2009

Bosses and your approach to Agile

For me the hardest part of Agile by far is getting bosses to understand what it is, why it matters, why what they're doing now is harder than it needs to be, and why what they're doing now is causing the problems they're seeing.

There are a few reasons I've observed and you may or may not run into that I think make this difficult.
  1. Developers tend to talk over "normal" people's heads. I struggle with this and I didn't even own a computer till I was 23, so in theory I should understand the non-technical perspective better. It's just ultimately VERY hard to take a technical and very detailed issue and bring it down to simpler terms and levels.
  2. Bosses that compartmentalize software they buy and software their employees build as entirely different species. If they buy software and it doesn't behave as they expect they'll stop using it, ask for their money back or raise unholy hell. If they spend 50k in man hours for in house work they can sometimes accept it breaking on its very basic designed functionality. I've seen software like that praised because it delivered business value, even if it did so at an excessive unnecessary cost. This ends up you'd think working in our favor, except inevitably when going Agile we have a TON of software to maintain, and none of it is maintainable. This stacks the deck against going agile in so many ways that I'll leave it for a dedicated blog post.
  3. Bosses assume that developers are not able to understand business value. This one has been a huge problem for me. I go out of my way to deliver business value first and foremost, I was a successful manager before I was a software developer. However, generally speaking bosses are correct into thinking this about us a developers, which I'll cover later in another blog post. Needless to say it's blunts our effectiveness at proposing solutions.
  4. Our industry is filled with people that don't deliver what they say. Sometimes it's us just overshooting our goal. Sometimes it's developers who just want to look better than they are and stretch the truth . Finally, sometimes it's people that just are flat out interested in taking the money and running (subtle distinction to others which one of the three types you are). Regardless, some bosses have been burned so much they assume everything is a lie and they've made up their mind when they walk in the room.
  5. Some bosses take a lot of pride in having a big hand in implementation details. Now while this can easily help you once you have agile working if they are interested in helping you produce software that has lots of feedback. However, if your boss is this way, he's probably a former developer in a time far far away, and absolutely convinced about how a software project should be implemented (and assumes that the way they did it then was perfect despite the problems that all projects inevitably have).
There are certainly more, and if anyone wants to share please do. In future blog posts I'll go through these one by one about what problems they cause and hopefully I can work through how to conquer these challenges in the future.

Wednesday, February 18, 2009

"Do I Care" and "It Depends"

Between my time talking to Agile Joe when my bank hired him and Jimmy Bogard in the last Virtual Alt.net meeting, I now have two new guiding principles to most development tasks.

Do I Care?

  • Should you unit test this code? Do I care about that code? Do I care if I change things later and this is not tested?
  • Should I write this Documentation? Do I care about the docs and what they say? Do I care if I can't remember what I did?
  • Should I delete this code? Do I care about it anymore? Does it do anything for me now?
  • Should I follow SOLID principles here? Is the work needed worth it for the payoff?
All of these questions may or may not be yes or no to "Do I Care?". So how do you know if you care or not..this dovetails nicely with "It Depends".

Like it or not one of our primary jobs is too manage tradeoffs. In one case we hamstring ourselves with too much work for little benefit in another we do not do nearly enough "housekeeping work" to make our code manageable.

Full on SOLID on an application you're building for a day and then going to throw away? I'd hope you say "No I Don't Care About SOLID where it causes me more work", an app that will take 2 months to build...if you don't care, make sure it's only the first couple of days and not when it's too late.

Bob Martin focuses on the "last responsible moment" i really always liked that and all but I feel like "Do I Care" maybe appeals in a more plain spoken way. I only follow "good patterns and design" when I start caring, otherwise I fall into the trap of forgetting why i do these things in the first place.

Monday, February 16, 2009

What to work on

Been quite busy with work for a couple of weeks, but as that is winding down a bit. I think I need another oss project to focus on. Pinsor needs one decent rewrite for clarity, and then some basic feature support and it'll need actual usage to warrant more changes.

Been thinking about what I should work on next?
  • Job scheduler ( some reason always loved these kind of projects, and could use pinsor on it)
  • Scrum project manager web app (would have to actually get comfy with pylons/tg/django)
  • BDD framework in either C#, python or start contribing to spectre in boo.

Monday, January 26, 2009

Pinsor Python DI/IoC framework

Well we'll see where this goes, but I finally decided to give back to open source a bit (besides being an advocate and willing trainer for those interested).

Pinsor Google Code Project

There doesn't seem to be much demand for IoC in Python (in fact anger see comments), but there wasn't in the DotNet community for a long time. I believe the trick there was making IoC containers that people wanted to use for their language (read not 4000 lines of xml that you found in Java containers so often back then).

Hopefully, my aim here is to bring auto-dependency resolution and cut down lines of code in an app, everything else that people typically blab on about with IoC/DI is staggeringly less important.

This is an area where I fundamentally disagree with the most users of IoC frameworks who tend to pound DI DI DI and TESTABILTY. Dependency Injection in of itself is a concept that's so bloody simple you can get it in 5 minutes of working with any language if you just accept it (which is by far the hardest part), and not the important part.

The most imporant thing pinsor will aim to bring is less lines of code in moderately complex projects or greater, if it doesn't accomplish that then I'll be the first to delete it and remove it permanently. My focus will therefore be on making sure automatic dependency resolution and convention based configuration are fluid and easy to use.

As I refine the api and get a pythonic configuration DSL up I'll post examples and add to the docs. Till then you may use the unit tests (which are done with a bit of Behavior Driven Development style).

Sunday, January 11, 2009

Developer Professionalism and Chad Myers

Generally speaking I like Chad Myers comments a lot, some of it he has more experience and that leaves me with less material to challenge his ideas, but sometimes he just see's the world the same way I do.

This post is exactly what I've felt for so terribly long, especially the parts about magic, hocus-pocus and charlatans. Its lonnngg past time computing in general move out of the voodoo phase. So here is my advice for aspiring professional developers, technicians and support techs:

Firstly, technology is not to be applied with the same logic as sports teams. Just because someone started liking Windows, Linux, c#, python, oracle, mysql, whatever does not mean that is the only technology in the world and one must support it till their dying day. Things are good/bad on their own merits, and most work in one situation or another, and what was once bad can become good and vice versa.

Let me state this REALLY clearly. Every time you refuse to dive into a technology because "it must be inferior" and you haven't actually tried to get some work done with it, you are hurting YOURSELF.

Secondly, things are not what they seem on initial examination. If you dont know how something works say so! If you don't like something, give it a deeper look and try to use it, talk to those that actually do use it to get work done on a day to day basis.

Thirdly, if something breaks, or acts in a way you didn't expect. Figure out why that is, with analysis and thought. Use the scientific method, only change one variable at a time, and dive deeply until you are satisfied with your findings. Even then don't trust what you've found is gospel.

Finally our job is to serve as tech experts for those that aren't tech experts. This is a delicate job at times, but honesty and building trust is mandatory. Bullcrap solutions/explanations that may fool the customer for a time have a way of sooner or later exposing the bullcrapper as a useless expert to deal with. Regardless, those that give good timely honest solutions and explanations with a touch of humility end up being the ones that everyone relies on.

That's enough soap box for now, but at the end of the day if the industry as a whole acted that way, I'm quite certain we'd have a lot less "awful legacy code", less management interference, and we'd be focusing on delivering business value to customers (and delivering it quickly) instead of geek ego.

Friday, January 2, 2009

Remoting objects (yes I know it's not 2001) without using the MSDN Way

Ok very few people use Remoting Services any more but it's good in a pinch for quick and dirty way of doing distributed applications.

Now when I went to first use Remoting I struggled to make it fully usable as the books I was using (as well as a quick Google and MSDN lookup) had me all using code like so:


// Create an instance of a channel
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel);

// Register as an available service with the name HelloWorld
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(SampleObject),
"HelloWorld",
WellKnownObjectMode.SingleCall );


The above code instantiates (calls: new SampleObject() ) an object to be able to accessed remotely..but it cannot take any arguments in the ctor !!

This ended up causing me no end of grief, because if I wanted to write a remoting test, I was pretty much stuck with whatever "new SampleObject()" initialized. Now I was forced to open up configuration changes via setters!

Eventually I scratched the whole thing when I found out Castle Windsor had a remoting facility and just used that to handle my remoting needs and it works quite well.

Looking through Castle Trunk they use RemotingServices like so:


internal static void Marshal(object instance, ComponentModel model)
{
MarshalByRefObject mbr = (MarshalByRefObject) instance;

if (!Convert.ToBoolean(model.ExtendedProperties["remoting.published"]))
{
string uri = (string) model.ExtendedProperties["remoting.uri"];

// key logic is here
RemotingServices.Marshal(mbr, uri, model.Service);

model.ExtendedProperties["remoting.published"] = true;
}
}




So with RemotingService.Marshal(object, uri ) is the key here it takes an already intialized class and makes it "remote" and available as a service to another client somewhere else. So much more flexible!