Kuro5hin.org: technology and culture, from the trenches
create account | help/FAQ | contact | links | search | IRC | site news
[ Everything | Diaries | Technology | Science | Culture | Politics | Media | News | Internet | Op-Ed | Fiction | Meta | MLP ]
We need your support: buy an ad | premium membership

[P]
Comparing ant and make as Java build tools

By GusherJizmac in Technology
Mon Sep 24, 2001 at 08:44:18 PM EST
Tags: Software (all tags)
Software

Recently, the tool ant has come to the forefront as a build tool for Java. It uses XML build files and contains many built-in commands to make it easy to work with Java code and Java projects. There are extensions to it to simplify developing web-based Java applications with tools like BEA Weblogic. Upon hearing about ant, many developers might first ask "Why not just use make?". This author has extensive experience with make, and with Java development, and the following article attempts to answer this question by offering a comparison of ant and make as build tools, under the assumption that Java applications are being developed. The conlusion drawn is that while ant has some powerful advantages, it is not as easily extensible, nor as flexible as make for most development situations and there isn't a strong argument in favor of using it.


Introduction

When my company first began serious Java application development (in the form of web-based, J2EE applications), my instinct was to create a Makefile system to handle the compilation of Java code, as well as some basic development environment setup procedures. This was done and included in our standard development procedure. Then, a while ago, I began reading about ant, which purported to be a better tool for automating builds in a Java environment. After reading about it, I decided to implement a simple J2EE application (using Tomcat and Oracle) using ant, instead of my company's Makefile system. This article documents my experience and impressions about using ant as a Java development tool. First, however, I provide a simple overview of the two tools.

make

If you aren't familiar with make (wherby I mean specifically GNU Make), it is a UNIX-based tool that reads a Makefile, which is a set of targets (with dependants) that get "made" when a target is out of date. What happens when a target is "made" is entirely up to the Makefile author. Usually, this means compiling source code into object or executable code, but it could be anything, including checkout of resources from source control or creating distributable archives. What happens during a make is typically calls to various shell commands. Since make originally was a UNIX program, make was designed assuming the full range of UNIX commands.

Make is very flexible, in that you have a wide latitude to define variables, manipulate those variables and pass them to any command available on your system. A simple Makefile might look like this:

FILE_BASE = hello
$(FILE_BASE) : $(FILE_BASE).o
    gcc -o $(FILE_BASE) $(FILE_BASE).o

$(FILE_BASE).o : $(FILE_BASE).c
    gcc -c $(FILE_BASE).c

Here, hello is a target, with hello.o being a dependant. hello.o is also a target itself, with hello.c as it's dependant. In most cases, make assumes that targets and dependants are files. So, in this example, if hello has an earlier modification date than hello.o, it will run the associated command (namely gcc -o hello hello.o), which creates hello and brings it up to date. So, if you had a whole slew of source files, make allows you to only recompile those that changed, not the whole tree. For more about what you can do with make, see the links at the end of the article.

ant

ant is part of the Apache Jakarta project. Ant has a similar concept to make in terms of targets and dependants, but ant doesn't assume that targets and dependants are files by default. Ant also doesn't assume that the purpose of dependants are to bring targets up to date, it's merely a simple dependancy. Ant also makes use of built-in commands to implement targets, rather than assuming shell commands are available (although you can execute arbitrary shell commands). This makes ant run on any Java-supported platform. Many of the commands are specific to compiling or working with Java code. Since ant is written in Java, it has the added feature of running the Java compiler from within itself, which ends up making compilation quite fast. Ant relies on this fact, even, because the typical compilation target results in compiling every single java source it can find each time you run it. For users of make, this may sound horrendous, but the compilation step (for me) took the same amount of time to compile one class as it did for 50.

Ant also uses an XML-based syntax for creating the buildfiles (although it is not strict XML in the sense that a DTD for all of ant cannot easily be made, and the syntax allows for a lot more flexibility than you might expect in an XML file). Following is an example:

<project name="foobar" 
         default="compile" 
         basedir=".">
  <description>Foobar!
  </description>
  <!-- set global properties for this build -->
  <property name="src" value="."/>
  <property name="build" value="site/foobar/war_file/WEB-INF/classes"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac debug="on" srcdir="${src}" destdir="${build}">
        <classpath>
            <pathelement path="${classpath}"/>
            <fileset dir=".">
                <include name="compiled/**/*.jar"/>
            </fileset>
        </classpath>
    </javac>
  </target>
</project>

Here, compile is a target (and the default target), and it compiles the java source code. It is dependant on the init target, which ensures that the build directory exists, as well as creating a timestamp. Note that here, everytime that the compile target is executed, the init target will also be executed. These aren't files with timestamps that may become out of date; they are simply chained events that occur in a certian order. I should note that you can conditionally execute the commands of a target, based on execute-time criteria, much as you can in make. Additionally, you can write Java classes to create your own built-in commands, or you can use a special built-in command that lets you run an arbitrary command-line command.

