woensdag 23 januari 2013

Jenkins Android Emulator Plugin Problems

Context

Here is a collection of issues I met when configuring the Android Emulator plugin for Jenkins ( ins-ci.org/display/JENKINS/Android+Emulator+Plugin ). Clearly the goal of this plugin is to start an emulator on your Jenkins build server for testing Android applications.

General Jenkins Debugging

In case you didn't find a solution on this page this is some good advice to get you started. And let the world know if you found a solution. In general it's always a good idea to try the commands Jenkins wants to execute yourself from the shell after changing to the Jenkins user.

sudo su Jenkins

You might need information on working with the emulator from the command line. Android has good documentation but it sometimes takes some time to get through it. Here are some quick references:

A quick 4 step overview on how to work with emulators from the command line: http://stackoverflow.com/questions/4974568/how-do-i-launch-the-android-emulator-from-the-command-line

Preparing Android projects for ant building (for Jenkins): TODO

/var/lib/jenkins/workspace/.../build.xml:90: Cannot find /.../tools/ant/build.xml imported from /var/lib/jenkins/.../build.xml

This was the first error I've met during configuration of Android Jenkins projects. Unless you have the android sdk path set for the Jenkins user you'll have to provide it with the ant build steps in Jenkins. For this you can use the properties field after clicking the "Advanced" option for the ant build step.

Solution: I've seen this error in 2 cases. Either the path is missing or plain wrong. Or the Jenkins user doesn't have the proper rights. You can easily check both.

Note: If you have multiple parameters make sure to expand the properties field and use a line per argument (each line would be translated to a -D in the final command).
sdk.dir=/path/to/android-sdk

More information:

http://stackoverflow.com/questions/11752594/how-to-debug-android-project-from-git-using-jenkins-frontend/14334099#14334099

http://stackoverflow.com/questions/10860777/building-android-project-from-jenkins-under-linux-build-fails-cannot-find-imp

Error: more than one device and emulator

Okay this one might be obvious. If you try to run/install an Android (test) app and you don't specify on which device while there are multiple devices available on the system you'll get this clear error (for a change).

install:
[echo] Installing /var/lib/jenkins/workspace/someProject/bin/someProject-debug.apk onto default emulator or device...
[exec] error: more than one device and emulator
[exec] - waiting for device -
[exec] error: more than one device and emulator
[exec] - waiting for device - 


Solution: make sure only one device is available, that can be checked with the android list targets command. Or you can use the adb.device.arg argument to specify a single device. Either the emulator, a real device or a specific device. See options below:

-d - directs command to the only connected USB device. Returns an error if more than one USB device is present.
-e - directs command to the only running emulator. Returns an error if more than one emulator is running.
-s - directs command to the device or emulator with the given serial number or qualifier. Overrides ANDROID_SERIAL environment variable. 


Note: remember the single line per argument on the jenkins ant build step configuration note mentioned earlier. 


http://www.alittlemadness.com/2010/06/15/android-ant-builds-targeting-a-specific-device/

Failure INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

This was a fun one, fun because it was solved so quickly. The error looks like this from the console in Jenkins:

install:
[echo] Installing /var/lib/jenkins/workspace/someProject/bin/Test.apk onto default emulator or device...
[exec] 2022 KB/s (318784 bytes in 0.153s)
[exec] pkg: /data/local/tmp/Test.apk
[exec] Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]


This was a result of having similar apk's already installed on the device but built from another source. Just running an application while developing from Eclipse on a device would install the same apk signed differently on your device.

An apk is identified by it's package as it is specified in the Android manifest file (check the very first lines).

package="be.hcpl.android.phototools"

Solution: Just uninstall from the device/emulator before you build from Jenkins. You can perform this uninstall with adb from the command line.

adb uninstall be.hcpl.android.phototools
More information: http://stackoverflow.com/questions/3185444/how-to-deal-with-install-parse-failed-inconsistent-certificates-without-uninstal

Unable to find the mojo 'generate-sources' 

This one is a little exotic already. You'll only encounter this when setting up your Android projects to built with maven: http://code.google.com/p/maven-android-plugin/

The error in more detail:

[INFO] Internal error in the plugin manager executing goal 'com.jayway.maven.plugins.android.generation2:android-maven-plugin:3.5.0:generate-sources': Unable to find the mojo 'generate-sources' (or one of its required components) in the plugin 'com.jayway.maven.plugins.android.generation2:android-maven-plugin'
Component descriptor cannot be found in the component repository: org.sonatype.aether.RepositorySystem.


Solution: Appearantly this plugin is requires Maven 3. Note that Maven 3 is not yet available from apt-get so you'll have to install it manually:

