Using the optional FTP tasks, requires the installation of optional libraries into Ant's classpath. I would suggest enhancing the FTP task, so that the optional libraries can be referenced with a classpath entry element in the same way as the JUnit task. I will be happy to make the enhancement.
Created attachment 22762 [details] FTPTask extracted out into delegate.
I have had a rough go at extracting out the direct dependencies on commons-net into a delegate. I have run into a snag - the FTPTask.LanguageCode.getValidLanguageCodes() method makes direct references to FTPClientConfig. :( Any suggestions for get this refactored out?
I don't think there is a clean way to do it since the class doesn't have any access to <ftp>'s classpath at all. One option may be to hard code the supported languages of commons-net 2.0 and I must admit I can't come up with an alternative.
My need was to get FTP to work without adding jars to %ANT_HOME%/lib or ${user.home}/.ant/lib, but rather use jars relative to my project so that each developer didn't have to do anything on their machine. I had to delve into the code, and although this may not work in the future, it does right now: <path id="wptg.classpath"> <fileset dir="${wptg.work.dir}" includes="commons-net-1.4.1.jar" /> <fileset dir="${wptg.work.dir}" includes="jakarta-oro-2.0.8.jar" /> <fileset dir="${ant.library.dir}" includes="ant-commons-net.jar" /> </path> <classloader classpathref="wptg.classpath" parentFirst="false" /> <taskdef name="wptg-ftp" classname="org.apache.tools.ant.taskdefs.optional.net.FTP" loaderref="ant.coreLoader" /> With the name off of <classloader>, it creates a new AntClassLoader with the optional jars, and ant-common-net.jar. If memory serves, specifying classpathref for the taskdef failed b/c the FTP task was loaded by the bootstrap classloader, and couldn't see the FTPClient class. I stuck with this as my method for adding more optional jars for the project as a whole.
svn revision 808350 contains the code in a further modified manner (basically I've shuffled around some code to make diffs against FTP.java easier to read) with support for a nested classpath. Since ftp had evolved a bit, I also had to merge a few changes. I can't properly use <ftp> in my current environment therefore I haven't enabled the changed task, yet. Will do so later on a different machine (later likely measured in days). As for the language configuration, I've simply decided to not use an enumerated attribute at all, but a plain string.
Thanks Stefan. I've checked out revision 808350, updated defaults.properties to use FTPTask and built ant. When I try to run with a nested classpath WITHOUT ant-commons-net.jar in the nested classpath, this is the error I get: java.lang.ClassNotFoundException: org.apache.tools.ant.taskdefs.optional.net.FTPTaskMirrorImpl at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoa der.java:1386) at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:133 6) at org.apache.tools.ant.util.SplitClassLoader.loadClass(SplitClassLoader .java:52) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at org.apache.tools.ant.taskdefs.optional.net.FTPTask.createMirror(FTPTa sk.java:824) at org.apache.tools.ant.taskdefs.optional.net.FTPTask.setupFTPDelegate(F TPTask.java:804) at org.apache.tools.ant.taskdefs.optional.net.FTPTask.execute(FTPTask.ja va:775) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.jav a:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:390) at org.apache.tools.ant.Target.performTasks(Target.java:411) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1360) at org.apache.tools.ant.Project.executeTarget(Project.java:1329) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExe cutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1212) at org.apache.tools.ant.Main.runBuild(Main.java:775) at org.apache.tools.ant.Main.startAnt(Main.java:217) at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109) When I try to run with a nested classpath WITH ant-commons-net.jar in the nested classpath, this is the error I get: java.lang.IllegalAccessError: tried to access field org.apache.tools.ant.taskdefs.optional.net.FTPTask.ACTION _STRS from class org.apache.tools.ant.taskdefs.optional.net.FTPTaskMirrorImpl at org.apache.tools.ant.taskdefs.optional.net.FTPTaskMirrorImpl.doFTP(FT PTaskMirrorImpl.java:1912) at org.apache.tools.ant.taskdefs.optional.net.FTPTask.execute(FTPTask.ja va:776) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.jav a:106) at org.apache.tools.ant.Task.perform(Task.java:348) at org.apache.tools.ant.Target.execute(Target.java:390) at org.apache.tools.ant.Target.performTasks(Target.java:411) at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1360) at org.apache.tools.ant.Project.executeTarget(Project.java:1329) at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExe cutor.java:41) at org.apache.tools.ant.Project.executeTargets(Project.java:1212) at org.apache.tools.ant.Main.runBuild(Main.java:775) at org.apache.tools.ant.Main.startAnt(Main.java:217) at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280) at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
the behavior without commons-net seems correct, isn't it? For the other case, packages loaded via different classloaders are different packages, so I'll have to change the things needed by FTPTaskMirrorImpl to public. Could you update to svn revision 808398 to see whether it works better then? Many thanks for testing.
Thanks Stefan. The reason I was trying without ant-commons-net.jar was because I saw it already in ANT_HOME/lib. Revision 808398 works for me with a nested classpath of: ant-commons-net.jar commons-net-1.4.0.jar oro-2.0.8.jar It does not work without a nested classpath and the libs copied into ANT_HOME/lib.
it is supposed to work without any nested classpath if the jars are in ANT_HOME/lib, so this is a bug. Most likely mustSplit returns true even if it should not. Will look into it. Thanks again.