JaCoCo for Android - Manual\MonkeyRunner testing

1,318 views
Skip to first unread message

parekh...@gmail.com

unread,
Oct 9, 2013, 8:41:34 PM10/9/13
to jac...@googlegroups.com
How can I generate code coverage data for an Android app using JaCoCo?

I am able to generate instrumented apk using JaCoCo Maven plugin as below:

<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<version>${jacoco-plugin.version}</version>
<classifier>runtime</classifier>
</dependency>

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-plugin.version}</version>
</plugin>

But when I install the app on the device and launch it, it crashes.

I see below in logcat:
D/dalvikvm( 9147): DexOpt: unable to opt direct call 0x6def at 0x23 in Lorg/jacoco/agent/rt/internal_9dd1198/Agent;.shutdown
D/dalvikvm( 9147): DexOpt: unable to opt direct call 0x6df0 at 0x30 in Lorg/jacoco/agent/rt/internal_9dd1198/Agent;.startup
D/dalvikvm( 9147): DexOpt: unable to opt direct call 0x6def at 0x37 in Lorg/jacoco/agent/rt/internal_9dd1198/Agent;.startup
W/System.err( 9147): android.os.NetworkOnMainThreadException
W/System.err( 9147): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)
W/System.err( 9147): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
W/System.err( 9147): at java.net.InetAddress.getLocalHost(InetAddress.java:365)
W/System.err( 9147): at org.jacoco.agent.rt.internal_9dd1198.Agent.createSessionId(Agent.java:179)
W/System.err( 9147): at org.jacoco.agent.rt.internal_9dd1198.Agent.startup(Agent.java:122)
W/System.err( 9147): at org.jacoco.agent.rt.internal_9dd1198.Agent.getInstance(Agent.java:56)
W/System.err( 9147): at org.jacoco.agent.rt.internal_9dd1198.Offline.<clinit>(Offline.java:31)
W/System.err( 9147): at {app_ID}.MainApplication.$jacocoInit(MainApplication.java)
W/System.err( 9147): at {app_ID}.MainApplication.<clinit>(MainApplication.java)
W/System.err( 9147): at java.lang.Class.newInstanceImpl(Native Method)
....
W/System.err( 9147): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
W/System.err( 9147): at dalvik.system.NativeStart.main(Native Method)

Any help would be greatly appreciated.

Thanks!

Marc R. Hoffmann

unread,
Oct 10, 2013, 12:33:21 AM10/10/13
to jac...@googlegroups.com
Hi,

this is a known issue that has been fixed, but not yet released:

https://github.com/jacoco/jacoco/issues/113

For now you kan use the latest snapshot builds

Best regards,
-marc

parekh...@gmail.com

unread,
Oct 10, 2013, 8:31:07 PM10/10/13
to jac...@googlegroups.com
Thanks Marc for your response. Using snapshot build, I was able to overcome Strict mode issue.

I have now run into another issue:
java.io.FileNotFoundException: /jacoco.exec: open failed: EROFS (Read-only file system)

I found below thread and see that it's resolved using offline instrumentation.
https://github.com/jacoco/jacoco/pull/58

On reading (http://www.eclemma.org/jacoco/trunk/doc/offline.html), I realized that I need to specify path for jacoco-agent.destfile. I tried updating the config as below, but I still see the same error. Since I am trying to get run the test manully, I can't set this property as part of some test run.

<build>
<plugins>


<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-plugin.version}</version>

