views:

43

answers:

3

I'm trying to upload a file using an Ant task. If I use Ant directly the file is uploaded, but if I call the ant task via Maven (using the maven-antrun-plugin) I get the following error:

An Ant BuildException has occured: The following error occurred while executing this line:

/home/me/proj/build.xml:15: Problem: failed to create task or type ftp
Cause: the class org.apache.tools.ant.taskdefs.optional.net.FTP was not found.
    This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
    -ANT_HOME/lib

ant-commonsnet.jar is clearly available to Ant:

$ ls $ANT_HOME/lib | grep ant-commons-net
ant-commons-net.jar

Is the Ant classpath defined separately for maven-antrun-plugin, or am I missing something?

A: 

There is a classpath property which can be set in <tasks> section of maven-antrun-plugin.

For instance,

<property name="classpath" refid="maven.compile.classpath"/>
Raghuram
+3  A: 

ant-commons-net.jar is clearly available to Ant

Yes, but Maven and the maven-antrun-plugin is not using your local Ant install.

Is the Ant classpath defined separately for maven-antrun-plugin, or am I missing something?

The way to use Ant Tasks not included in Ant's default jar is documented in Using tasks not included in Ant's default jar (which should definitely help):

To use Ant tasks not included in the Ant jar, like Ant optional or custom tasks you need to add the dependencies needed for the task to run to the plugin classpath and use the maven.plugin.classpath reference if needed.

<project>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-test-app</artifactId>
  <groupId>my-test-group</groupId>
  <version>1.0-SNAPSHOT</version>

  <build>
    <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-antrun-plugin</artifactId>
         <version>1.6</version>
         <executions>
           <execution>
             <id>ftp</id>
             <phase>deploy</phase>
             <configuration>
               <target>

                 <ftp action="send" server="myhost" remotedir="/home/test" userid="x" password="y" depends="yes" verbose="yes">
                   <fileset dir="${project.build.directory}">
                     <include name="*.jar" />
                   </fileset>
                 </ftp>

                 <taskdef name="myTask" classname="com.acme.MyTask" classpathref="maven.plugin.classpath"/>
                 <myTask a="b"/>

               </target>
             </configuration>
             <goals>
               <goal>run</goal>
             </goals>
           </execution>
         </executions>
         <dependencies>
           <dependency>
             <groupId>commons-net</groupId>
             <artifactId>commons-net</artifactId>
             <version>1.4.1</version>
           </dependency>
           <dependency>
             <groupId>ant</groupId>
             <artifactId>ant-commons-net</artifactId>
             <version>1.6.5</version>
           </dependency>
           <dependency>
             <groupId>ant</groupId>
             <artifactId>ant-nodeps</artifactId>
             <version>1.6.5</version>
           </dependency>
         </dependencies>
       </plugin>
    </plugins>
  </build>
</project>
Pascal Thivent
This is the right approach. The only things I would suggest doing differently is:1) specifying the `ant` groupId instead as `org.apache.ant` as this is what Maven plugins reference internally.
Tim Clemons
If this is a multi-module project, you should also consider adding the dependencies to a pluginManagement section within the root project pom. This will prevent other references to antrun in your project from clobbering your dependencies.
Tim Clemons
@Tim Indeed, [as of version 1.7.0](http://mvnrepository.com/artifact/org.apache.ant/ant-commons-net) of `ant-commons-net`, the `groupId` is `org.apache.ant` but the above one is correct for version 1.6.5. In other words, adapt it if you want to use a more recent version. And you're of course right about the `pluginManagement` section. I'll update my answer to mention that... tomorrow :) Thanks for both comments!
Pascal Thivent
A: 

As Pascal has mentioned, the maven-antrun-plugin is not using the ant specified by your $ANT_HOME environment variable, and the configuration that he's mentioned is probably the best way to do it consistently from a pure maven perspective.

However, the jar can be stored in $USER_HOME/.ant/lib instead of $ANT_HOME/lib, these jars should be available on the classpath for any instance of ant that is run by that user.

Note that your ant script cannot assume that the jars are present, and that the jars are only placed on the classpath at startup, so if the script defines a setup target to download the jars into $USER_HOME/.ant/lib, then this target would have to be run in a "separate-ant-session", before and is invoked again to execute the task that depends on the jar.

The only potential benefit that you may derive from this approach is that the Ant script may be runnable from maven and Ant.

crowne