Ben Northrop

  Thinking out loud about programming, decisions, philosophy...
...code ownership
Blog   |   Misc   |   CV   |   RSS    

A quick look at Groovy builds with Gant

  April 29th, 2008

I've been looking into Groovy lately, and I'm really impressed. The language is powerful but concise, the tool support and documentation seems good and getting better, and the community is growing. The problem is, in an enterprise environment, I have no idea where it actually fits in. I don't think it makes sense using it for any large-scale system, at least for now - weak typing scares me in team environments...and in general it's just too bleading edge. So what else?

Well...I recently read Groovy-powered automated builds with Gant, and I think the case here is strong. Groovy could make a lot of sense as a replacement or complement to Ant. After a few hours of playing around with Groovy, Gant, and AntBuilder, here's my humble assessment.

Advantages

  • Full Ant API available, as well as hooks to Ivy and Maven.
  • Readable, concise language. Much less typing than XML.
  • Native support for conditional logic and looping constructs (i.e. no AntContrib, Jelly).
  • Benefits of OO. Greater opportunities for code reuse, better modularity.
  • Extension easier. Groovy code simpler to write than custom Ant tasks.
  • Learning. Get to tell people you know Groovy! :)

Disadvantages

  • Little documentation or tool support. Seems to be very bleeding edge.
  • Learning curve. Groovy and Gant take time to learn. Must understand closures.
  • Potential maintenance issues if leaving for less tech-savvy developers.

When to Use

  • Complex builds that require non-standard functionality (i.e. Groovy is easier to write than custom Ant Tasks).
  • Environments where people are open to using (and maintaining!) newer technologies.