Evaluation Method

I have many years of experience with GNU make, and worked on our company's Makefile system. I'm familiar with makes pros and cons, especially with respect to Java development, which I've been doing steadily for the past 3 years. This is obviously going to make me a little biased against ant, because I know much more about make. However, my first experience with make was to create platform independant (UNIX, Windows, OS/2) build-files for creating shared libraries, so I remember what it was like to have to learn a wierd tool and get it to work in a general sense. Also, creating shared libraries (at least at the time) was not the trivial task that compilation is, and so I needed to learn make quite well to get it working right. My hope was that this experience would allow me to be objective with respect to ant.

I downloaded and installed ant, and set it up as my compilation tool for my project. Our company's Makefile system does the following things for the average developer:

  • Maintain a list of 3rd party jars needed for the project.
  • Checkout those jars if they are not checked out
  • Compile any Java classes changed since the last compile
  • "clean" functionality, which deletes all generated or checked-out files so you can do a "clean" build
Deployment of jars and classes (to the developer's Tomcat instance, not to a production server) is done by manipulating the arguments of the compilation command, so that the classes end up where tomcat is expecting them. My goal with ant was to create a buildfile that gave me this functionality. Doing so was very straightforward, save for configuring it to check out my jars only if they didn't exist. This required some more hunting and experimenting. Specifics on this appear below.

Once I had my ant file, I was off and developing and didn't really notice much of a difference between using make. With both systems I simply type a 'make' or 'ant' and my code compiles. The first time I build, my jars get checked out.

Comparison of the two Tools

My comparison will take two parts: The first will focus on the differences with using each tool for my specific task, namely writing a Java-based web application. The second part will discuss my more general impressions of ant vs. make as build tools, apart from my specific project (but still within the realm of writing Java applications).

Using ant on my J2EE Web Application

Boy does ant compile fast! The biggest difference I noticed was the speed at which ant compiled. I was quite distressed while creating my buildfile that ant would be compiling all the code every time, but after the first compile, I had to change to by output directory to verify that the classes were actually there, because I couldn't believe it had compiled all those sources so quickly. From a pure user perspective, however, ant didn't integrate with vim out of the box. With make (more specifically javac), you can have vim run your build and then step you to each line with syntax errors, because vim can parse the output of javac. Since ant reformats javac's output, vim wasn't able to do this. I assume that some tweaking with vim could alleviate this, but I didn't look into it. The reformatting (which amounts to indenting javac's output and prepending each line with a flag indicating that the output came from javac) made it harder to read the output of javac (probably because I was used to reading it direct from javac). I'm not sure if there is an option to disable this, but I couldn't find it.

I did have a somewhat difficult time getting ant to checkout my jar files only if they didn't exist. It required using the "uptodate" builtin command and creating a timestamped file. Perhaps there is a better way to do it, but the documentation wasn't clear. Accomplishing this in make was quite simple. I could make a target named for each jar (make allows for creating make-time targets dynamically, wheras ant can only have static targets defined at buildfile-creation), and then the command for that target is to check it out of CVS. The effect is that the checkout only happens when the file doesn't exist.

Using ant to make a full-blown development system

My company's Makefile system supports (or will support) additional functionality, including tagging source files, committing class files for distribution, running checks on source files before tagging, and other things needed for a sophisticated development environment. Implementing these is fairly straightfoward, because make and shell programming is very similar to LISP programming, where code and data are interchangeable, and there is a high degree of dynamicism. This allows for a general-purpose Makefile that needs to know little or nothing about the files on which it operates. My checkout example above indicates what I mean. A better example is if I want to make a "tag" target, that tags all source files as "stage", so they can be pushed to a staging environment. Before tagging, I need to make sure that each file has been committed to CVS. I can't imagine how to do this with ant without writing a builtin command or shell script (or, worse yet, hard-coding the java source file names in the buildfile). I'm sure it can be done, but in make, it is very simple. Since you can construct targets and commands dynamically at make-time, I can write a generic make target that does this check and fails if any file isn't committed to CVS. Being able to do this easily is, in my opinion, is a pretty basic feature that a build system should have. Ant could support this with a more robust variable assignment mecahnism and with a way to create dynamic targets, or a way to treat property values as lists for iteration.

Integrating ant with other systems also seems to be quite cumbersome. You bascially have two choices to integrate ant with other systems (e.g. clear case if you don't use CVS): writing a java class, or using the <Exec...> builtin command. Writing a Java class seems quite cumbersome, and often Java is not suited to executing system-level tasks involved with running command-line tools typically provided by configuration management tool vendors. Using the builtin command is also somewhat cumbersome, as it is not as flexible as just running the command through a shell. You are bascially specifying all the parameters to pass to the java method that executes external commands, and as mentioned before, this is not always appropriate for executing command line tasks.

Even if this is done (as many have done with providing builtin commands for BEA Weblogic), your commands won't work if the interface changes. For example, BEA radically changed their EJB deployment procedure between version 4.5 and 5.1. An ant builtin task would have to be rewritten, recompiled and redistributed to accomodate this. Another example is the change between javadoc for java 1.1 and for java2. If such a change occurs again, ant will not easily be able to take advantage of the better featureset. This is because with ant, you would have to reimplement your builtin task. With make, you can easily change your Makefile.

Additionally, ant doesn't have nearly the documentation, developer knowledge, or proven value that make has. I know that whatever needs my organization will have (including developing non-Java applications), make will be able to support them. I cannot say the same for ant.

That said, ant has some good things going for it. For one, if you are a developer that knows neither make nor ant, you will be up and compiling javacode a lot faster with ant. ant essentially provides a builtin Makefile for compiling and running Java code, and that's pretty good. Make was designed with compiling C code in mind, and getting it to work with Java requires some non-obvious make coding that does require some prioir knowledge of make to do. Additionally, ant compiles incredibly fast. While I didn't try ant on a real sized project (e.g. 1000s of classes), for my one-person development effort, it was much faster than make (of course, you could have make call ant for compiling). Finally, ant is truely cross-platform. Ant will run on Max OS 9 and VMS. Make will not (without additional software installed). In make's favor, I should point out that Cygwin provides free versions of make and all other GNU tools for windows, including bash, and that the vast amount of Java coders in the world are using either UNIX or Windows. So, for most Java coders, make is platform independant (although it does require an extra package for Windows).

Summary

OK, I don't want to fill this article up with anecdotal evidence or, worse yet, ranting. So, I'll try to capture my thoughts in the following pros/cons table:

  • ant
    • Pros
      • Fast Compiles.
      • Easy to get up and running for compilation.
      • True platform independance.
      • Good error reporting of buildfile syntax errors.
    • Cons
      • Property value assignment very simple and inflexible.
      • Cannot create dynamic targets at build-time, making complex build tasks difficult to write.
      • Compiling every source file every time might be a problem for large systems.
      • Integration with other systems limited to Java classes or executing command line through Java.
      • Wrapping commands in "builtin tasks" exposes them to breakage when underlying tasks change.
      • Sparse documentation, not widely used
      • Use for non-Java projects not realistic without more builtin commands.
  • make
    • Pros
      • Incredibly flexible
      • Run-time dynamicism simplifies creating complex tasks
      • Powerful variable creation mechanism simplifies creating complex tasks
      • Integration with other build and deployment tools is very simple through shell commands
      • Assumes targets and dependants are files, which makes it easy to write targets that only do the work that is needed
      • Extensive documentation, developer knowledge and proven track record as industry standard build tool
      • Can be used for any type of project, even projects that mix languages and technologies.
    • Cons
      • Requires UNIX command set installed to be effective.
      • Requires some non-beginner level make coding to work effectively with Java compiler.
      • Complex Makefiles can be difficult to debug if not architected properly.
      • Typical UNIX user-unfriendly error messages increase learning curve.
      • Full system compiles are slower because of multiple javac invocations (although this could be remedied by calling ant for compiles only :)

I've also come up with the following, that I believe characterizes the situations in which ant or make are warranted:

  • Use ant if:
    • You are a single developer or one of a very small development group working a small Java-based application and you don't know make.
    • You are working on a project that will be developed or deployed on a platform other than UNIX or Windows
    • Your developers are all using their own build scripts and you need something fast and are not looking to build a large general-purpose build system
  • Use make if:
    • You know make
    • You are working on a medium to large sized project or on a project with more than a few developers.
    • You need to integrate with a variety of configuration management tools
    • You are building a medium to long-term solution for build and deployment that must handle a wide variety of tools and technologies

Conclusions

While ant is an interesting tool, I don't see it as a heavy-duty build tool for Java development. Furthermore, ant's overall design seems to be the opposite of make. ant tries to be all things to all people and reimplements functionality that's available and proven on UNIX. ant tries to have a command for everything. Looking at the list of builtin commands one can't help but get the feeling that ant was made by someone who did not understand make and didn't want to learn it, and slowly realized that there's a lot of functionality a build tool will need if it cannot rely on the UNIX command set. Comments on the ant homepage support this (e.g. "Makefiles are inherently evil") to an extent. make, on the other hand, is a framework for running arbitrary commands. True, make requires UNIX to be useful, but UNIX commands are available on almost all platforms where Java is being developed. Yes, make can be hard to learn, and it does have it's quirks, but it works and it works well for almost any situation. The make code to implement java compilation (ant's biggest draw, IMO) is quite simple (even if non-trival to derive). This is one time only operation. I think ant is great if you are a single developer who can't afford an IDE and don't want to mess with make. With ant, you'll be up and running quickly. For a Release Engineer or Lead Programmer on a project, though, make is a tried and tested tool that works just as well with Java as it does with C, and you know that it will do whatever you want it to do.