<configuration>
<systemPropertyVariables>
****** <jacoco-agent.destfile>sdcard/jacoco.exec</jacoco-agent.destfile> ******
</systemPropertyVariables>
</configuration>
<executions>
<execution>
<id>instrument-classes</id>
<goals>
<goal>instrument</goal>
</goals>
<configuration>
<excludes>
<exclude>*test*</exclude>
<exclude>*/test/*</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>restore-instrumented-classes</id>
<phase>package</phase>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
</executions>
</plugin>


Thanks,
Rahul

Marc R. Hoffmann

unread,
Oct 11, 2013, 12:25:14 AM10/11/13
to jac...@googlegroups.com
Hi,

I don't think you can set system properties this way on the target device. What you do is to deploy a
jacoco-agent.properties file with your test app containing the settings. Here is a example project for code coverage on Android:

  https://github.com/Godin/jacoco-experiments/tree/android/android

Best regards,
-marc

parekh...@gmail.com

unread,
Oct 11, 2013, 10:09:21 AM10/11/13
to jac...@googlegroups.com
Hi Marc,

I am new to both Maven and Android, could you please tell me the steps for deploying jacoco-agent.properties with the app. I looked at the example project you mentioned, but wasn't able to figure out how jacoco-agent.properties was packaged and deployed.

Thanks,
Rahul

Marc R. Hoffmann

unread,
Oct 11, 2013, 1:06:08 PM10/11/13
to jac...@googlegroups.com
Hi Rahul,

we cannot provide general support for Android development here. I would
recommend to ask the question about test resources at a Android forum.

Best regards,
-marc

parekh...@gmail.com

unread,
Oct 16, 2013, 7:38:03 PM10/16/13
to jac...@googlegroups.com
Hi Marc,

To deploy jacoco-agent.properties with the app, I took below steps:

1. Updated Pom.xml of the main app to include <resources>:

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>src/main/resources/jacoco-agent.properties</include>
</includes>
</resource>
</resources>


<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-plugin.version}</version>

<executions>
<execution>
<id>instrument-classes</id>
<goals>
<goal>instrument</goal>
</goals>
<configuration>
<excludes>
<exclude>*test*</exclude>
<exclude>*/test/*</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>restore-instrumented-classes</id>
<phase>package</phase>
<goals>
<goal>restore-instrumented-classes</goal>
</goals>
</execution>
</executions>
</plugin>

2. Copied: jacoco-agent.properties to src/main/resources

I am doing all these changes in the main app. Since I am trying to get code coverage for manual testing, I have not other test project.

----

For MonkeyRunner tests, they run outside the maven configuration. I these tests are called from terminal.

I tried supplying jacocoagent at runtime, using below command:

$ANDROID_HOME/tools/monkeyrunner -u -PATH_TO_TEST/test_runner.py -javaagent:/Users/username/Desktop/AndroidCodeCoverage/jacoco-0.6.4-20131014.021613-14/lib/jacocoagent.jar=destfile=/sdcard/jacoco.exec

----
In both scenario, I am seeing the same error as before:

D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6def at 0x23 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.shutdown
D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6df0 at 0x30 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6def at 0x37 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
W/System.err(28814): java.io.FileNotFoundException: /jacoco.exec: open failed: EROFS (Read-only file system)
W/System.err(28814): at libcore.io.IoBridge.open(IoBridge.java:416)
W/System.err(28814): at java.io.FileOutputStream.<init>(FileOutputStream.java:88)


Really appreciate you take a look at this.

Thanks,
Rahul

Marc R. Hoffmann

unread,
Oct 17, 2013, 12:23:17 AM10/17/13
to jac...@googlegroups.com
Hi,

1) What is the content of your jacoco-agent.properties file?
2) Please do not specify another JaCoCo agent on the command line if it
is already deployed with the app

Cheers,
-marc

Rahul Parekh

unread,
Oct 17, 2013, 2:31:01 AM10/17/13
to jac...@googlegroups.com
Hi Marc,

Below is the content of jacoco-agent.properties file:

destfile=/sdcard/jacoco.exec
append=true
dumponexit=true
output=file

Got your 2nd point about not specifying JaCoCo agent from command line.

Thanks,
Rahul


--
You received this message because you are subscribed to a topic in the Google Groups "JaCoCo and EclEmma Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jacoco/9Atzd4Kq0NU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jacoco+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Marc Hoffmann

unread,
Oct 17, 2013, 4:25:04 AM10/17/13
to jac...@googlegroups.com
So, what happens if you remove the agent from the command line?
You received this message because you are subscribed to the Google Groups "JaCoCo and EclEmma Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jacoco+un...@googlegroups.com.

parekh...@gmail.com

unread,
Oct 17, 2013, 10:14:14 AM10/17/13
to jac...@googlegroups.com
If I don't pass the agent via command line, I get the same error. It appears as if it's not able to see the jacoco-agent.properties file.

One reason I thought this could be happening is because all the other resource files for the app are located under: ${project.basedir}/res

Where I created new folders under ${project.basedir}/src for main/resources. So at this point ${project.basedir}/src/main/resources has just the jacoco-agent.properties file.

I had tried to put jacoco-agent.properties file under res/raw, but it complained about the "-" in the file name.

Below is the error I am seeing (same as before):

D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6def at 0x23 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.shutdown
D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6df0 at 0x30 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
D/dalvikvm(28814): DexOpt: unable to opt direct call 0x6def at 0x37 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
W/System.err(28814): java.io.FileNotFoundException: /jacoco.exec: open failed: EROFS (Read-only file system)
W/System.err(28814): at libcore.io.IoBridge.open(IoBridge.java:416)
W/System.err(28814): at java.io.FileOutputStream.<init>(FileOutputStream.java:88)


Thanks.
Rahul
> To unsubscribe from this group and all its topics, send an email to jacoco+un...@googlegroups.com.

parekh...@gmail.com

unread,
Oct 17, 2013, 7:38:13 PM10/17/13
to jac...@googlegroups.com, parekh...@gmail.com
Please ignore my earlier comment. I made below change and it seems that jacoco-agent.properties is getting in play now.

<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
*** <include>jacoco-agent.properties</include> ***
</includes>
</resource>
</resources>

Now I am seeing below error:
D/dalvikvm(13350): DexOpt: unable to opt direct call 0x6def at 0x23 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.shutdown
D/dalvikvm(13350): DexOpt: unable to opt direct call 0x6df0 at 0x30 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
D/dalvikvm(13350): DexOpt: unable to opt direct call 0x6def at 0x37 in Lorg/jacoco/agent/rt/internal_3d5ada2/Agent;.startup
D/KeyguardViewMediator( 2017): setHidden false
D/WindowManager( 2017): mInputFocus is not null.
D/WindowManager( 2017): mInputFocus is not null.
W/dalvikvm(13350): VFY: invoke type does not match method type of LCLASS_PATH;._getINFO
W/dalvikvm(13350): VFY: rejecting opcode 0x6f at 0x0005
W/dalvikvm(13350): VFY: rejected LCLASS_PATH;._getSOME_THING ()LABC;
W/dalvikvm(13350): Verifier rejected class LABC;
D/AndroidRuntime(13350): Shutting down VM
W/dalvikvm(13350): threadid=1: thread exiting with uncaught exception (group=0x41eae2a0)
E/AndroidRuntime(13350): FATAL EXCEPTION: main
E/AndroidRuntime(13350): java.lang.RuntimeException: Unable to create application PATH.MainApplication: java.lang.IllegalStateException: Could not construct instance of helper class class com...

Googling a bit, I found below link and it seems that this could be happening during to a missing external lib.
https://code.google.com/p/android/issues/detail?id=23672

I tried including jacocoagent.jar in the resource section above and build failed with below error, as jacoco agent was already there.

[DEBUG] Adding dex input: /Users/username/.m2/repository/com/google/guava/guava/14.0.1/guava-14.0.1.jar
[INFO] /Library/Java/JavaVirtualMachines/jdk1.7.0_40.jdk/Contents/Home/jre/bin/java [-Xmx1024M, -jar, /Users/username/Softwares/sdk/build-tools/17.0.0/lib/dx.jar, --dex, --output=/Users/username/PATH/target/classes.dex, /Users/username/PATH/target/classes, /Users/username/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar, /Users/username/.m2/repository/org/jacoco/org.jacoco.agent/0.6.4-SNAPSHOT/org.jacoco.agent-0.6.4-SNAPSHOT-runtime.jar, /Users/username/.m2/repository/com/squareup/javawriter/1.0.5/javawriter-1.0.5.jar, /Users/username/.m2/repository/com/j256/ormlite/ormlite-android/4.45/ormlite-android-4.45.jar, /Users/username/.m2/repository/com/amazon/inapp/purchasing/amazon-in-app-purchasing/1.0.3/amazon-in-app-purchasing-1.0.3.jar, /Users/username/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar, /Users/username/.m2/repository/com/squareup/dagger/dagger/1.0.1/dagger-1.0.1.jar, /Users/username/.m2/repository/com/j256/ormlite/ormlite-core/4.45/ormlite-core-4.45.jar, /Users/username/.m2/repository/com/squareup/dagger/dagger-compiler/1.0.1/dagger-compiler-1.0.1.jar, /Users/username/.m2/repository/android/support/compatibility-v4/18/compatibility-v4-18.jar, /Users/username/.m2/repository/com/google/guava/guava/14.0.1/guava-14.0.1.jar]
[INFO]
[INFO] UNEXPECTED TOP-LEVEL EXCEPTION:
[INFO] java.lang.IllegalArgumentException: already added: Lcom/vladium/emma/rt/RT;
[INFO] at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:123)
[INFO] at com.android.dx.dex.file.DexFile.add(DexFile.java:163)
[INFO] at com.android.dx.command.dexer.Main.processClass(Main.java:490)
[INFO] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459)
[INFO] at com.android.dx.command.dexer.Main.access$400(Main.java:67)
[INFO] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:245)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:131)
[INFO] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
[INFO] at com.android.dx.command.dexer.Main.processOne(Main.java:422)
[INFO] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333)
[INFO] at com.android.dx.command.dexer.Main.run(Main.java:209)
[INFO] at com.android.dx.command.dexer.Main.main(Main.java:174)
[INFO] at com.android.dx.command.Main.main(Main.java:91)
[INFO] 1 error; aborting


Thanks again for looking into this.
- Rahul

Marc R. Hoffmann

unread,
Oct 18, 2013, 12:23:50 AM10/18/13
to jac...@googlegroups.com
Hi,

what version of JaCoCo are you using? JaCoCo 0.6.3 does not support
Adroid strict mode, please try 0.6.4, see this issue:

https://github.com/jacoco/jacoco/issues/113

Cheers,
-marc
--
Marc Hoffmann
hoff...@mountainminds.com
_______________________________________________
Mountainminds GmbH & Co. KG

Nussbaumstr. 4 * 80336 Muenchen * Germany
Phone/Fax +49-700-68664637 * 0700-MTNMINDS

Registergericht Muenchen * HRA 80201
Mountainminds Verwaltungs GmbH
Registergericht Muenchen * HRB 143183
Geschaeftsfuehrer Marc Hoffmann


parekh...@gmail.com

unread,
Oct 18, 2013, 1:00:12 AM10/18/13
to jac...@googlegroups.com
Hi Marc,

I am using 0.6.4-SNAPSHOT. Below are relevant pieces of my POM setup.

Also, when I tried deploying jacocoagent.jar using <Resource> it gave an error message which included (full error message in my previous reply):

*** /Users/username/.m2/repository/org/jacoco/org.jacoco.agent/0.6.4-SNAPSHOT/org.jacoco.agent-0.6.4-SNAPSHOT-runtime.jar, ***


POM:

<pluginRepositories>
<pluginRepository>
<id>jacoco.snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots> <enabled>true</enabled> </snapshots>
</pluginRepository>
</pluginRepositories>

Properties:
<jacoco-plugin.version>0.6.4-SNAPSHOT</jacoco-plugin.version>

Dependency management:

<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<version>${jacoco-plugin.version}</version>
<classifier>runtime</classifier>
</dependency>

Plugin:
Thanks again,
Rahul

On Thursday, October 17, 2013 9:23:50 PM UTC-7, Marc R. Hoffmann wrote:
> Hi,
>
>
>

parekh...@gmail.com

unread,
Oct 20, 2013, 8:16:49 PM10/20/13
to jac...@googlegroups.com, parekh...@gmail.com
Hi Marc,

One thing I had forgot to mention in earlier reply is, jacoco.exec is being generated under sdcard, but it's size is 0 bytes. So jacoco-agent.properties file is definitely having an impact!

Thanks,
Rahul
Reply all
Reply to author
Forward
This conversation is locked
You cannot reply and perform actions on locked conversations.
0 new messages