When *not* to Use

  • Large teams or when other people are going to maintain your build code (and will curse you if they don't know or want to know Groovy).
  • Environments that are apprehensive about new technologies.
  • Deadline pressure or risky projects - just use Ant!

Resources

Hello World - Ant vs. Gant


// Ant
<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="E" default="compile" basedir="." >

<target name="compile" depends="init">
  <mkdir dir="classes/" />
  <javac srcdir="src/" destdir="classes/">
    <classpath>
      <pathelement location="lib/log4j.jar"/>
    </classpath>
  </javac>
  <copy todir="classes/" file="src/log4j.properties" />
</target>

<target name="jar" depends="init, compile" >
  <jar jarfile="lib/e.jar" basedir="classes/" includes="**/**" />
</target>

<target name="clean" depends="init" >
  <delete failonerror="true" dir="classes/"/>
</target>
</project>

// Gant
target (clean: "Clean") {
  Ant.delete(failonerror: false, dir: "classes/")
}

target (compile: "Compile") {
   Ant.mkdir(dir: "classes/")
   def javaCompileClasspath = Ant.path {
     pathelement(location: "lib/log4j.jar")
   }
   Ant.javac(destdir: "classes/", srcdir: "src/",
    classpath: javaCompileClasspath)
   Ant.copy (todir: "classes/",
      file: "src/log4j.properties" )
}

target (jar: "Jar") {
  depends(clean, compile);
  Ant.jar(jarfile: "lib/e.jar",
      basedir: "classes/", includes: "**/**")
} setDefaultTarget(compile)



I am currently living in Pittsburgh, PA, working as a Senior Technical Consultant for Summa, and studying as a part-time graduate student in Philosophy at Carnegie Mellon University. My thoughts here are mostly on software development, but trying to take a few insights from philosophy, psychology, economics, and decision sciences to help us understand better why we do what we do...and how to do it better. I maintain two pet projects: codersCV and PMDReports. Check 'em out!




Got a Comment?

Name:
Website:
Are you human:
Comment:

Comments (20)



WarpedJavaGuy May 29, 2008
To me it's all about abstractions. Interfaces allow you to create abstractions over the domain and model a clean OO design. By programming to interfaces we program to abstractions. The rest is implementation.

Rolfst May 30, 2008
As the warpedJavaGuy said it is about abstractions.
You mustn't let the java interface be the substitute for the Interface Erich Gamma mentioned. There are a lot of other programming languages that doesn't have such a construct.
And yes your arguments are mostly valid when you look at the implementation level (in Java that is). although keep in mind that using concrete classes and proxying them can lead to memory leaks when using tools such as cglib or asm.

Sergey May 30, 2008
I have something to say here (http://seeingfuture.blogspot.com/2008/05/programming-to-interfaces-buy-me.html)

Sakuraba May 30, 2008
Your example-diagram does show the true value of interfaces. I agree that this interface-per-DAO- hing is pretty useless in many cases. But that is not the most compelling case for usage of interfaces.

You need to have an example where an interface acts more like a contract between different logical aspects of code.

The easiest example that comes to my mind is the Iterable interface( http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Iterable.html ). Because e.g. the new foreach loop in java 5 can take any Iterable, you can implement Iterable in your client code and therefore making it possible to use your client class in foreach loops.

Had foreach been written towards a specific implemention - say any Collection class for example - this wonderful scenario would not be possible. Iterable provides a contract in this place, it tells you "if you implement this interface, I can provide functionality for you without knowing any of your details".


THAT IS what interfaces buy you, if they are used in the correct place. Not every DAO needs one though, matter of fact if I ever see a IUserDAO or something like that, I will quit software engineering.


Sakuraba May 30, 2008
Damn.. the first sentence should have been

"Your example-diagram does NOT show the true value of interfaces."

Casper Bang May 30, 2008
While I don't hold back on my criticism of Java, I do think it succeeded in bringing contractual development into the mainstream and generally with a lot of bennefits.

Of course, possibly that hindered other things, like language evolution (look at how much more work we need to do in Java where patterns via interfaces are preferred over practical language features like in C#).

Anthony May 30, 2008
Use of interfaces with IoC can be of great benefit when the requirements clearly state the need to be able to swap out different classes. As an example, building multiple reports with collections of parameters ranging from layout to ranges. Doing it all without interfaces results in a large amount of glue code that is simply nasty to look at. On the other hand, with interfaces and IoC each class now becomes a small pluggable component that swaps in and out with a quick edit of a text file.

I'm not sure I like the idea of relying on my IDE to provide me information. It's a slippery slope that leads developers to become dependent on the IDE and eventually become useless without it. The thought of C++ developers who can't perform simple actions without a Vistual Studio wizard comes to mind.

However, I also don't believe interface files solves the problem either as you are still forced to munge around through files and directories in search of your target. I think in the end it really comes down to having good documentation both in and out of the code (ie: javadoc and supplemental documentation that tells the newb where to start). With good documentation and a clear high-level overview of the code or library, I don't know to what extent an interface can provide additional information.

I suppose it really comes down to scope and requirements. Some people would argue that you should always code to the interface. I argue that doing so may limit your ability to use the extending class. I'd write more on the issue but I just saw the time and realized I'm late for work!

Giancarlo Frison May 30, 2008
Set proprierties type as interfaces not as implemented classes.
For example set
private Collection strings instead of ArrayList. It would skirt future refactories if you'll inject different implementations than the initial development.
I keep in mind the say "write once" so when i write code, i write straight naked object, unless it appears a sort of generalization between classes, then gather them toghether and generalize within superclass, abstractclass or interface refactoring as much as possibile, if necessary.

nkijak May 30, 2008
IMHO it's not about expectations since you can't try to expect everything or you'll tear your hair out. It's about leaving something where you can tweak as much stuff as possible with as little impact as possible in the future. This could be days, months or years (although with days maybe you're just doing it wrong from the start)
I just had a project where I had to replace the FTP implementation because it was very old code and it didn't meet all the requirements for the new FTP server. I was hoping that it would be a simple replacement but since there was no interface (and why would you think to use one on something as old and developed as FTP) all the code was tied to this implementation. It required many, many changes and partial rewrites to switch over. I assure you we now have a FTP package that uses a common interface for all future work.
So my point is that you never know what you'll need to replace. Yes, when you have one implementation of the interface now it seems like a waste but you just might need that interface when something unexpected comes up.

bobmanc May 30, 2008
I don't think Ben is saying that interfaces are bad. They are obviously very useful in many situations. The question is should you ALWAYS program to an interface.

raveman May 30, 2008
I think many of you are missing the point. author DOESNT say "lets remove List and Collection and all interfaces!! i hate interfaces!! last time i saw interface i killed it with a hammer!!", but he DOES say "lets remove dao interfaces, because they are useless".

I must admit that it is the most painfull thing in java, i saw few places when dao interface has many implementations, but i dont think it was more than 0,0001% of it(i mean at work when we do only db stuff, i use many dao impls in my home made apps).

I think good example of it will be if you would like to create class representing Cat that will print out "miau" message. Do we need Cat, Animal, Talkable interfaces for it? And if we do need them - do we need them now or can we add them when it will be needed?

However i think we all are too brainwash to dump it. I dont see any of big java players backing up the idea that this is USELESS DESIGN. At work we HAVE TO use dao interfaces or we would look weird. its just how its done, dont ask questiona be one of the ants.

However if you are doing independent projects you can forget about those stupid ideas and extract interfaces at the end of the project. most people cant understand why they are useless, because of Spring and people at Spring have iq like 500 and are always right(i think they have patent for it).

raveman May 30, 2008
Please can we speak about DAO that everybody is using and not the DAO design pattern? I know its hard to admit that most common use of DAO is database access.

DAO <> DAO DESIGN PATTERN !!

raveman May 30, 2008
Please can we speak about DAO that everybody is using and not the DAO design pattern? I know its hard to admit that most common use of DAO is database access.

DAO <> DAO DESIGN PATTERN !!

InterfaceDesign May 30, 2008
I have done some projects changing from Mysql to Oracle and Oracle to Mysql(!). However, it's more often you see people replace Drirect JDBC with Hibernate or toplink.

In my company, we always start with Interfaces first. Let's say programmer A works on service layer and programmer B works on DAO layer. A and B would define/write interfaces first and start programming at the same time.

Neil Weber May 30, 2008
I gotta agree with Ben. In my experience, I've never swapped out the Manager implementation. I have only once swapped out the DAO implementation. In that case, we were supporting multiple versions of a vendor product where each version was implemented on a different DB and each version had a slightly different schema. The DAO layer hid these differences. BTW, this was a C# project so it's not about Java.

Personally, I wouldn't care too much about this, except for one thing. In the IDE (VisualStudio 2008 in my case), I can't just navigate to a method via Ctrl-Left-MouseButton-Click. That'll take me to the method declaration in the interface. Instead, I have to remember to Right-MouseButton-Click, select the Find Usages Advanced menu item, make sure the Interfaces checkbox is clicked in the Find Usages popup, and then press OK. I only do that about 100 times on a slow day.

Wanderson Santos June 02, 2008
I didnīt see the RSS subscription. Could anyone help me?

Very good articles, indeed.

Ben Northrop June 02, 2008
Thanks everyone for the comments!

Wanderson Santos - in recent my site redesign, I forgot to put out the RSS link. It should be there now. Please let me know if it doesn't work.

With respect to the article, actually, I kind of wish I had re-do, because my main gripe wasn't as clear as I had hoped. I think, however, the ambiguity of my argument actually fueled more discussion/debate...which is good.

Basically, raveman hit the nail on the head - I wasn't trying to say that interfaces are a bad construct or that abstraction is a silly/useless concept, only that too often we apply the principle of "programming to interfaces" dogmatically - as though it's some religious principle we should never question! De-coupling is great, but only when you expect that those two things, at some point in the future, may not be coupled together. In other words, if there's only ever going to be one implementation to an interface, prefer tight-coupling. It'll be less code, fewer layers of indirection, etc.

Also, I definitely stated the DAO case too weakly/shallowly. In some cases, moves from MySQL to Oracle are obviously justified. However, I still think that this alone shouldn't necessarily compel you write a DAO interface layer. Unless you're developing an actual product (vs. a single deployment), where multiple RDBMS's need to be supported, there will still only be one implementation of the DAOs living within the system at any one time. Sure, right now they're written for MySQL and in 6 months for Oracle, but a SCM can maintain the differences - they don't need to both live in your system.

With respect to moving from a JDBC-type approach to ORM, I've found that a system with JDBC DAOs often has a de-normalized or redundant domain model to compensate for the difficulties in writing JDBC code. Moving to ORM means not just re-writing DAOS, but also refactoring the domain model classes as well, which means the classes the DAOs accept and return will likely be different. Therefore, the ORM DAO interface still differs from the JDBC DAO interface, and again, programming to interfaces at this layer buys little if anything.

Anyway, thanks again for all the feedback! I've enjoyed reading a your blogs as well.

-Ben

Larry Maccherone June 02, 2008
Remember, when the GoF wrote their design patterns book, they were talking about C++. There is no such thing as an interface type in C++. What Gamma means when he says, "program to an interface..." is not "use the interface keyword in java". In fact, the link you provide for the "program to an interface..." quote explains this quite well. In that link he talks about how you can use an abstract base class as an interface. Venners elaborates and Gamma agrees that even the idea of using the highest class up in a deep class hierarchy is consistent with programming to an interface. Gamma then elaborates on what he means to NOT program to an interface.


Bill Venners: How can I write to an implementation?

Erich Gamma: Imagine I define an interface with five methods, and I define an implementation class below that implements these five methods and adds another ten methods. If only the interface is published as API then if you call one of these ten methods you make an internal call. You call a method that is out of contract, which I might break anytime. So it's the difference, as Martin Fowler would say, between public and published. Something can be public, but that doesn't mean you have published it.


A keyword "interface" type in java is only one way to program to an interface. Going back to your example, if you had put the meat directly in CustomerManager and CustomerDAO, you would still be following the principle of "programming to an interface..." as long as you used only those limited method calls that you indicate.

Rajiv Narula March 02, 2009
On moving from a database to another
I once was working for a company which has their own hosted solution and one of the first thing I noticed was they had hard coded references to Weblogic and Oracle specific queries all over.
When I cautiously commented (I was only a week into the company) that - we should avoid such strategy- I was met with the answer we are a hosted solution and free to do what we can
Six months later- the company was bought by another company and we scrambled to get our application work on webshere and host of other databases
My experience is - things happen.
If you are writing a tic-toe program for your son- go ahead and call new
If you are wring a more serious enterprise application- a true of a good software application is - it will undergo lots of changes

On pluggable DAO Impls
On another project - I saw the DAO layer implemented in JDBC being replaced by DAO implemented in hibernate
What made it more painful than it had to be was that the clients of the existing DAO classes were bound to the super classes that the JDBC DAO classes Had we contracted with the DAO implementation y interface- we could have all slept longer.

My two cents...

Harsha September 01, 2009
our enterprise application is plagued with interfaces. Every class has an interface defined. But there are few instances where we do alternate implementation. For me, this has become more of a liability than the help. I know interfaces are great and they are there for a reason but using them everywhere just to use it is a overkill. Code reading is difficult because you dont know which implementation gets created (in my case) always the same implementation. Visual Studio takes you to the interface file instead of the implemention file so you are always lost in your own code.

We usually take anything good to the extreme and it really starts to hurt us after that.

I totally agree with the author in this regard.

Harsha