Bug 45860 - Optional classpath entry support for FTP task
Summary: Optional classpath entry support for FTP task
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Optional Tasks (show other bugs)
Version: 1.7.1
Hardware: All All
: P1 enhancement with 1 vote (vote)
Target Milestone: 1.8.0
Assignee: Ant Notifications List
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2008-09-22 07:35 UTC by Greg Roodt
Modified: 2009-08-27 07:43 UTC (History)
1 user (show)



Attachments
FTPTask extracted out into delegate. (96.80 KB, application/x-zip-compressed)
2008-10-21 09:20 UTC, Greg Roodt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Greg Roodt 2008-09-22 07:35:56 UTC
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.
Comment 1 Greg Roodt 2008-10-21 09:20:57 UTC
Created attachment 22762 [details]
FTPTask extracted out into delegate.
Comment 2 Greg Roodt 2008-10-21 09:25:33 UTC
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?
Comment 3 Stefan Bodewig 2008-10-21 20:43:19 UTC
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.
Comment 4 Robert Flaherty 2008-10-21 22:48:14 UTC
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.
Comment 5 Stefan Bodewig 2009-08-27 03:17:16 UTC
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.
Comment 6 Greg Roodt 2009-08-27 04:54:32 UTC
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)
Comment 7 Stefan Bodewig 2009-08-27 05:31:31 UTC
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.
Comment 8 Greg Roodt 2009-08-27 06:51:13 UTC
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.
Comment 9 Stefan Bodewig 2009-08-27 07:43:35 UTC
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.