Search code examples
antftpant-contrib

ANT FTP task throws strange error


I had an issue with the ftp task in ANT 1.9.1

here is my ftp macrodef:

  <target name="checkAntCommons">
          <!-- Test if ant commons-net jar is present -->
          <echo message="checking for ${ant.library.dir}/commons-net-1.4.1.jar"/>
          <if>
            <available file="${ant.library.dir}/commons-net-1.4.1.jar" type="file" />
            <then>
                 <echo message="ANT commons-net library is available"/>
            </then>
            <else>
              <echo message="ANT commons-net library is not available" />
                 <copy file="${ANT_ROOT}/commons-net-1.4.1/commons-net-1.4.1.jar" todir="${ant.library.dir}"/>
                 <fail status="0" message="Must re-run build for changes to take effect" />
            </else>
          </if>
   </target>
   <target name="checkJakartaOro">
          <!-- Test if ant jakarta-oro jar is present -->
          <echo message="checking for ${ant.library.dir}/jakarta-oro-2.0.8.jar"/>
          <if>
            <available file="${ant.library.dir}/jakarta-oro-2.0.8.jar" type="file" />
            <then>
                 <echo message="jakarta-oro library is available"/>
            </then>
            <else>
              <echo message="jakarta-oro library is not available" />
                 <copy file="${ANT_ROOT}/jakarta-oro-2.0.8/jakarta-oro-2.0.8.jar" todir="${ant.library.dir}"/>
                 <fail status="0" message="Must re-run build for changes to take effect" />
            </else>
          </if>
   </target>

<macrodef name="deploySite" description="Deploy site files to ftp">
    <sequential>
        <antcall target="checkAntCommons"/>
        <antcall target="checkJakartaOro"/>
        <ftp userid="*******" password="*******" 
            server=***.***.***.***" 
            remotedir="/site/assets/foo"
            port="21"
            verbose="true"
            action="send"
            passive="yes"
            systemTypeKey="UNIX"
            >
            <fileset dir="./deploy">
                <includesfile name="deploy/foo.swf"/>
            </fileset>
        </ftp>
    </sequential>
</macrodef>
<target name="deploy" description="deploy foo files">
    <deploySite/>
</target>

I know that i successfully connect to my server because I get a login error if i change the password, and i get my problem if i put the right password. I also connect via filezilla all the time. it is not an issue of concurrent connections, because i have no limit.

when i run this task i get the following output:

$ ant deploy
Buildfile: f:\var\projects\hof\svn2.-----------------.com\lobby\trunk\build.xml

deploy:

checkAntCommons:
     [echo] checking for F:\bin\ant\lib/commons-net-1.4.1.jar
     [echo] ANT commons-net library is available

checkJakartaOro:
     [echo] checking for F:\bin\ant\lib/jakarta-oro-2.0.8.jar
     [echo] jakarta-oro library is available
      [ftp] sending files

BUILD FAILED
f:\var\projects\hof\svn2.-----------------------.com\lobby\trunk\build.xml:324: The following error occurred while executing this line:
f:\var\projects\hof\svn2.-----------------------.com\lobby\trunk\build.xml:309: Syntax error in property: ${ c6W∟5⌂[6▄≈☻wä5↓╚╞K▐Bd≡6?k╥<╞:èbE▒9≡'╗î£Θ┼è├≤╘r≤?öæCu½╞╖§Σ ç▓(σⁿ.?n≡PßΘéK┼ ΣRq!╣T,ò■Ä╠W3║»æ ?√i
╩↑↓UQa{σ▼î¼≈Lpt■┼Ç☻/α┐┘D`╬!`8&├ òƒ Üj▲?╔  1Q.ô²¢┴┌Ça£∙▒∙Oækñcl╜vÑl^)w╠G╒╠gäêyPε╘╟7░═µu╚¡I┐N6»º4%▒ƺ≥á=⌂î5←7╚µ

Total time: 3 seconds

I have absolutely NO variables in my macrodef. It appears to me that for some reason ANT is trying to parse replacements in the binary data of the file I'm trying to transfer.

So after much trial and error, I found the cause. The answer is below!


Solution

  • The answer is that the fileset element was wrong:

    <fileset dir="./deploy">
        <includesfile name="deploy/foo.swf"/>
    </fileset>
    

    The element was somehow reading garbage, and thus resulted in a totally unpredictable response from the ant task.

    do it like this:

    <fileset>
        <include name="@{file-name}"/>
    </fileset>
    

    the final working solution is:

    <macrodef name="deployFile" description="Deploy foo to *******">
        <attribute name="file-name" default="none" />
        <attribute name="path" default="." />
        <attribute name="remote-dir" default="." />
        <sequential>
            <property name="needToResend" value="false"/>
            <antcall target="checkAntCommons"/>
            <antcall target="checkJakartaOro"/>
            <trycatch>
                <try>
                    <echo message="trying to upload ${basedir}/@{path}/@{file-name} to @{remote-dir}"/> 
                    <sendFTPFile file-name="@{file-name}" path="${basedir}/@{path}" remote-dir="@{remote-dir}"/>
                </try>
                <catch>
                    <echo message="${basedir}/@{path}/@{file-name} exists in @{remote-dir}"/> 
                    <deleteFTPFile file-name="@{file-name}" remote-dir="@{remote-dir}"/>
                    <property name="needToResend" value="true"/>
                </catch>
            </trycatch>
            <if>
                <equals arg1="${needToResend}" arg2="true"/>
                <then>
                    <echo message="re-uploading ${basedir}/@{path}/@{file-name} to @{remote-dir}"/> 
                    <sendFTPFile file-name="@{file-name}" path="${basedir}/@{path}" todir="@{remote-dir}"/>
                </then>
            </if>
        </sequential>
    </macrodef>
    <macrodef name="sendFTPFile" description="send a file to FTP">
        <attribute name="file-name" default="none" />
        <attribute name="path" default="." />
        <attribute name="remote-dir" default="." />
        <sequential>
            <echo message="sending @{path}/@{file-name} to @{remote-dir}"/>
            <ftp userid="****" password="********" 
                server="***.***.***.***" 
                remotedir="@{remote-dir}"
                port="21"
                verbose="true"
                action="send"
                passive="yes"
                systemTypeKey="UNIX"
                ignorenoncriticalerrors="true"
                >
                <fileset dir="@{path}">
                    <include name="@{file-name}"/>
                </fileset>
            </ftp>
        </sequential>
    </macrodef>
    <macrodef name="deploySite">
        <sequential>
            <deployFile file-name="foo.bar" path="${DEPLOY_DIR}" remote-dir="/foo/bar/baz"/>
            <deployFile file-name="*.bar" path="${DEPLOY_DIR}/blah" remote-dir="/foo/bar/baz/blah"/>
        </sequential>
    </macrodef>