wget http://apache.belnet.be/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz
tar -xzvf apache-maven-3.0.4-bin.tar.gz



[android] Emulator did not appear to start; giving up

This one can have several reasons. One of them is listed in the error below. I didn't encounter this myself but I've read on stackoverflow while looking for a solution to my specific issue.

It seems to be related to the revision of the android sdk tools. On windows there was a fix like stated in this ticket: https://issues.jenkins-ci.org/browse/JENKINS-10815

However there seems to be a similar issue on linux that isn't fixed yet (at least the ticket is still open): https://issues.jenkins-ci.org/browse/JENKINS-14901

Solution: The proposed solution in that ticket is to create a link with the name emulator (back original) towards the appropiate emulator-X bin.

More information: This google groups discussion is related: https://groups.google.com/forum/#!msg/jenkinsci-users/wi5fSWVvwz0/ICiJSJD98qQJ

SDL init failure, reason is: No available video device

Now this is the issue I encountered. So I can give more details on this one.

Missing 64 bit libraries

For ubuntu 64 bit systems you probably need to install some missing 32 bit libraries. Most of the stackoverflow pages I've found give this as the main reason so you'll find solutions there.

More information:
http://stackoverflow.com/questions/4841908/sdl-init-failure-reason-is-no-available-video-device
http://stackoverflow.com/questions/12709719/sdl-init-failure-reason-is-no-available-video-device-in-ubuntu-12-04-lts
http://stackoverflow.com/questions/6129091/error-sdl-init-failure-reason-is-no-available-video-device-when-launching-a

But that's not the only solution people seem to find. Others are talking about permissions and/or display selection. That is what the next point is all about.

Jenkins user permissions

And we're back to the beginning of this post. Where I informed you that the best way to find a Jenkins build error is to try the commands from the shell yourself with this Jenkins user. Doing so showed me that I can perfectly run the emulator with a different user (the one logged) or the root and the error only occurs if I try to run the emulator with the Jenkins user.

Solution (kind of): Unless, and this is where it's getting interesting, the Jenkins user is the user currently logged in to the machine. So it seems to be related to the xsession. I'm not a Linux export but this should be enough information for someone who is.

For instance running xhost + before performing sudo su Jenkins results in a working emulator. This is a pointer only, no actual solution. This just opens up the xsession to any user.

~/path/to/sdk/tools$ xhost +
access control disabled, clients can connect from any host

More information: http://superuser.com/questions/321880/how-can-i-start-the-android-sdk-manager-with-non-root-shell

Also check the xvnc setup instructions for headless systems: https://wiki.jenkins-ci.org/display/JENKINS/Android+Emulator+Plugin. That eventually was the solution in my case. Note that you'll have to start the xvnc service once from outside Jenkins to get the password set up. On first run it will ask you to enter a password and create the required password files.

sudo su jenkins
vncserver :10

More information: http://blog.dahanne.net/2011/07/18/run-ui-tests-on-a-headless-jenkins-hudson-continuous-integration-server-running-ubuntu/

Update: Another one I just encountered.

Error= Permission Denial: starting intrumentation not allowed because package does not have a signature matching the target. 

The below error happened to me when reusing a device for running some tests that already had a test package (signed with another key) installed on the device. So make sure to not only remove the app with adb uninstall package but also the test apk.

test:
     [echo] Running tests ...
     [exec] INSTRUMENTATION_STATUS: id=ActivityManagerService
     [exec] INSTRUMENTATION_STATUS: Error=Permission Denial: starting instrumentation ComponentInfo{your.package.here.test/com.zutubi.android.junitreport.JUnitReportTestRunner} from pid=31732, uid=31732 not allowed because package your.package.here.test does not have a signature matching the target your.package.here
     [exec] INSTRUMENTATION_STATUS_CODE: -1
     [exec] java.lang.SecurityException: Permission Denial: starting instrumentation ComponentInfo{your.package.here.test/com.zutubi.android.junitreport.JUnitReportTestRunner} from pid=31732, uid=31732 not allowed because package your.package.here.test does not have a signature matching the target your.package.here
     [exec]  at android.os.Parcel.readException(Parcel.java:1431)
     [exec]  at android.os.Parcel.readException(Parcel.java:1385)
     [exec]  at android.app.ActivityManagerProxy.startInstrumentation(ActivityManagerNative.java:2938)
     [exec]  at com.android.commands.am.Am.runInstrument(Am.java:801)
     [exec]  at com.android.commands.am.Am.onRun(Am.java:242)
     [exec]  at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
     [exec]  at com.android.commands.am.Am.main(Am.java:75)
     [exec]  at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
     [exec]  at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
     [exec]  at dalvik.system.NativeStart.main(Native Method)


1 opmerking: