4

I am trying to use Travis CI and get it to run through the tests to see the results on codecov.

.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 instrumented test. The output on 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

Also there was the autogenerated Test which simply adds two numbers and checks the result but Travis did not even go through it.

Can anyone please help fixing this mess?

albodelu
  • 7,931
  • 7
  • 41
  • 84
Curunir
  • 1,186
  • 2
  • 13
  • 30

1 Answers1

0

Read this related question about HTTPClient - NoSuchMethodError for .releaseConnection.

The method HttpRequestBase#releaseConnection() definetely was added at 4.2 version.

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

So actually HttpRequestBase#releaseConnection() method just proxy invocation to AbstractExecutionAwareRequest#reset(). And AbstractExecutionAwareRequest#reset() just cancel method execution. Probably it is not what do you need.

The correct way to execute and release httpClient resources is to close httpResponse, which means you can release Thread in 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 the quickstart you'll see that .releaseConnection() is no longer used (it is deprecated), instead the response object is closed to ensure connections are closed.

Try a different httpclientor httpcore version (from here):

It looks like you have a jar file with an old/newer version of BasicHttpContext. If there were a direct conflict, you'd receive a ClassNotFoundException. ClassLoaders are typically jerks about this kind of thing. In this case, the class exists, however, does not have the method that another library (I believe it's httpclient that's invoking the Context) was compiled against.

For API 23+ you can also add the removed apache library in your /app/build.gradle like this:

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

Android 6.0 release removes support for the Apache HTTP client. If your app is using 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 sample seem useful to configure Codecov for Android and Travis-ci:

Generating instrumentation tests code coverage reports requires a minor change to the build script.

android {
  buildTypes {
    debug {
      testCoverageEnabled true
    }
  }
}

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

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

Next, we need to configure report output:

 jacocoAndroidUnitTestReport {
  csv.enabled false
  html.enabled true
  xml.enabled true
}
albodelu
  • 7,931
  • 7
  • 41
  • 84