发布无法解决对具有不同坐标的多个发布的项目的依赖性

时间:2018-07-09 14:23:19

标签: android gradle android-gradle maven-publish

我有2个lib模块: java.lang.IllegalStateException: Could not execute method for android:onClick at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) at android.view.View.performClick(View.java:6597) at android.view.View.performClickInternal(View.java:6574) at android.view.View.access$3100(View.java:778) at android.view.View$PerformClick.run(View.java:25885) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) at android.view.View.performClick(View.java:6597)  at android.view.View.performClickInternal(View.java:6574)  at android.view.View.access$3100(View.java:778)  at android.view.View$PerformClick.run(View.java:25885)  at android.os.Handler.handleCallback(Handler.java:873)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:6669)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.CheckBox.isChecked()' on a null object reference at rocks.athrow.android_quiz_app.MainActivity.submitAnswers(MainActivity.java:128) at java.lang.reflect.Method.invoke(Native Method)  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)  at android.view.View.performClick(View.java:6597)  at android.view.View.performClickInternal(View.java:6574)  at android.view.View.access$3100(View.java:778)  at android.view.View$PerformClick.run(View.java:25885)  at android.os.Handler.handleCallback(Handler.java:873)  at android.os.Handler.dispatchMessage(Handler.java:99)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:6669)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)  library,并使用android-maven-publish发布具有multi-productFlavors的多模块android项目

library2在库中:

build.gradle

apply plugin: 'com.android.library' apply plugin: 'digital.wup.android-maven-publish' android { compileSdkVersion 26 defaultConfig { minSdkVersion 14 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' } } flavorDimensions "runner" productFlavors { sit { dimension "runner" } dev { dimension "runner" } uat { dimension "runner" } prd { dimension "runner" } } } dependencies { ... implementation project(':android-library2') } apply from: '../publish.gradle' 在library2中:

build.gradle

publish.gradle:

apply plugin: 'com.android.library'
apply plugin: 'digital.wup.android-maven-publish'

android {
    compileSdkVersion 26
    defaultConfig {
        minSdkVersion 14
        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'
        }
    }

    flavorDimensions "runner"
    productFlavors {
        sit {
            dimension "runner"
        }
        dev {
            dimension "runner"
        }
        uat {
            dimension "runner"
        }
        prd {
            dimension "runner"
        }
    }

}

dependencies {
   ...
}

apply from: '../publish.gradle'

当我在库中运行任务publishing.publications() { android.libraryVariants.all { variant -> "maven$project.archivesBaseName${variant.name.capitalize()}Aar"(MavenPublication) { from components.findByName("android${variant.name.capitalize()}") groupId 'com.android.saleshelp' artifactId project.archivesBaseName + "-${variant.name.capitalize()}" version android.defaultConfig.versionName } } } publishing.repositories { mavenLocal() } 时,出现以下错误:

publish

如果我删除了library2的* What went wrong: Could not determine the dependencies of task ':android-library2:publishMavenandroid-library2SitReleaseAarPublicationToMavenLocalRepository'. > Publishing is not able to resolve a dependency on a project with multiple publications that have different coordinates. Found the following publications in project ':android-library': - Maven publication 'mavenandroid-libraryPrdDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-PrdDebug:1.0 - Maven publication 'mavenandroid-libraryPrdReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-PrdRelease:1.0 - Maven publication 'mavenandroid-libraryDevDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-DevDebug:1.0 - Maven publication 'mavenandroid-libraryDevReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-DevRelease:1.0 - Maven publication 'mavenandroid-libraryUatDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-UatDebug:1.0 - Maven publication 'mavenandroid-libraryUatReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-UatRelease:1.0 - Maven publication 'mavenandroid-librarySitDebugAar' with coordinates com.cestbon.android.saleshelp:android-library-SitDebug:1.0 - Maven publication 'mavenandroid-librarySitReleaseAar' with coordinates com.cestbon.android.saleshelp:android-library-SitRelease:1.0 * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org 中的apply from: '../publish.gradle',则任务build.gradle可以成功运行。但是由于我想独立发布:library:publish,所以library2必须library2

如何解决此错误? 谢谢。

环境: gradle 4.4〜4.9-rc1

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,似乎仍然是maven-publish的局限性。我找到了一种对我来说很好的解决方法:

publishing {
  repositories {
    def repositoryName = 'X'
    maven { name = repositoryName /* ... */ }
    
    afterEvaluate {
      def targetComponent = System.getProperty("targetComponent")
      components.each { component ->
        if (component.name != targetComponent) return

        def appendage = component.name.replaceAll("[Rr]elease", "")
        if (!appendage.isEmpty()) appendage = "-$appendage"

        publications {
          "${component.name}"(MavenPublication) {
            from component
            artifactId = project.name + appendage
          }
        }

        publish.doFirst {
          if (targetComponent == null)
            throw new GradleException("Deployment requires specifying -DtargetComponent option")
        }
      }
    }
  }
}

使用gradle project:publish -DtargetComponent=release或您要发布的任何其他组件调用。

说明: Gradle在project级别看到工作空间内的依赖关系,但在component级别将其输出到Maven存储库。 Maven没有相同的项目与组件概念。这也意味着您无法在Gradle dependencies块中指定要查找的Maven样式依赖项的哪个组成部分(因为Maven并没有真正理解该概念)。结果:Gradle无法弄清楚如何为具有多个publication的工作空间内依赖项编写POM文件条目。

最小问题示例:

// a/build.gradle:
publications {
  release(MavenPublication) { from components.release }
  debug(MavenPublication) { from components.debug; artifactId = 'a-debug' }
}

// b/build.gradle:
dependencies {
  project(':a') // ERROR: should this be 'group:b:1.0.0' or 'group:b-debug:1.0.0'?
}

通过在配置时间之前指示所有项目中要部署的组件,可以解决此问题。在配置过程中,Gradle仅根据您标记的组件为每个项目生成一个出版物,并添加了Gradle要将项目内部门映射到Maven样式部门所需的额外信息。您只需要在部署时指定命令行参数即可;条件绑定到publish任务,因此只有在实际调用该任务时它才会关闭。

限制:

  • 假定组件信息应保留在Maven artifactId中;您可以根据需要更改此内容
  • 如果您未指定属性,则gradle publish --dry-run不会显示有意义的结果
  • Gradle在每次调用中只能发布一个组件
  • 工作区中的每个项目都必须公开名称相似的组件(不过,您可以定制此代码以解决此问题),并且它们都绑定在该选择中(即a:release绑定到b:release,并且a:debug绑定到b:debug

编辑:我已调用任务deploy,但在编写此答案时将其重命名为publish。事实证明,maven-publish自动创建了一个任务publish,它完全可以完成我想要的工作。我已经更新了代码片段以反映这一点。

EDIT2:而是抛出GradleException;有点惯用。

答案 1 :(得分:1)

这是maven-publish插件的已知限制。

当项目依赖项具有多个发布时,maven-publish插件无法正确选择它们。在您的情况下,当maven-publish插件尝试解析implementation project(':android-library2')时,它无法决定向pom文件写入什么内容,因为android-library2项目有多个具有不同坐标的出版物。< / p>

在Gradle 4.9-rc-1中引入了alias property。如果将所有发布都标记为别名,并且拥有主发布,则可以解决您的问题。但是我认为这不能完全解决您的问题,因为maven publish插件会将主出版物的坐标写到pom文件中,而与产品类型无关。

如果这样做没有帮助,则可以使用the original bug report中的解决方法。