References

Before You Respond!!

I know that many of you who prefer ant will want to put me in my place and point out that because I don't know ant very well, I will be biased towards make. Aside from requestng that you post constructive comments on this issue instead of flames, I would ask that you keep the following in mind:

  • Make does have a large base of users, and many will be less objective than I am without arguments more convincing than "Makefiles are evil". The greatest tool in the world that no one uses is worthless.
  • Do you know a lot about make and build systems? I do, and I've built a lot of Makefiles and used make to do a lot of things that would be needed in any serious build system. If you have something to say about ant's ability to complete with make at this level, I hope you have done something more than just compile java code and create a .war file
  • Have you worked on a large Java project that lasted more than a few months and required more than a few developers? Have you worked on a project where non-programmers needed to create or modify files that were part of the overall build?
  • I know that make and ant are not the only build tools around. I know that other build tools cost money, and I'm operating under the assumption that someone using these tools cannot or will not buy a build tool. I also don't have much experience with them, but I tried to write the article so that that wouldn't matter
OK, I just want comments to be constructive and useful. I don't purport to know everything and have no problem being set straight, as long as convincing arguments are made.

Sponsors

Voxel dot net
o Managed Hosting
o VoxCAST Content Delivery
o Raw Infrastructure

Login

Poll
I prefer
o make 24%
o ant 27%
o some IDE 20%
o typing everything on the command line 10%
o entering Java bytecode directly 17%

Votes: 69
Results | Other Polls

Related Links
o ant
o BEA Weblogic
o make
o Cygwin
o Ant Homepage
o Ant Documentation
o Make Homepage
o Make Documentation
o Cygwin Homepage
o Java Homepage
o Tomcat Homepage
o Also by GusherJizmac


