Не удалось скопировать зависимости конфигураций после обновления плагина Gradle для Android Studio до 3.0.1 и Gradle до 4.1

Я использовал для копирования зависимостей "compile" в определенную папку, используя эту простую задачу gradle:

task copyLibs(type: Copy) {
    from configurations.compile
    into "$project.rootDir/reports/libs/"
}

Но он перестал работать сразу после обновления моего проекта Android с помощью плагина gradle 3.0.1 для Android Studio и инструмента Gradle до 4.1. Поскольку конфигурация зависимостей "compile" теперь устарела из-за https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#new_configurations, я изменил ее на "реализацию". Однако я не могу использовать мою задачу copyLibs, так как непосредственное разрешение "реализации" конфигурации не разрешено в соответствии с выводом ошибки сборки Gradle:

$ ./gradlew.bat clean build

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':app:copyLibs'.
> Resolving configuration 'implementation' directly is not allowed

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s

Смотрите следующий мой текущий файл build.gradle для модуля приложения: примените плагин: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "newgradle.com.testingnewgradle"
        minSdkVersion 21
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

task copyLibs(type: Copy) {
    from configurations.implementation
    into "$project.rootDir/reports/libs/"
}
build.dependsOn copyLibs

Если я использую 'compile', это работает, но я бы хотел соответствовать последней рекомендации по использованию этого плагина.

Мне нужна помощь, чтобы обновить мою задачу copyLibs, чтобы работать так же, как и до обновления моей среды. Я использовал плагин Gradle 2.2.3 для Android Studio и инструмент Gradle 2.14.1.

Ответ 1

вместо использования configurations.implementation лучше всего использовать: configurations.runtimeClasspath

Вы также можете подумать: compileClasspath default

Ответ 2

Это, вероятно, не поможет или не будет лучшего способа решить, но...

Вы можете поместить свои зависимости таким образом, который можно скопировать, выполнив следующие действия:

android { ... }

// Add a new configuration to hold your dependencies
configurations {
    myConfig
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:support-v4:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

    // Now you have to repeat adding the dependencies you want to copy in the 'myConfig'
    myConfig fileTree(dir: 'libs', include: ['*.jar'])
    myConfig 'com.android.support:appcompat-v7:26.1.0'
    myConfig 'com.android.support:support-v4:26.1.0'
    ...
}

task copyLibs(type: Copy) {
    // Now you can use 'myConfig' instead of 'implementation' or 'compile' 
    from configurations.myConfig 
    into "$project.rootDir/reports/libs/"
}

Это также помогает, если у вас есть задача Jar, которая перестает помещать зависимости в файл jar, потому что вы изменили с compile на implementation.

Вы можете использовать:

from {configurations.myConfig.collect { it.isDirectory() ? it : zipTree(it) }}

Вместо:

from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }}

Ответ 3

Я делаю, конфигурация может быть решена, поэтому не исключение получить файл зависимостей

configurations.implementation.setCanBeResolved(true)
configurations.api.setCanBeResolved(true)

println configurations.implementation.resolve()
println configurations.api.resolve()

Ответ 4

Я хотел сделать комментарий, но мне все еще не хватает репутации, необходимой для этого (по одному пункту !!>. & Lt;). Не похоже, что есть способ получить список зависимостей implementation, а compileClasspath, упомянутый в заявке на Gradle, опубликованной Рафаэлем, не будет работать, если вы работаете с Android напрямую, например мой случай, когда мне нужно экспортировать зависимости, чтобы Unity3D мог их упаковать для выпуска.

Итак... похоже, что единственным решением в этом случае является использование устаревшего типа compile.

Ответ 5

Еще одно предложение.

Я создал свой пользовательский конфиг и затем использовал его как configurations.customConfig:

configurations {
  customConfig.extendsFrom implementation
}

Ответ 6

спасибо за @act262, это действительно работает!

configurations.implementation.setCanBeResolved(true)
configurations.implementation.each {
    println it
}

Ответ 7

Я начал получать эту ошибку после обновления с версии 5.5 до 5.6, и это происходит, когда я пытаюсь синхронизировать проект в intelliJ.

Благодаря этому ответу на другой вопрос я решил его, применив idea плагин ко всем проектам, а затем запустив gradle cleanIdea, после чего все снова заработало.

Еще один день, еще одно необъяснимое решение проблемы.