This is so trivial that I'm hesitant to post it. But it might save someone a few minutes. Short version: be sure to end any external taskdef declarations in a properties file with newlines.
Long version:
When using custom Ant tasks you have the option of specifying the name and class of the task in the <taskdef> tag:
<taskdef name="mytask" classname="com.mydomain.MyTask"/>
You can then reference this task like any built-in Ant task:
<mytask myOption="foo" myOtherOption="${bar}" />
Easy enough. But there's another way to declare a task:
<taskdef resource="mytask.properties"> <classpath refid="some.classpath.ref" /> </taskdef>
The referenced properties file (mytask.properties) is a simple name-to-class mapping like you'd expect:
# Ant automatically makes these tasks available mytask = com.mydomain.MyTask othertask = com.mydomain.OtherTask
And when Ant reads this in it loads the referenced classea and makes taskdefs available under the given names. Very useful for building task libraries, and pretty simple. But if the last line does not end in a newline Ant will die with something like:
BUILD FAILED .../build.xml:84: The following error occurred while executing this line: .../build.xml:123: taskdef class com.mydomain.MyTask cannot be found
If you have any experience with Ant your first instinct will be to check your classpath reference, make sure you don't have any typos or pointers to out-of-date JARs, whatever. Resist that urge, and first make sure your properties file has at least one trailing newline. (Sidenote: One of my sayings is: "When dealing with hardware, 90% of the time the problem is the cables." So: "When dealing with Ant, 90% of the time the problem is the paths." Except this time.)