Travis CI and CodeCov Android

I am trying to use Travis CI and run it to check the results for codecs.

.travis.yml:

language: android
sudo: required
jdk: oraclejdk8

before_cache:
 - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
 - rm -fr $HOME/.gradle/caches/*/plugin-resolution/

cache:
 directories:
 - $HOME/.gradle/caches/
 - $HOME/.gradle/wrapper/

env:
 global:
 - ANDROID_API=25
 - EMULATOR_API=21
 - ANDROID_BUILD_TOOLS=25.0.0
 - ADB_INSTALL_TIMEOUT=5 # minutes

android:
 components:
 - tools
 - platform-tools
 - build-tools-$ANDROID_BUILD_TOOLS
 - android-$ANDROID_API
 - android-$EMULATOR_API_LEVEL
 - extra-google-m2repository
 - extra-android-m2repository # for design library
 - addon-google_apis-google-19 # google play services
 - sys-img-armeabi-v7a-addon-google_apis-google-$ANDROID_API_LEVEL
 - sys-img-armeabi-v7a-addon-google_apis-google-$EMULATOR_API_LEVEL

licenses:
 - android-sdk-preview-license-.+
 - android-sdk-license-.+
 - google-gdk-license-.+

before_install:
- mkdir "$ANDROID_HOME/licenses" || true
- echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
- chmod +x gradlew
#- ./gradlew dependencies || true # DON'T ADD unless you are getting "Install missing components using SDK manager"
#Source: https://medium.com/@oldergod/constraint-layout-and-circleci-travis-d50342696d2



script:
  - ./gradlew build jacocoTestReport assembleAndroidTest
  - echo no | android create avd --force -n test -t android-21 --abi armeabi-v7a
  - emulator -avd test -no-skin -no-audio -no-window &
  - android-wait-for-emulator
  - adb shell setprop dalvik.vm.dexopt-flags v=n,o=v
  - ./gradlew connectedCheck

after_success:
- bash <(curl -s https://codecov.io/bash)

      

build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.2'
        classpath 'com.dicedmelon.gradle:jacoco-android:0.1.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

      

build.gradle (app):

apply plugin: 'com.android.application'
apply plugin: 'jacoco-android'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.3"
    defaultConfig {
        applicationId "<ID>"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            testCoverageEnabled true
        }
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
    lintOptions {
        abortOnError false
    }
    productFlavors {
        free {}
        paid {}
    }


    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
}

dependencies {
    compile files('libs/httpclient-4.5.1.jar')
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile 'com.android.support:support-v4:24.2.1'
    compile 'com.android.support:design:24.2.1'
    compile 'com.android.support:support-vector-drawable:24.2.1'
    testCompile 'junit:junit:4.12'
    compile files('libs/themoviedbapi-4.3.jar')
    compile files('libs/api-common-2.0.jar')
    compile files('libs/commons-codec-1.9.jar')
    compile files('libs/commons-lang3-3.4.jar')
    compile files('libs/httpcore-4.4.3.jar')
    compile files('libs/jackson-annotations-2.7.1.jar')
    compile files('libs/jackson-core-2.7.1.jar')
    compile files('libs/jackson-databind-2.7.1.jar')
    compile files('libs/slf4j-api-1.7.16.jar')
}

      

The test we are trying to run is an instrumental test. The result in the Travis log looks like this:

com.example.fabian.tinf15b4_lsmf.SeeMovieDetailsTest > seeMovieDetails[test(AVD) - 5.0.2] [31mFAILED [0m
    java.lang.NoSuchMethodError: No virtual method releaseConnection()V in class Lorg/apache/http/client/methods/HttpRequestBase; or its super classes (declaration of 'org.apache.http.client.methods.HttpRequestBase' appears in /system/framework/ext.jar)

    at org.yamj.api.common.http.DigestedResponseReader.processRequest(DigestedResponseReader.java:119)

Tests on test(AVD) - 5.0.2 failed: Instrumentation run failed due to 'java.lang.NoSuchMethodError'
:app:connectedFreeDebugAndroidTest FAILED

      

There was also an auto-generated test that just adds two numbers and checks the result, but Travis didn't even pass it.

Can anyone please help in fixing this mess?

+3


source to share


1 answer


Read this related question about HTTPClient - NoSuchMethodError for .releaseConnection

.

The method was HttpRequestBase#releaseConnection()

definitely added in version 4.2 .

Probably you have hell. If the compiler has no compilation errors, another version of the class can be loaded at runtime. The real reason depends on your build tool. If you are using maven / gradle be some kind of transitive dependency.

So the HttpRequestBase#releaseConnection()

method is actually just a proxy call AbstractExecutionAwareRequest#reset()

. And also AbstractExecutionAwareRequest#reset()

only cancel the execution method. This may not be what you want.

The correct way to start and release the httpClient resources is to close the httpResponse, which means you can release the Thread in the httpClient's internal threadPool.

private static String makeRequest(HttpUriRequest httpRequest) throws IOException {
        CloseableHttpResponse httpResponse = httpClient.execute(httpRequest);
        try {
            HttpEntity httpEntity = httpResponse.getEntity();
            StringWriter writer = new StringWriter();
            IOUtils.copy(httpEntity.getContent(), writer, "UTF-8");
            return writer.toString();
        } finally {
            httpResponse.close();
        }
    }

      

In quickstart you will see that it is .releaseConnection()

no longer used (deprecated), instead the response object is closed to make sure the connections are closed.

Try using a different version httpclient

or httpcore

(from here ):

It looks like you have a jar file with an older / newer version of BasicHttpContext. If there was a direct conflict, you would receive a ClassNotFoundException. ClassLoaders are usually jerks about this stuff like that. In this case, the class exists, however, does not have a method that the other library (I believe the httpclient is a call to the context) was compiled.

For API 23+, you can also add the remote apache library to /app/build.gradle like this :

android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
    useLibrary 'org.apache.http.legacy'
    ...
}

      



The Android 6.0 release removes support for the Apache HTTP client. If your application uses this client and targets Android 2.3 (API level 9) or higher, use the HttpURLConnection class instead. This API is more efficient ...

this article and this example seems useful for setting up Codecov for Android and Travis-ci:

A minor build script change is required to generate code coverage reports for instrumentation.

android {
  buildTypes {
    debug {
      testCoverageEnabled true
    }
  }
}

      

To avoid ignoring our tests in the coverage report, we need to configure the following settings:

android {
  testOptions {
    unitTests.all {
      jacoco {
        includeNoLocationClasses = true
      }
    }
  }
}

      

Then we need to customize the output of the report:

 jacocoAndroidUnitTestReport {
  csv.enabled false
  html.enabled true
  xml.enabled true
}

      

0


source







All Articles