title: jacoco+gradle taskdef A class needed by class org.jacoco.ant.InstrumentTask canno t be found
body: <p>I'm trying to get jacoco+gradle work together. Looking at this forum it seems some people have successfully done that. But when I tried I got a strange exception.</p>
  
  <p>What I did:</p>
  
  <p>1.Downloaded gradle 2.2.1 and configured env variables, etc.</p>
  
  <p>2.Downloaded jacoco 0.7.1 from   <a href="http://www.eclemma.org/jacoco/" rel="nofollow">http://www.eclemma.org/jacoco/</a></p>
  
  <p>3.added:</p>
  
  <pre><code> apply plugin: 'jacoco'
  </code></pre>
  
  <p>and</p>
  
  <pre><code> buildTypes {
           debug
  {
           testCoverageEnabled true
  ...
  </code></pre>
  
  <p>in the build.gradle</p>
  
  <p>4.run gradle build</p>
  
  <p>5.I got an error saying the jacoco agent jar cannot be found, etc. Error message showed it tried to search files under C:\Program Files (x86)\Android\android-sdk\extras\android\m2repository... etc.</p>
  
  <p>6.I manually unzipped the jacoco jar files and put them in the place where the error message mentioned and the error message disappeared.</p>
  
  <p>7.Then I ran gradle build. I got the following new error when running the built-in instrumentDebug task:</p>
  
  <pre><code>Caused by: : taskdef A class needed by class org.jacoco.ant.InstrumentTask cannot be found: org/jacoco/core/runtime/IExecutionDataAccessorGenerator using the classloader AntClassLoader[C:\Program Files (x86)\Android\android-sdk\extras\android\m2repository\org\jacoco\org.jacoco.ant\0.7.1.201405082137\org.jacoco.ant-0.7.1.201405082137.jar]
      at org.apache.tools.ant.taskdefs.Definer.addDefinition(Definer.java:612)
  
      at org.apache.tools.ant.taskdefs.Definer.execute(Definer.java:237)
      at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
      at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
      at org.gradle.api.internal.project.ant.BasicAntBuilder.nodeCompleted(BasicAntBuilder.java:77)
      at org.gradle.api.internal.project.ant.BasicAntBuilder.doInvokeMethod(BasicAntBuilder.java:92)
      at com.android.build.gradle.internal.coverage.JacocoInstrumentTask.instrument(JacocoInstrumentask.groovy:51)
      at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
      at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.doExecute(AnnotationProcessingTaskFactory.java:218)
      at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
  
  
  Caused by: java.lang.ClassNotFoundException: 
  
      at org.jacoco.core.runtime.IExecutionDataAccessorGenerator
      at org.apache.tools.ant.AntClassLoader.findClassInComponents(AntClassLoader.java:1366)
      at org.apache.tools.ant.AntClassLoader.findClass(AntClassLoader.java:1315)
      at org.apache.tools.ant.AntClassLoader.loadClass(AntClassLoader.java:1068)...
  </code></pre>
  
  <p>When I used process monitor (My dev machine is Win 7), I saw there was no access to org.jacoco.core-0.7.1.201405082137.jar,which the org.jacoco.ant.InstrumentTask class resides in. So I think the gradle did not pass the file path to org.apache.tools.ant.AntClassLoader correctly.</p>
  
  <p>I have tried below ways but none of them worked:</p>
  
  <ol>
  <li>Add all jacoco jar files to CLASSPATH environment variable.</li>
  <li>Add the jacoco jar files to ant libs, gradle libs,gradle libs/plugins, folder.</li>
  <li>Look at source code of gradle 2.2.1. Clueless at this moment...</li>
  </ol>
  
  <p>Does anyone know how to resolve this problem?</p>
  
  <p>Thanks in advance!</p>
  
  <p><strong>Edit:</strong></p>
  
  <p><strong>The main purpose is to:</strong></p>
  
  <p><strong>1. Let jacoco build an instrumented apk file</strong></p>
  
  <p><strong>2. Manually test the apk file (Not auto test)</strong></p>
  
  <p><strong>3. Let jacoco generate coverage report</strong></p>
  
  <p><strong>Update:</strong>
  I just found when executing InstrumentDebug task, the gradle starts a new process with below command:</p>
  
  <p>"C:\Program Files\Java\jdk1.8.0_25\bin\java.exe" -XX:MaxPermSize=512m -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country=CN -Duser.language=zh -Duser.variant -cp D:\gradle-2.2.1\gradle-2.2.1\lib\gradle-launcher-2.2.1.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 2.2.1 D:\gradle-2.2.1\gradle-2.2.1\daemon 120000 744501ac-32c1-4930-82bd-59e0a9e2b92d -XX:MaxPermSize=512m -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country=CN -Duser.language=zh -Duser.variant</p>
  
  <p>As you can see the class path is hard coded, which overwrites what defined in environment variable. So the required core lib of jacoco could not be found and thus caused this problem. I'm now trying to see where this process is started and whether there is a way to change the -cp option.</p>
  
  <p><strong>Update2:</strong>
  I finally found this process is started by gradle-launcher-2.2.1.jar. See below code. I'm now trying to see whether it's possible to change DefaultModuleRegistry and make registry.getGradleHome() == null. <strong>In the meantime could anyone who has successfully used jacoco+gradle tell me which version of gradle are you using?</strong></p>
  
  <pre><code>public DaemonStartupInfo startDaemon()
  {
  DefaultModuleRegistry registry = new DefaultModuleRegistry();
  Set&lt;File&gt; bootstrapClasspath = new LinkedHashSet();
  bootstrapClasspath.addAll(registry.getModule("gradle-launcher").getImplementationClasspath().getAsFiles());
  if (registry.getGradleHome() == null) 
  {
    bootstrapClasspath.addAll(registry.getFullClasspath());
  }
  if (bootstrapClasspath.isEmpty()) {
    throw new IllegalStateException("Unable to construct a bootstrap classpath when starting the daemon");
  }    
  new JvmVersionValidator().validate(this.daemonParameters);
  List&lt;String&gt; daemonArgs = new ArrayList();
  daemonArgs.add(this.daemonParameters.getEffectiveJavaExecutable());
  List&lt;String&gt; daemonOpts = this.daemonParameters.getEffectiveJvmArgs();
  LOGGER.debug("Using daemon opts: {}", daemonOpts);
  daemonArgs.addAll(daemonOpts);
  daemonArgs.add("-cp");
  daemonArgs.add(CollectionUtils.join(File.pathSeparator, bootstrapClasspath));
  daemonArgs.add(GradleDaemon.class.getName());
  daemonArgs.add(GradleVersion.current().getVersion());
  daemonArgs.add(this.daemonDir.getBaseDir().getAbsolutePath());
  daemonArgs.add(String.valueOf(this.daemonParameters.getIdleTimeout()));
  daemonArgs.add(this.daemonParameters.getUid());
  
  ...
  }
  </code></pre>