Skip to main content

Convenience kills the Cat

Posted by schaefa on November 9, 2005 at 10:55 AM PST

This week I created a test suite for a project I am currently
working on and a coworker wanted to run the same tests but no matter
what we did defining the junit task in the Ant build script failed. The
script just reported:

taskdef A class needed by class org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
cannot be found: junit/framework/Test

even tough we added junit.jar in the classpath in the junit's
taskdef.. After a search on the web I figure out that a long time ago I
put junit.jar into the Ant's lib directory and now forgot to tell my
coworker about it.

The reason for that is that the classes for the Ant's
junit task is in the archive ant-junit.jar and that is placed by
default in the Ant's lib directory. So the class loader of ant will
have the junit task put is not able to find the junit classes because
Ant does not bundle the junit.jar archive together. Now even when I put
the junit.jar in the taskdef's classpath the Ant's class loader is not
able to find the junit classes because junit.jar is only available to a
child class loader. There are only two ways to fix that:

  1. Put junit.jar into the Ant's lib directory
  2. Remove ant-junit.jar from the Ant's lib directory and add
    junit.jar and ant-junit.jar into the taskdef's classpath

In my opinion both solution are bad because it requires human
interaction and the user is maybe not aware of the problems that go
along with each solution. Solution 1 does look in the version of jUnit
that can be used even when another Ant script wants to use a newer
version. Solution 2 maybe breaks other scripts that expect that both
archives are in Ant's lib directory and does not add both archives to
the taskdef's classpath.

The best solution in my opinion would be that all optional
tasks that need another library are not placed into the Ant's lib
directory so that they are not loaded by the Ant's class loader. Ant's
distribution could have them in a separate directory available for
scripts to use. Now in the jUnit's taskdef one could add the
ant-junit.jar from the Ant distro along with the desired
junit.jar. This way there is not human interaction needed and the
scripts can choose the library they want to use rather than relying on
the user to select the right one to be put in Ant's lib directory. Of
course scripts that do rely on the fact that these archives are placed
in Ant's lib directory would need to be adjusted but that would be a
one time task rather than spending hours later to figure out why the
junit tasks fails in certain environments or after someone upgraded to
a newer version of Ant.

Once again convenience has proven once more, at least to me, that on the long haul it uses up more time solving the problems it
causes than what it actually saves in the first place. I think that it is much better to
fail fast rather then letting a problem lurk under the surface and then
it bites you from behind at the probably most inconvenient time.

Have fun - Andy

Related Topics >>