Display: Sort:
Comparing ant and make as Java build tools | 89 comments (82 topical, 7 editorial, 0 hidden)
this is nice (3.83 / 6) (#5)
by speek on Mon Sep 24, 2001 at 05:00:06 PM EST

But I just like Ant. I never went to school for computers, so I've never been seriously exposed to Unix. And no, running Linux at home isn't really teaching me all those built-in commands...

The documentation is straightforward and clear for Ant (I'm surprised that's one thing you picked on, actually). I'm not sure why I would want dynamic targets just yet - your example of checking out jar files only if they don't exist just shows your ignorance of the available tag in Ant - unless I've misunderstood your example.

I have nothing against Make - but I've only used it a few times for a few simple school projects. Ant made more sense when starting from scratch to learn a build tool. There is no question that Make provides more power and flexibility. I just haven't had a reason to care yet.

--
al queda is kicking themsleves for not knowing about the levees

Parsing output - Read the Fine Manual (4.25 / 4) (#9)
by smileyy on Mon Sep 24, 2001 at 07:12:33 PM EST

Having your editor parse ant output (specifically, the fact that it will prepend [javac] to compiler output seems to be a question that comes up a lot. So much, that its a frequently asked question.

The long answer can be found here, while the shorter answer is...use the -emacs option

% ant -emacs <target>


--
...alone in suicide, which is deeper than death...
A couple of inaccuracies... (4.00 / 5) (#11)
by smileyy on Mon Sep 24, 2001 at 07:18:43 PM EST

You talk about ant compiling your code. This is misleading, since ant will just call javac or jikes (or your java compiler of choice) to perform the compilation.

Also, ant doesn't recompile every file every time. Ant will only recompile source files that are newer than their corresponding class files. That's probably why ant seemed so fast to you.


--
...alone in suicide, which is deeper than death...
XML build files (3.00 / 1) (#13)
by wiredog on Mon Sep 24, 2001 at 07:44:05 PM EST

Borland Builder and, I think, Delphi/Kylix use XML build files.

If there's a choice between performance and ease of use, Linux will go for performance every time. -- Jerry Pournelle
Inner Classes ?? (4.00 / 6) (#16)
by Estragon on Mon Sep 24, 2001 at 09:27:06 PM EST

How does ant deal with inner classes? Make has a hard time with them. What you need is an implicit rule that knows the target foo$bar.class depends upon the target foo.java.

It would be nice to do something like:

%1.class %1$$%2.class : %1.java
        insert java compile rule here

Can ant solve this problem?

Shell-level scripts in Java (4.50 / 4) (#17)
by slaytanic killer on Mon Sep 24, 2001 at 09:53:06 PM EST

When I built the build with Ant, I found myself writing built-in tasks with Java. Used regexes a lot, to boot. It was terrible. I would write hundreds of brainless Java lines a day, just for trivial things to express in a better scripting language.

Try Jython. It's kind of Lisp-like because you're manipulating lots of lists, and you don't have to put extra slashes for regexps and it's more fun to write stuff with... I did not rewrite my build in Jython because I already had the system stable, but it is worth a look. It also has the interactive evaluator, like Scheme, so you can just sit there and test stuff on some directories.

BTW, Jikes rocks. I don't quite understand using Javac, though there are situations where people say they need to.

To the author (3.00 / 4) (#18)
by valency on Mon Sep 24, 2001 at 10:01:25 PM EST

Can you give us an example of when it might be absolutely necessary to create dynamic targets at build-time? I don't deny that such situations exist, I just can't think of any.

Also, isn't Make's integration with other systems "limited to executing command lines"? The Ant exec target gives you at least that much power.



---
If you disagree, and somebody has already posted the exact rebuttal that you would use: moderate, don't post.
Not widely used? (2.33 / 3) (#19)
by jdludlow on Mon Sep 24, 2001 at 11:29:45 PM EST

You say that ant is not widely used. How do you arrive at this conclusion? I use ant all the time, but I don't remember ever telling anyone that I was doing so.

dependency detecting (4.25 / 4) (#20)
by sesquiped on Tue Sep 25, 2001 at 12:54:29 AM EST

I've had some experience with make, so I'm going to use that to illustrate my point: a makefile line for Foo.class obviously depends on Foo.java, but it might also depend on other classes in the package, like Bar.java. It's generally not a good idea to write down all those dependencies manually, since they're bound to change and then the actual depencies won't match what make is working with. My question, then, is how do you create makefiles that contain the true dependencies amoung files in your project? With C, you can use commands like gcc -MM, which lets the compiler figure them out for you. But in Java, it's much harder to figure out dependencies because you don't have to explicitly import anything. It's more of a job for the compiler, and indeed, many Java compilers will figure them out for you and only recompile what has changed if you run them as 'javac *.java'. But if the compiler does this already, then where does a build tool fit in?

Sorry that was so rambling...

antfarm (4.33 / 6) (#21)
by macpeep on Tue Sep 25, 2001 at 01:35:12 AM EST

At work, we need to compile our app (non-Java) on several platforms. We solved this problem by coding our own version of ant that is remotely controllable, and that sends its logs remotely, over RMI, to a central server. On the central server is a web based tool that allows one to control the remote ant's, as well as view the build log history. With this system, engineers can build to any target platform from their own desk, and view the logs. At the same time, the system acts as a continuous build system.

Doing things like this is *SO* much easier with ant and Java than with make.

I smell a religious war coming on... (3.37 / 8) (#22)
by Will Sargent on Tue Sep 25, 2001 at 03:45:51 AM EST

Ant is not Make. Make is not Ant.

In some respects, this argument mirrors the "Java vs C++" wars that make their way around Slashdot every so often. Java is slower, simpler and more restrictive than C++. However, what it loses in flexibility it makes up for in pluggability. It's very easy to write new TaskDefs if you need to do something in Ant, and you can use the pre-built stuff or exec for everything else.

I've used Ant in situations involving over 20 developers and N designers and multiple J2EE projects. If I tried to use Ant on Mozilla, I'd be screwed, but I think this is missing the point: Java has less moving parts than C++, so I don't NEED the flexibility of make. That's why it works so well.
----
I'm pickle. I'm stealing your pregnant.
Dynamic targets (4.25 / 4) (#25)
by 3john on Tue Sep 25, 2001 at 04:00:53 AM EST

If dynamic targets and such appeal to you, have a look at the <SCRIPT> task .
You can use python and jaavscript in your tasks. Make sure you actually *work* through the example, too. It is more than it seems at first glance.

Example of a dymanic target? (none / 0) (#34)
by kostya on Tue Sep 25, 2001 at 11:11:10 AM EST

I'm not sure I understand exactly what the author means by dynamic target, but maybe this is an example.

Our build process is pretty rapid, so it's very important that we know the exact build of a jar file, especially when we publish them to other groups. Our dev process commits version changes only when they make it to a production situation. So SIT foo113.jar from yesterday could be three builds away from foo113.jar of today.

The solution is to automatically (or at least easily) increment build numbers and then to keep a record of how the jar was created in the jar (basically a log of the build is included). This requires writing state out to a file, and then reading that state from a file. I don't use ant, so I'm not sure how easy that is with ant. It isn't all that hard in make, but it is hard with make on NT because NT's cmd shell bites. My solution was to use perl for number handling (ever try to work with numbers in NT batch?) and then write the state file as a makefile. Each project then includes its statefile if it exists and then uses the version numbers and history to determine the jarfile name and version.

In our case, we needed simple make files that developers could just add or subtract lines to but would have the entire automated build and history logging built in. Actual changes required by a developer of a new project are about 10 lines maybe. We just used a lot of includes. I can rebuild 6 projects from scratch in about 2 minutes (jikes rocks)--and that includes probably 6 EJB compiles.

Someone who knows ant should feel free to enlighten me ...



----
Veritas otium parit. --Terence
Full of incorrect information (4.50 / 8) (#35)
by mulvaney on Tue Sep 25, 2001 at 11:15:03 AM EST

  1. Ant does not recompile everything each time you run it. It only recompiles .java files that are newer (timestamp) than the .class file. The only way to get it to recompile everything is to have some kind of clean rule, which would delete all the .class files. Are you calling a clean rule before your compile rule every time?
  2. Ant has a very large number of users. Virtually every java project available on the web uses ant. Check all the different Apache projects, including such important projects as Tomcat and the Xerces.
  3. It is easier to integrate with CVS than you imply. You could do your tag rule with the command:

    <cvs command="tag mytag" />

  4. Ant has great documentation at http://jakarta.apache.org/ant. By looking at it for 15 seconds I found the <availble> command, which can be used to determine if a file exists (which would solve the other problem you had with ant.)
I work on a large java project that switched from Imake/make to ant a few months ago. It has been a very successful switch.

I have a couple of questions about how you used make.

  1. Did you edit the Makefiles directly? You don't mention using Imake or anything else to generate them. It would seem that editing all those Makefiles directly would be a nightmare...
  2. What kind of rules did you use to compile the java classes? Did you invoke a javac for each different .java file, with a rule like:
foo.java : foo.class
javac -d /bar foo.java
Or something like that? (My syntax may be off a little bit, its been a while since I used make :) If that is what you used, then that is why ant is so much faster. Invoking a new javac for each class is prohibitably expensive.

Assuming that you did it that way, how do you account for circular dependencies in java files? Did you make rules to compile several files at once?

This is one of the problems we had with Imake. Our rules required us to edit the Imakefile with each source file we added, and make sure that we compiled things in the correct order. I think this is the most compelling reason to use ant over make: make just doesn't work for java dependency relationships.

With ant, you don't have to worry about stuff like that, and you can think like a java developer and not a C programmer.

-Mike

javac, blach (4.00 / 2) (#37)
by hardburn on Tue Sep 25, 2001 at 11:34:05 AM EST

While javac is nice in that everyone with a JDK already has it, I prefer jikes. It is much, much faster then javac, and has some of the best debugging output I've ever seen in a compiler (not that I would know much about that; my code compiles perfectly the first time . . . )


----
while($story = K5::Story->new()) { $story->vote(-1) if($story->section() == $POLITICS); }


But you clearly *don't* know Ant (4.54 / 11) (#44)
by lordpixel on Tue Sep 25, 2001 at 12:42:11 PM EST

I read your "please read before responding" but I'm going to say it anyway:

Clearly you know make a _lot_ better than you know Ant. So you commit the classic fallacy of trying to do what you do in make the same way in ant. Sometimes that fits, sometimes ant just does it differently.

You should have spent more time on the ant-user mailing list - you'd understand how to do many of the things you ask about.

You're also not doing your argument any favours by failing to understand the basic dependancy rules for compiling Java. It makes you come accross as a C programmer who's trying their hand at Java - fine, but I'm not going to be immediately impressed by the "depth" of your analysis in this case either.

As for the "more users" argument - ant's userbase is only small by the standards of a tool which has been around for decades like make. Its userbase is *huge* by most project's standards, and its focussed almost entirely on Java, whereas Make can barely handle basic Java dependancies, let alone give me the power to intergate something like JUnit or Weblogic. Sure I can always call it on the command line, but...

You're right. BEA have changed their EJB tool definition with every major release. And ant has followed every change, because it hasa highly active community. With make, *you* would have had to update your makfile because the syntax of the command line tools changed. With ant, its done for you, and if you need it sooner, guess what, you can use command line tools from inside ant (or code it yourself in Java and contribute it back to the project if that's sensible for you).

Yes, there is sure to be some class of problems where make is better - I used it myself to build Java projects before ant came along, its certainly capable - but most people will waste time in make if Java is what they're doing.



I am the cat who walks through walls, all places and all times are alike to me.
Autoconf/automake? (none / 0) (#46)
by tjansen on Tue Sep 25, 2001 at 01:58:10 PM EST

I wonder why nobody mentioned autoconf/automake. There is a number of Java-macros and they make configuring the make environment and installation quite easy. IMHO they are a good choice for Java development as well, especially for open-source software (because with a wide distribution of the source it gets harder to make assumptions about the make environment, so you need that autoconfiguration and installation stuff).

Ant scales well (4.80 / 5) (#51)
by yigal on Tue Sep 25, 2001 at 03:08:20 PM EST

At my company we switched to Ant more than one year ago (back in the times of Ant 1.1). Now, after more than a year, it still works and it is still editable. In my opinion, this is largely due to the fact that Ant is much more verbose than Make.

When auto-building a release, Ant will help us to compile hundreds of classes, put it in a fair number of jarfiles and copy files around, in the meanwhile creating zipfiles, tarballs, tagging and committing stuff, and using XSLT stylesheets to convert our docbooks documents into HTML. And when all is finished, it uploads the code to the Spot You Want. All this takes less than half an hour. And then we have a fully functional release, one for Windows, one for Linux, and one for the CD.

And the neat integration with JUnit allows for a very fast edit-compile-failure-debug cycle. Completely compatible with Emacs.

Just my happy experiences.

YDD
.sigmentationfault

10 months with ant... (4.50 / 10) (#57)
by technik on Tue Sep 25, 2001 at 04:22:45 PM EST

10 months with ant and it is currently building 33 (today's count) products in three project areas across seven different teams in two companies and targeting both NT and Unix running Java1 and Java2 under ServletExec, JRun, Tomcat, WebSphere, and WebLogic (So many standards, so little time...). I first mentioned it in a diary entry on Advogato. Thanks to JPython I was able to quickly hack together support for PVCS (that VM is a wretched mess) which at the time was not supported. Some of these products were begun in 1997 and, mostly because no one knew better, have convoluted build requirements.

The build system is maintained by the individual developers who, following the existing work, need about fifteen minutes of explanation before they're able to put together new product builds. Ever explain make in fifteen minutes? Me neither. That's a success right there.

The SCM people love it because they can perform the builds from scratch themselves with simple commands (ant <project>, ant <product>, ant <product> -Dversion=1foo2bar3.0, etc.). They are generally former mainframe QA or developers and distributed systems look like an awful mess to them. I packaged up all the necessary tools and libraries including stable JDKs so they can start with a bare OS and have a working build in a few minutes. Sure, I could have done that with a native tool chain but having everything under the JVM makes for easier acceptance (even if it's not necessarily the best idea, for lots of reasons).

I'd love to see what commercial build tools can do, but since I'm a fixed cost it's better for them in the short-term to let me do it myself than to shell out and hope that it works.

- technik

Jam. (none / 0) (#60)
by i on Tue Sep 25, 2001 at 05:27:58 PM EST

I wonder where Jam and FT Jam stand in the grand scheme of things.

and we have a contradicton according to our assumptions and the factor theorem

make bias (4.50 / 2) (#73)
by jilles on Wed Sep 26, 2001 at 07:22:03 AM EST

I have worked with ant recently and I think you have overlooked a few things and dismiss ant to easily:

- Ant is XML based. This means that tool support is very easy. A good example is netbeans that allows you to create ant files in a point and click fashion (you can also edit the xml by hand or even do both). I would defininately call this an advantage. As ant becomes more popular, I expect that most java IDEs will integrate it with their project management.
- Compilation of java source code pretty much scales linearly. This is because you don't have a linking phase until run-time. In other words most dependencies are resolved at run-time rather than compile time. Therefore compiling all sourcefiles shouldn't be a problem, especially if the compiler skips files that don't need recompilation.
- Tool creators can actually include ant tasks. A good example is AspectJ that bundles ant tasks with their tools. This combined with tool integration should make it easy to integrate new tools into your build file.
- With make you also break compatibility if the tools you call are updated (and for example have a changed command line interface). The problem with make however is that you will have to debug the script whereas with ant you can fix the task definition (e.g. to be backwards compatible) without ever touching the uses of the tasks.

I agree that ant right now is most suitable for usage in combination with Java. However, it is all XML and it shouldn't be hard to create a C version of it. Make is a relic of the past. Using it costs you in terms of maintenance (of the build files). The syntax is awkward at best and very error prone (I recall having spent an entire afternoon once figuring out that I should have used a tab instead of four spaces). The worst thing about make is that it mixes configuration and tools. Ant separates the two since ant files only define properties and parameters. The actual tools are singled out in task definitions which are designed to be reusable rather than the ad hoc sripting often found in make files.
Regards, Jilles
RTFM (4.00 / 6) (#74)
by nichughes on Wed Sep 26, 2001 at 07:56:51 AM EST

I got as far as
You bascially have two choices to integrate ant with other systems (e.g. clear case if you don't use CVS): writing a java class, or using the Exec... builtin command.
before I gave up on the article. If you are not familiar with the tasks available in Ant then you are preaching from a position of ignorance. Clearly you are trying to emulate Make using Ant, a classic mistake akin to writing procedural code in an OO language made worse by your own failure to read the user docs.

Please refer to the user documentation. You will find that there is CVS support in one of the core tasks and Clearcase support in an optional task. I can vouch for the fact that the CVS support is more than adequate for any need we have come across in the past year.

--
Nic

Innovator's Dilemma (4.33 / 3) (#77)
by ajm on Wed Sep 26, 2001 at 01:36:13 PM EST

I think Ant is a pretty good example of the Innovator's Dilemma in action. Make is fantastic, it does, or can be made to do, just about anything that you need done in a build system. The average user makes use of a small fraction of the capabilities. Ant does less than make. However, ant completely satisfies some fraction of make users because it satisfies their requirements, and offers, for java developers, an orthogonal advantage, java integration, that make cannot. p.s. When I first looked at Ant I was also put off by the dismisal of make as evil. Stupid. Ant could certainly benefit from dependency analysis and other of make's features. Though it's great it is to some extent a reinvention of the make wheel in a less round form.

Why not Imake? (3.00 / 1) (#79)
by jcrosbie on Thu Sep 27, 2001 at 03:41:53 PM EST

Why did the author write a Make build system to build for multiple platforms when Imake exists to do just that? Check out the X project for more info.

Ant (5.00 / 6) (#81)
by donaldp on Thu Sep 27, 2001 at 09:59:07 PM EST

Hi,

Theres some serious faults and innaccuracies in the above article regarding ant but that is excusable given that the author admits he is not that familiar with ant. Many of the more obvious faults have been corrected.

However there is one pervading theme through the whole article. Namely he doesn't list simplicity as a pro for ant but does list complexity as a pro for make ;) I suspect he may be a build engineer or at least worn that hat at one time. IMO one of the biggest advantages of Ant is it's simplicity. Most users of ant pick up the basics of ant in 10 minutes and many are non-technical / non-programmers. The same can not be said about make. Any decent sized make setup virtually mandates a make guru on hand and can make it difficult for people other than make gurus to work with.

I have used (GNU) make for far longer than ant has existed, but I am a committer for ant so I think I can say that I am reasonably familiar with both systems. Both have their strengths and both have their weaknesses. Personally I still use make for all my native compiling but use ant for all my xml, java and content related builds. Sometimes I throw a custom tcl system in there for good measure ;)

There was a lot of issues brought up in response to this article. In many cases they are invalid or they tried to compare the worst of ant with the best of make (file copying and mkdir example). However there are two good examples of faults with the ant system. Namely

1. ant doesn't deal well with complexity
2. ant interacts with the system using java specific methods in most cases and thus is limited by java

(1) is a recognized fault and will be addressed (hopefully) when Ant2 comes out. Time will tell if we succede in removing that failing.

(2) is also gradually being fixed when the need becomes apparent.

Anyways this kinda reminds me of the cgi vs servlet argument. Servlets are vastly simplified and can not be scripted without using other infrastructure. So instead of cut/copy/munging scripts you are actually forced to reuse at the component level. Servlets are much faster than cgi, require more knowledge to write but are far simpler to use. I suspect the same is true of tasks. Faster, harder to write and easier to reuse.

However given that current ant solves 90% of the problems of most people who write java products need to be solved but is far more accessible than make I can't see it's popularity diminishing, nor it's rate of growth.

I am sure some peeps will say that because it doesn't do X it is useless - much like they used to say that because C didn't do Y (while assembly can), thus C must be useless. ;)
Cheers, Pete
ant and large build systems (4.00 / 2) (#84)
by Ranger Rick on Sat Sep 29, 2001 at 12:57:34 PM EST

One of the reasons we went with ant instead of make is make's unsuitability to working with Java code. Yes, it can be coaxed into working with the way java builds, but it's a terrible pain in the ass.

Our office is filled with Java coders, not build engineers. If I, with my defacto job of build engineer, were to use make, it would be just another thing that only I understand enough to tinker with. When you're job is supporting your programmers, being the only one who is able to modify the build system is not conducive to getting things done.

Our entire codebase is based on Java and XML; ant is immediately understandable to anyone who works with our build, and, if we need to make additional tasks or classes, we have plenty of coders who are able to whip something together very quickly.


:wq!


Maintenance (4.00 / 1) (#89)
by damphlett on Wed Oct 03, 2001 at 04:37:16 AM EST

The people I work with place high value on being able to move jobs between staff, and even bring new staff in on a job. - .

ANT files are just really self explanitory - you actually have to try to make them unreadable.

Make files can range from reasonable to plain bizarre. Most people understand their own, but there are many different styles

Comparing ant and make as Java build tools | 89 comments (82 topical, 7 editorial, 0 hidden)
Display: Sort:

kuro5hin.org

[XML]
All trademarks and copyrights on this page are owned by their respective companies. The Rest © 2000 - Present Kuro5hin.org Inc.
See our legalese page for copyright policies. Please also read our Privacy Policy.
Kuro5hin.org is powered by Free Software, including Apache, Perl, and Linux, The Scoop Engine that runs this site is freely available, under the terms of the GPL.
Need some help? Email help@kuro5hin.org.
My heart's the long stairs.

Powered by Scoop create account | help/FAQ | mission | links | search | IRC | YOU choose the stories!