为什么不能使用POM文件中的maven依赖?

and*_*per 6 android dependency-management pom.xml maven jitpack

背景

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

SDK 本身使用各种依赖项,因此它们在最终代码中可用很重要,这意味着使用 SDK 的人不会看到由于找不到类而导致的崩溃。

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

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

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

问题

出于某种原因,这种行为对我来说不存在。这意味着就好像 SDK 不使用任何依赖关系一样,所以如果我尝试使用任何依赖关系,我无法访问这些类,并且如果我在使用某些依赖关系时尝试使用 SDK,则会导致异常的 ClassNotFoundException。

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

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

implementation 'androidx.security:security-crypto:1.1.0-alpha03'
Run Code Online (Sandbox Code Playgroud)

如果我不使用它,我将无法访问此依赖项的任何类,并且如果 SDK 尝试访问它的任何类,应用程序将崩溃。

因此,我必须添加 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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

运行“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>
Run Code Online (Sandbox Code Playgroud)

根据各种网站的说法,这似乎有效且良好,但遗憾的是,正如我所写的,当我使用它时,就好像这些依赖项都不存在一样,我需要在消费者端声明它们。

在 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
Run Code Online (Sandbox Code Playgroud)

我试过的:

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

问题

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

and*_*per 2

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

这是由安装命令和“-DgeneratePom=true”参数引起的。它会生成一个新的 pom 文件,但它不知道任何有关依赖项的信息。

如果您已经有一个包含所有依赖项的 pom 文件,那么您可以将其添加到 GitHub 存储库。您可以使用“-DpomFile=”代替“-DgeneratePom=true”

我们建议在 JitPack 上运行之前在本地尝试该命令。

另一种选择是将库的所有源代码放在 JitPack 上并从源代码构建。

事实上,如果我使用它(并且在库的依赖项中有“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
Run Code Online (Sandbox Code Playgroud)
  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的)在这里使用?

尽管这是我问题的主要答案,但对于其余问题回答得好的人,我将给予赏金:)