Ant imports & taskdefs - failed to create task or type junit

I’m a complete gradle newbie and I’m trying to import an ant file and invoke one of it’s targets that happens to do some junit stuff. Apparently I’m loading up the taskdef properly but I’m clueless.

  • Gradle uses its own ‘instance’ of ant and does not bother using what’s installed at $ANT_HOME, yes?

  • Should the build.gradle below work?

defaultTasks = ['smoke']
  project(':foo-webapp'){
      repositories{
        mavenCentral()
    }
    configurations {
        antClasspath
    }
    dependencies {
        antClasspath 'org.apache.ant:ant-junit4:1.8.3'
    }
    ClassLoader antClassLoader = org.apache.tools.ant.Project.class.classLoader
    configurations.antClasspath.each { File f ->
        println('[Dependencies] ' + f.toURI().toURL())
        antClassLoader.addURL(f.toURI().toURL())
    }
      ant.importBuild 'test/bug.xml'
  }

Error:

C02LG18JF1G3:zuora revans$ ./gradlew smoke [Dependencies] file:/Users/objectiveous/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant-junit4/1.8.3/5c021fdf73b2561d55130e6c8d4dd495c3dfb8e7/ant-junit4-1.8.3.jar [Dependencies] file:/Users/objectiveous/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant/1.8.3/77c746ecab048b9839c7a8e39e55fe8636c5b11/ant-1.8.3.jar [Dependencies] file:/Users/objectiveous/.gradle/caches/modules-2/files-2.1/junit/junit/4.8.1/f2975548f836416306ef1dee748d956f04733915/junit-4.8.1.jar [Dependencies] file:/Users/objectiveous/.gradle/caches/modules-2/files-2.1/org.apache.ant/ant-launcher/1.8.3/a22bcf9438c41828b04c13b052c4886606abac2/ant-launcher-1.8.3.jar :Zuora-webapp:smoke FAILED

FAILURE: Build failed with an exception.

  • What went wrong: Execution failed for task ‘:foo-webapp:smoke’. > Problem: failed to create task or type junit

Cause: the class org.apache.tools.ant.taskdefs.optional.junit.JUnitTask was not found.

This looks like one of Ant’s optional components.

Action: Check that the appropriate optional JAR exists in

-ANT_HOME/lib

-the IDE Ant configuration dialogs

Do not panic, this is a common problem.

The commonest cause is a missing JAR.

This is not a bug; it is a configuration problem

  • Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 2.77 secs

Gradle uses its own ‘instance’ of ant and does not bother using what’s installed at $ANT_HOME, yes?

Correct.

Should the build.gradle below work?

Not necessarily.

What’s in the ant build?

Thanks for the reply, Luke. I’ve been meaning to get this sample into a github repo for easy troubleshooting but in the mean time, here’s what my ant target looks like. In a nutshell, I’m just trying to call a target that runs some unit tests via junit.

Any info you can provide would be appreciated.

<target name="smoke" description="smoke testing JUnit">
       <junit forkmode="perBatch" printsummary="on" haltonfailure="off" haltonerror="off">
    <jvmarg value="-XX:MaxPermSize=256M" />
    <jvmarg value="-Xmx2048M" />
      <batchtest fork="yes" todir="/tmp">
              <fileset dir='/Users/objectiveous/IdeaProjects/zuora/Zuora-webapp/test/classes'>
     <include name="**/SmokeTestSuite.class" />
           </fileset>
    </batchtest>
  </junit>
</target>

Check this userguide section: http://www.gradle.org/docs/current/userguide/ant.html#N113EE

For examples of registering non core tasks.

JUnit is an optional task in Ant. Usually, you add the JUnit library and the library containing the JUnit task to Ant’s lib directory to make it work. Gradle ships with Ant and uses the Ant libraries contained in the Gradle distribution. Gradle does not come with the JUnit task so you need to declare it in your build script.

To reuse an Ant task that uses the JUnit task, you will have to declare the Ant task definition in Gradle. The following example shows how to retrieve the JUnit libraries from Maven Central by assigning them to a custom configuration.

repositories {
    mavenCentral()
}
  configurations {
    junitAnt
}
  dependencies {
    junitAnt 'junit:junit:4.8.2'
    junitAnt('org.apache.ant:ant-junit:1.9.2') {
        transitive = false
    }
    junitAnt('org.apache.ant:ant-junit4:1.9.2') {
        transitive = false
     }
   }
  ant.taskdef(name: 'junit', classname: 'org.apache.tools.ant.taskdefs.optional.junit.JUnitTask',
             classpath: configurations.junitAnt.asPath)
ant.importBuild 'build.xml'

Benjamin,

I’m trying to wrap my ant build.xml file which uses junit and i tried your solution and I get this error:

Could not resolve all dependencies for configuration ‘:junitAnt’. . . .

I believe this is because the taskdef is being called in the configuration phase (dependencies have not been resolved yet). Any ideas on how to fix this?

You are likely not defining a repository.

I have a multi-project build and have an artifactory repo setup. All of my subprojects are able to resolve the dependencies except for this one… not exactly sure why. Although this is the only one where I’m wrapping an ant script like this. I did redefine the repo in my subproject’s build.gradle file and it seems to resolve the dependencies fine.

I was curious though and went back removed the respository definition from my subproject’s build script. I added the taskdef to an execution task and it was able to resolve just fine. I’m guessing this might be a bug with the artifactory plugin?

I’d have to see your build code to get an idea of what’s going wrong. If you want to discuss this further, please open a question and post/link your source code.

Benjamin: did you put this in the buildscript section? The place where I’ll be calling the JUnit task is defined in the subproject section. Is that the correct place to put this code instead if not the buildscript section

This does not go into the buildscript block. To fully understand your question, I think I’d need to see your code.

I would include my code if it wasn’t so confusing… I think it would do more harm than good at this point. However…

It seemed to me that running Ant tasks would be part of the “build” code, and therefore would use the buildscript block. I’ve put your examples in my subproject block, and made considerable progress.

My last step… I’m running tests in the Subproject, but my Test classes (compiled… thus the Ant task instead of a Test task) reside in the root project. I’d like to be able to reuse the jar sitting in the libs directory of the root project for all the subprojects. So I need to reference (I believe) a fileTree in {rootDir}/libs to make the test jar available. Does this make senses?

I really appreciate the help. I was banging my head before seeing your code snippets.

Sorry, I can’t follow. Can you put a minimalistic code example on GitHub that demonstrates your issue?

Working on it. Thanks Benjamin.

I got my issue resolved. I’m working on the test case for posterity sake… maybe it will help some one.