POM文件中的maven依赖怎么不能用?

How come maven dependencies in POM file can't be used?

背景

我的任务是为开发人员提供一种方法,将单个依赖项添加到 Android 项目的 build.gradle 文件中,以使用我准备的一些(混淆的)SDK(AAR 文件 - Android图书馆)。

SDK 本身使用各种依赖项,因此在最终代码中提供它们很重要,这意味着使用 SDK 的任何人都不会看到由于 class-not-found 而导致的崩溃。

SDK 作为私有存储库存储在 Github 上,开发人员可以通过 Jitpack 访问存储库中的 POM 文件和其他一些文件。

单独使用 AAR 文件,您必须设置与 SDK 相同(或更新)的依赖项。

但是,如果您在发布时使用 POM 文件,消费者(使用 SDK 的任何人)不需要编写 SDK 上的每个依赖项,因为它是从 POM 文件中添加的。

问题

出于某种原因,这种行为对我来说不存在。这意味着 SDK 好像不使用任何依赖性,所以如果我尝试使用任何依赖性,我无法达到 classes,如果我尝试使用 SDK,当它使用一些依赖性时,它会导致 ClassNotFoundException 异常。

起初我认为这是因为一些 Proguard 规则,但后来我注意到它也发生在 debug-variant 上(使用 SDK 的应用程序)。

例如,当库在依赖项中使用它时:

implementation 'androidx.security:security-crypto:1.1.0-alpha03'

如果我不使用相同的,我将无法达到此依赖项的任何 class,如果 SDK 试图达到它的任何 class,应用程序将崩溃.

因此,我必须添加 SDK 已经使用的所有依赖项,而不是使用 SDK 的单一依赖项。

我试过的

为了生成 AAR 文件,我使用“assembleRelease”gradle 任务,为了生成 POM 文件,我使用“generatePomFileForReleasePublication”(或“publishReleasePublicationToMavenLocal”)gradle 任务。

库有很多依赖项。这是它的 build.gradle 文件:

plugins {
    id 'com.android.library'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'kotlin-parcelize'
    id 'io.michaelrocks.paranoid'
    id 'maven-publish'
    id 'com.github.dcendents.android-maven'
}

android {
    compileSdkVersion 30
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            consumerProguardFiles 'consumer-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    configurations {
        all {
            exclude module: 'httpclient'
        }
    }
    packagingOptions {
        //for google login token
        exclude 'META-INF/DEPENDENCIES'
    }
}

dependencies {
    api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    api 'androidx.core:core-ktx:1.6.0-alpha01'
    api 'androidx.collection:collection-ktx:1.2.0-alpha01'
    api 'androidx.security:security-crypto:1.1.0-alpha03'
    def room_version = "2.2.6"
    api "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    api "androidx.room:room-ktx:$room_version"
    api 'com.squareup.retrofit2:retrofit:2.9.0'
    api 'com.squareup.retrofit2:converter-gson:2.9.0'
    api 'com.squareup.okhttp3:okhttp:5.0.0-alpha.2'
    api 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2'
    api('com.google.android.gms:play-services-auth:19.0.0')
    api('com.google.auth:google-auth-library-oauth2-http:0.25.0')
    api('com.google.apis:google-api-services-people:v1-rev99-1.22.0') {
        exclude group: 'com.google.guava'
    }
    api 'io.michaelrocks:libphonenumber-android:8.12.20'
}

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.release
            }
        }
    }
}

运行 “generatePomFileForReleasePublication” 的任务 我得到了 POM 文件 “pom-default.xml” :

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>MySdk</groupId>
  <artifactId>library</artifactId>
  <version>unspecified</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib</artifactId>
      <version>1.4.32</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>androidx.core</groupId>
      <artifactId>core-ktx</artifactId>
      <version>1.6.0-alpha01</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>androidx.collection</groupId>
      <artifactId>collection-ktx</artifactId>
      <version>1.2.0-alpha01</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>androidx.security</groupId>
      <artifactId>security-crypto</artifactId>
      <version>1.1.0-alpha03</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>androidx.room</groupId>
      <artifactId>room-runtime</artifactId>
      <version>2.2.6</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>androidx.room</groupId>
      <artifactId>room-ktx</artifactId>
      <version>2.2.6</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>retrofit</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.squareup.retrofit2</groupId>
      <artifactId>converter-gson</artifactId>
      <version>2.9.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>okhttp</artifactId>
      <version>5.0.0-alpha.2</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp3</groupId>
      <artifactId>logging-interceptor</artifactId>
      <version>5.0.0-alpha.2</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.google.android.gms</groupId>
      <artifactId>play-services-auth</artifactId>
      <version>19.0.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.google.auth</groupId>
      <artifactId>google-auth-library-oauth2-http</artifactId>
      <version>0.25.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.google.apis</groupId>
      <artifactId>google-api-services-people</artifactId>
      <version>v1-rev99-1.22.0</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
        <exclusion>
          <artifactId>*</artifactId>
          <groupId>com.google.guava</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>io.michaelrocks</groupId>
      <artifactId>libphonenumber-android</artifactId>
      <version>8.12.20</version>
      <scope>compile</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-parcelize-runtime</artifactId>
      <version>1.4.32</version>
      <scope>runtime</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>io.michaelrocks</groupId>
      <artifactId>paranoid-core</artifactId>
      <version>0.3.3</version>
      <scope>runtime</scope>
      <exclusions>
        <exclusion>
          <artifactId>httpclient</artifactId>
          <groupId>*</groupId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>

