Create an instrumented artifact using offline instrumentation with the maven plug-in

2,514 views
Skip to first unread message

Henrik Horneber

unread,
Feb 1, 2013, 11:18:47 AM2/1/13
to jac...@googlegroups.com
Hi everyone,

I'm trying to record coverage of an application using jacoco and its maven offline feature (I cannot use the on-the-fly-instrumentation for a couple of reasons I don't want to go into ;-) ).

I've created an instrumented artifact for my application (see pom-application-instrumented.xml).

That artifact contains the classes from target/generated-classes/jacoco/.
During the build the unit test coverage is recorded to target/jacoco.exec as expected when triggering the build using 'maven -f pom-application-instrumented.xml clean install'.
So I know that some instrumentation happens during this build.

For my integration tests I'm using a dependency on the instrumented application and a dependency on the jacoco-agent (see pom-systemtests.xml).
During the build with 'maven -f pom-system-instrumented.xml clean install', tests are run but no coverage is recorded. No jacoco.exec to be found anywhere.

I'm pretty certain the systemtests should trigger coverage as they currently are exactly the same ones as the unit tests of the application.

Am I archiving the wrong class files (i.e. target/generated-classes/jacoco/ does not actually contain the instrumented classes)? What else might I be missing?

best regards,
Henrik


pom-application-instrumented.xml
pom-systemtests.xml

Marc R. Hoffmann

unread,
Feb 2, 2013, 9:43:38 AM2/2/13
to jac...@googlegroups.com
Hi Henrik,

some remarks about offline instrumentation that may help you to track
down the issue:

1) If you just add the agent to the classpath it has to be activated by
at least one offline instrumented class. If not instrumented class is
executed at all the agent will not be activated and no coverage data
will be written. You can verify whether a class has been actually
instrumented by looking at the class file with e.g. javap and see
whether a field named $jacocoData is present.

2) By default the jacoco.exec file is written to the working directory
of the application under test. Are you sure what the working directory
for your IT is? The output location can be modified by setting the
system property "jacoco-agent.destfile".

3) The java process must terminate normally, otherwise coverage data
cannot be written. For example if you kill the Java process, no exec
file is written.

Best regards,
-marc
> --
> 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.
> For more options, visit https://groups.google.com/groups/opt_out.

Evgeny Mandrikov

unread,
Feb 2, 2013, 6:59:34 PM2/2/13
to jac...@googlegroups.com
Hi,

Maven goal "instrument" replaces original classes in "target/classes/" by instrumented and stores original classes in "target/generated-classes/jacoco/" in order to be able to restore them back by using goal "restore-instrumented-classes" so that in a typical Maven scenario original classes can be packaged into jar. Thus if you want to create an artifact with instrumented classes, then you should package "target/classes/" (instead of "target/generated-classes/jacoco/") before "restore-instrumented-classes". Hope this will help.

Evgeny Mandrikov

unread,
Feb 2, 2013, 7:01:19 PM2/2/13
to jac...@googlegroups.com
Also keep in mind that in order to generate report JaCoCo requires original (not instrumented) classes to be analysed.

Henrik Horneber

unread,
Feb 2, 2013, 10:30:38 PM2/2/13
to jac...@googlegroups.com
Hi,

so I actually packaged the wrong classes! Great, I'm gonna try that on Monday.

Thanks, you guys! :-)


--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
"I find many of the machines of violence very attractive. Tanks, airplanes, warships, especially aircraft carriers."
- 14th Dalai Lama

johann...@gmail.com

unread,
Feb 12, 2013, 3:28:25 AM2/12/13
to jac...@googlegroups.com
Hi,

We are building an android project and seem to have the exact same problem. No jacoco.exec file is generated.

Henrik, did you give it another try?

Evgeny, what do you mean with your reply; if we want jacoco to report coverage, should we package "target/classes/" or "target/generated-classes/jacoco/" ?

Thanks for you help,
Johannes

Henrik Horneber

unread,
Feb 12, 2013, 4:01:02 AM2/12/13
to jac...@googlegroups.com
Hi,

yeah, it works for me now. I'm packaging the classes in /target/classes.

In other words, no extra configuration for the archiver needed, default maven config works fine.

best regards,
Henrik

Evgeny Mandrikov

unread,
Feb 12, 2013, 4:01:11 AM2/12/13
to jac...@googlegroups.com, johann...@gmail.com
Hi,

JaCoCo Maven Plugin places instrumented classes into "target/classes" - they should be used to collect coverage, i.e. they should be packaged and deployed on Android. "target/generated-classes/jacoco/" - is an original classes without instrumentation and they should be used to create report based on collected coverage.

I didn't had time yet to write a blog entry on how to use JaCoCo for Android, but you can take a look on my example at https://github.com/Godin/jacoco-experiments/tree/android/android First execute "mvn clean install" - it will instrument classes, execute tests and collect coverage. Then go to "app" and execute "mvn jacoco:report" - it will generate report based on collected coverage. But keep in mind that this is just a POC, i.e. might be process can be improved.

johann...@gmail.com

unread,
Feb 12, 2013, 9:08:06 AM2/12/13
to jac...@googlegroups.com, johann...@gmail.com
Thanks!

We're getting closer. Now, when we run the instrumentation tests we get a java.lang.IllegalAccessError. Not sure why that is or if it has anything to do with jacoco. Probably not.

We also tried your example and it seems to work fine with the exception that we have to run it in the emulator since we don't seem to have permission to pull the file from /data/data/org.example/... from a non-rooted device.

Is it possible to output the coverage.ec to /sdcard/ instead of the apps internal file area?

Evgeny Mandrikov

unread,
Feb 12, 2013, 9:22:45 AM2/12/13
to jac...@googlegroups.com, johann...@gmail.com
I never tried with a real device, but it should be possible - you just need to change configuration for android-maven-plugin in "app.test" :
  • add property "coverageFile" into the "test" section near property "coverage"
  • and change property "pullSource" to be the same as "coverageFile".

johann...@gmail.com

unread,
Feb 12, 2013, 9:31:05 AM2/12/13
to jac...@googlegroups.com, johann...@gmail.com
Awesome. The file is written to /sdcard/coverage.ec. But now the pullSource configuration fails. It's configured to read /sdcard/coverage.ec but for some reason it seems to look at /mnt/sdcard/coverage.ec (at least that is printed in the maven output, and the build fails).

Evgeny Mandrikov

unread,
Feb 12, 2013, 10:54:31 AM2/12/13
to jac...@googlegroups.com, johann...@gmail.com
It might be an issue on android-maven-plugin side, which is out of our control. Did you tried to search this problem in their bug-tracker? Did you tried different versions? My example was based on android-maven-plugin 3.3.0, but maybe it's already fixed in latest 3.5.0 ? Starting from this point I can't help you more than try to reproduce this configuration.
Reply all
Reply to author
Forward
This conversation is locked
You cannot reply and perform actions on locked conversations.
0 new messages