views:

864

answers:

6

I've grown disillusioned with Groovy based alternatives to Ant. AntBuilder doesn't work from within Eclipse, the Groovy plugin for Eclipse is disappointing, and Gradle just isn't ready yet.

The Ant documentation has a section titled "Using Ant Tasks Outside of Ant" which gives a teaser for how to use the Ant libraries from Java code. There's another example here:

http://www.mail-archive.com/[email protected]/msg16310.html

In theory it seems simple enough to replace build.xml with Build.java. The Ant documentation hints at some undocumented dependencies that I'll have to discover (undocumented from the point of view of using Ant from within Java).

Given the level of disappointment with Ant scripting, I wonder why this hasn't been done before. Perhaps it has and isn't a good build system.

Has anyone tried writing build files in Java using the Ant libraries?

A: 

While I suppose its possible, you would probably be better off with shell scripts then writing a full on java program to simply automate builds.

You would be missing out on one of the key uses for ant, which are the easy-to-specify filesets and easy to read in properties.

I have stuck with ant as Groovy is too close to writing an entire application to just build your real application. Too complicated for the trouble.

Mike Miller
Sometimes Ant build.xml files do become a sub-project of their own. Builds can be complicated, too complicated for xml.
Dean Schulze
+2  A: 

Given that Java is compiled, this is kind of a chicken and egg problem. You need to build your Build.java to build your project.

Ant currently supports inline scripting using BeanShell, Groovy and a bunch of others, that can really help reduce the need for that.

EDIT: In response to Dean's multiple comments, if your build consists strictly of a long proceedure, then indeed you don't need ant's build script. However, the power of the build script is that it ensures that dependencies are only executed once while allowing for mulitiple entry points, something that is far from trivial if you roll your own.

If you don't like the XML format, you are not alone, the author of ANT agrees with you. However, if your view of the build process is something that can be launched from your IDE as its only launch point, I would say that your build needs are quite simple.

EDIT2: I upvoted skaffman's answer because it speaks directly to the question. In the comments we seem to agree that the approach is fine for a procedural build, but would not work for a declarative one, and that you need at least a little ANT xml to get the ball rolling with your Build.java to avoid the chicken and egg problem. That seems to get to the crux of the matter.

Yishai
No chicken and egg problem. Build and execute Build.java from within Eclipse or whatever IDE you use. The Ant <script> task is a half-measure that underscores the inadequacy xml for builds. Why add scripting instead of just replacing the whole inadequate approach?
Dean Schulze
Typically a build script has to run on a build machine, not from your IDE. If you want to go with a different approach, go for a dynamic language. A compiled language isn't an appropriate build platform, IMO.
Yishai
As skaffman points out above I can still use a simple build.xml file to control the execution of Build.java so there will be no dependence on an IDE. My comment about the IDE was for typical development cycle use.Multiple launch points can be handled with the simpler build.xml that controls Build.java. I don't see why it is simpler to control dependencies with xml than it is with Java. The Java and xml both call the underlying Ant tasks.
Dean Schulze
A: 

While using Ant tasks inside Java programs is fairly easy, I probably would stick to Ant build files if I were you. If you're doing some groovy development, if Eclipse doesn't do what you need, maybe you need to look elsewhere(IntelliJ, NetBeans, etc.).

+2  A: 

You had a fine idea. Cliff Click had a similar idea: http://blogs.azulsystems.com/cliff/2008/01/i-hate-makefile.html

If you go through with it I advise you to keep it as simple as possible so your build system doesn't need a [non-trivial] build system itself.

Ron
There shouldn't be any more Build.java files than there are build.xml files for any given project. In most cases a Build.java at the top level is all there would be. My concept is just using Ant from Java instead of from an xml file.
Dean Schulze
+6  A: 

Our build system is primarily based upon exactly what you describe, and it works very well indeed. We use the Ant tasks (especially the file-manipulation tasks) from custom java programs which assemble the application using auto-discovery of convention-based application module layout.

You may need some glue Ant XML, to do things like compile the build scripts themselves, and to actually invoke the java to perform the build, but it's minor.

Not only is java more readable than Ant, especially when it comes to conditional execution, but it's vastly quicker. Our Ant-based build used to take a minute or so to assemble an EAR, now the java based version takes about 5 seconds.

skaffman
Yes, I could see where using a small Ant script to build and execute the Build.java would be convenient. I could have different targets in the build.xml to pass different arguments to "java Build arg1 arg2 ..." corresponding to the different targets you would have in a larger build.xmlDid you find any undocumented / unexpected dependencies when using Ant from Java i.e. having to have a Project with Target objects?
Dean Schulze
Yes, the Ant tasks do require a certain amount of plumbing, but they're easy to spoof. We ended up creating subclasses of each Ant task that we wanted to use, providing a more convenient and fluid API for the build "scripts" to use, and hiding the mechanics of injecting things like the Project. Nothing that caused us any problems.
skaffman
Sounds great. Do you have any plans to open-source it or at least provide a high level overview of your build system?
Dean Schulze
How do you handle dependencies and ensuring that a given dependency only executes once? For example, if I have a test target and a compile target, and both have a dependency on a prepare target, how do you ensure that when you launch the test, which depends on both compile and prepare, the prepare only gets called once? (I realize the example is trivial, but I hope the underlying point comes through).
Yishai
I don't handle that, because it's not a declarative build like you have with an Ant script, but a procedural program. I tend to find that Ant scripts of any complexity tend to become more and more procedural, and Ant isn't very good at that.As for open-sourcing it, I have thought about it. It's currently quite tightly tied into our specific environment, so I'm not sure how much work would be involved in extracting it.
skaffman
Assuring that any number of dependencies (no matter how complex) execute only once is trivial: use a boolean. I can't think of anything you can do with xml that you can't do better and easier with Java when it comes to controlling the build process.
Dean Schulze
With ant you can force an execution (with antcall) as well as rely on the dependency framework. So that means for every task you call you need a wrapper. I would call that non-trivial.
Yishai
+1  A: 

An important point seems to have gotten lost here.

Ant is written in Java and what I'm looking for is a better way to use the Ant tasks (APIs in the Ant libraries) than through xml. For the life of me I can't see how using xml to invoke Java would ever be better or easier than using Java to invoke Java.

The one obstacle is that the xml approach is documented whereas the Java approach is not documented so I'll have to download and get familiar with the Ant code.

I held back from posting this question for a couple of weeks because I was sure that someone had done this before and that my google-foo just needed improving. It just seems so obvious to use Java to call the Ant APIs instead of xml that I'm still surprised that there wasn't a parallel Java-based approach developed for Ant as well as the xml approach.

Just because it is obvious doesn't mean that someone has done it before, though.

Dean Schulze