根据各种网站,这似乎有效且不错,但遗憾的是,正如我所写的,当我使用它时,就好像 none 这些依赖项存在,我需要在消费者上声明它们边.

在 Jitpack 的文件 ("jitpack.yml" ) 中,我有这样的东西:

install: 
  - FILE="-Dfile=library-release.aar" 
  - mvn install:install-file $FILE -DgroupId=my-sdk -DartifactId=MySdk -Dversion=1.0 -Dpackaging=aar -DgeneratePom=true

我尝试了什么:

  1. 我尝试使用“实现”和“api”。没有帮助。
  2. 我试图从所有 dependency 标签中删除 scope。没有帮助。
  3. 我尝试在消费者端添加 transitive = true,但这没有做任何事情,可能是因为默认情况下它本身就是这样。
  4. 删除 POM 文件在 Jitpack 上没有显示任何警告,表明它甚至可能不会检查它。
  5. 我注意到 POM 文件提到“此模块还发布了更丰富的模型,Gradle 元数据,应该改用它”,所以我尝试找到此文件,但找不到。 运行 publishToMavenLocal 任务,我得到了另一个文件 ("module.json"),甚至把它放在单独的 pom-default.xml 文件中(也作为一个完整的替换),它没有帮助。
  6. 我认为“jitpack.yml”文件和gradle文件之间存在一些不一致,所以我为它们设置了相同的“groupId”值,, artifactId”和“版本”。

问题

  1. 为什么依赖关系在消费者端被忽略了?我怎样才能解决这个问题?这可能是我错过的非常简单的事情......
  2. Jitpack具体需要哪些文件?哪些是强制性的?哪些是可选的?
  3. 是否也可以在消费者方面避免 packagingOptions {exclude 'META-INF/DEPENDENCIES' } 的部分?
  4. 奖励:我注意到 JavaDocs(在我的例子中是 Kdocs,因为我在 Kotlin 中编写了所有内容)也被完全忽略了。我怎样才能使这些也可访问和可读?

我认为问题出在您的 jitpack.yml 上。 Jitpack 的默认 install 命令依赖于 maven-publish,因此使用生成的 pom.xml。您使用对您的依赖项一无所知并且无法生成正确的 pom.xml 的自定义命令覆盖它,因为该命令是基于 Maven 的并且您的项目是 Gradle-based.

删除 jitpack.yml 或其 install 部分,一切正常。

更新:

您必须在 Gradle 配置中配置 Maven 发布才能使其正常工作。为此,您必须应用 maven-publish 插件

apply plugin: 'maven-publish'

并配置发布

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.release
                groupId = 'my-sdk'
                artifactId = 'MySdk'
                version = '1.0'
            }
        }
    }
}

请看官方Jitpack的Android sample。他们在 build.gradle 中配置 Maven 发布,既不使用 jitpack.yml,也不使用 maven实用程序。

好的,我已经找到方法了。答案来自 Jitpack 支持本身。首先引用他们的话:

This is caused by the install command and ' -DgeneratePom=true' parameter. It will generate a new pom file but it doesn't know anything about dependencies.

If you already have a pom file with all the dependencies then you could add it to the GitHub repository. Instead of ' -DgeneratePom=true' you could use '-DpomFile='

We recommend trying that command locally before running on JitPack.

The other option is to put all the source code of the library on JitPack and build from source.

事实上,如果我使用它(并且在库的依赖项中有“api”)我的大部分问题都得到了回答:

  1. 它修复了依赖项问题(是的,您不必自定义 -DgroupId=my-sdk -DartifactId=MySdk -Dversion=1.0 ):
install: 
  - FILE="-Dfile=library-release.aar" 
  - mvn install:install-file $FILE -Dpackaging=aar -DpomFile=pom-default.xml
  1. 目前存在的文件似乎只有那些:jitpack.yml、library-release.aar、pom-default.xml .

  2. 显然现在不需要了。可能由修复依赖关系问题的同一件事修复。

话虽如此,现在我有以下问题:

  1. “pom-default.xml”中使用不同文件的建议是什么(“此模块还发布了更丰富的模型,Gradle 元数据,应该代替使用。”)?它在哪里?它可能是“module.json”文件吗?我尝试改用它,但 Jitpack 出现错误。

  2. 这个用例的Jitpack文档在哪里?他们有一些关于私有存储库的东西,但没有关于 AAR 文件的东西。事实上,关于“jitpack.yml”文件我什么也看不到。

  3. 定制-DgroupId=my-sdk -DartifactId=MySdk -Dversion=1.0部分的目的是什么?是在库的“jitpack.yml”文件中还是在gradle文件中?我认为他们根本没有做任何事情...似乎 Github 存储库本身就是决定消费者如何使用它的存储库。

  4. 如何添加 JavaDocs 和 Kdocs(Kotlin 的)在这里使用?

即使这是我的问题的主要答案,我也会奖励那些回答我剩下的问题的人:)