Проблема в том, что вы используете разные загрузчики классов. Классы Commons Net должны загружаться тем же загрузчиком классов, который загружает задачу FTP. Поскольку задача FTP загружается Ant при запуске, вам необходимо добавить Commons Net в путь к классам Ant, чтобы он загружался тем же загрузчиком классов. Вот почему документация дает вам 4 различных способа сделать это.
Я согласен, что ни один из них не идеален (переменная среды CLASSPATH является худшей). Одним из способов решения этой проблемы является предоставление сценария оболочки вашего проекта, который вызывает Ant и передает аргумент apporpriate -lib. Затем вы заставляете людей использовать это, а не вызывать Ant напрямую. На самом деле, вы могли бы хитро назвать его «ant», чтобы он запускался вместо существующего «ant» на пути (это работает, только если текущий каталог находится на пути перед другими каталогами).
Пятый вариант документации великолепен в теории. Они наконец исправили проблемы с загрузкой классов в 1.7.0. К сожалению, как вы упомянули, никто не обновил задание FTP, чтобы взять путь к классу. Вы можете попробовать отправить запрос на улучшение, но это не поможет в краткосрочной перспективе.
Есть еще один вариант, который не лучше других. Вместо того чтобы убедиться, что классы Commons Net загружаются загрузчиком классов, который загружает задачу FTP, вы можете убедиться, что задача FTP загружена загрузчиком классов, который загружает классы Commons Net. Для этого вам нужно удалить файл ant-commons-lib.jar из каталога 'lib' установки Ant. Это означает, что задача FTP не будет загружаться при запуске. Именно поэтому необязательные задачи разбиты на множество отдельных JAR-файлов, так что их можно удалить по отдельности. Поместите этот JAR-файл вместе с JAR-файлом Commons Net, чтобы он мог быть загружен одновременно. Тогда вы можете сделать что-то вроде этого (я попробовал это, и это работает):
<taskdef name="ftp"
classname="org.apache.tools.ant.taskdefs.optional.net.FTP">
<classpath>
<pathelement location="${basedir}/lib/ant-commons-net.jar"/>
<pathelement location="${basedir}/lib/commons-net-2.0.jar"/>
</classpath>
</taskdef>
<ftp server="yourserver.com"
userid="anonymous"
password="blah">
<fileset dir="somedirectory"/>
</ftp>
Но это, вероятно, худший вариант, чем просто использование ключа -lib (со скриптом-оберткой или без него). Единственное, о чем я могу подумать, - это попытаться найти стороннюю задачу FTP для использования вместо задачи по умолчанию.