简体   繁体   English

如何将 Maven 清单添加到指定依赖项的 AAR

[英]How to add a maven manifest to an AAR which specifies dependencies

I was (finally) able to publish my Android library to an AWS S3 maven repository using this guide.我(终于)能够使用指南将我的 Android 库发布到 AWS S3 maven 存储库。 It's published as an AAR instead of JAR file, which means that even though the generated POM file lists all its internal dependencies, they are ignored when adding the library to another project.它作为 AAR 而不是 JAR 文件发布,这意味着即使生成的 POM 文件列出了其所有内部依赖项,在将库添加到另一个项目时它们也会被忽略。 Seems like a pretty common problem.似乎是一个很常见的问题。 I understand from this that I just need to list the dependencies in a maven manifest , but how is this done?我从中了解到, 只需要在 maven manifest 中列出依赖项,但是这是如何完成的呢?

I'm really a newbie at this, so the simpler the better... Thanks!我真的是这方面的新手,所以越简单越好......谢谢!

Note: I also found this question, so I added "{transitive=true}" at the end of the dependency implementation line and it worked.注意:我也发现了这个问题,所以我在依赖实现行的末尾添加了“{transitive=true}”并且它起作用了。

So now to include my library successfully, the dependency must be coded as:所以现在要成功包含我的库,依赖项必须编码为:

implementation (group: 'com.mygroup', name: 'my_library', version: '1.3', ext: 'aar', classifier: 'release') { transitive=true changing=true }

(I included "changing=true" to force it to re-download the library every time.) (我包括“改变=真”来强制它每次重新下载库。)

If I don't include "transitive=true", I get the following errors:如果我不包含“transitive=true”,我会收到以下错误:

    02-04 20:11:48.462 10225-10225/com.mydomain.app.testapplication4 E/dalvikvm: Could not find class 'android.graphics.drawable.RippleDrawable', referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
    02-04 20:14:07.080 10225-10225/com.mydomain.app.testapplication4 E/dalvikvm: Could not find class 'android.app.NotificationChannel', referenced from method com.mydomain.library.mydomain$1.onReceive
    02-04 20:14:07.290 10225-10225/com.mydomain.app.testapplication4 E/AndroidRuntime: FATAL EXCEPTION: main
        java.lang.NoClassDefFoundError: com.google.firebase.iid.FirebaseInstanceId
            at com.mydomain.library.MyActivity.onCreate(MyActivity.java:88)
            at android.app.Activity.performCreate(Activity.java:4701)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1051)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1924)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1985)
            at android.app.ActivityThread.access$600(ActivityThread.java:127)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1151)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4477)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
            at dalvik.system.NativeStart.main(Native Method)

Here is the latest script I used to publish the library (note that it only publishes the release build, but the dependency line still requires the "release" classifier):这是我用来发布库的最新脚本(注意它只发布发布版本,但依赖行仍然需要“发布”分类器):

    apply plugin: 'maven-publish'

    group = 'com.mydomain'
    version = '1.3'

    // Add sources as an artifact
    task sourceJar(type: Jar) {
        from android.sourceSets.main.java.srcDirs
        classifier "source"
    }

    // Loop over all variants
    android.libraryVariants.all { variant ->
        if (variant.buildType.name == "release") { // only release build
        variant.outputs.all { output ->
            // This creates a publication for each variant
            publishing.publications.create(variant.name, MavenPublication) {
                // The sources artifact from earlier
                artifact sourceJar

                // Variant dependent artifact, e.g. release, debug
                artifact source: output.outputFile, classifier: output.name

                // Go through all the dependencies for each variant and add them to the POM
                // file as dependencies
                pom.withXml {
                    final dependenciesNode = asNode().appendNode('dependencies')

                    ext.addDependency = { Dependency dep, String scope ->
                        if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
                            return // ignore invalid dependencies

                        final dependencyNode = dependenciesNode.appendNode('dependency')
                        dependencyNode.appendNode('groupId', dep.group)
                        dependencyNode.appendNode('artifactId', dep.name)
                        dependencyNode.appendNode('version', dep.version)
                        dependencyNode.appendNode('scope', scope)

                        if (!dep.transitive) {
                            // If this dependency is transitive, we should force exclude all its dependencies them from the POM
                            final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                            exclusionNode.appendNode('groupId', '*')
                            exclusionNode.appendNode('artifactId', '*')
                        } else if (!dep.properties.excludeRules.empty) {
                            // Otherwise add specified exclude rules
                            final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                            dep.properties.excludeRules.each { ExcludeRule rule ->
                                exclusionNode.appendNode('groupId', rule.group ?: '*')
                                exclusionNode.appendNode('artifactId', rule.module ?: '*')
                            }
                        }
                    }

                    // List all "compile" dependencies (for old Gradle)
                    configurations.compile.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "api" dependencies (for new Gradle) as "compile" dependencies
                    configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "implementation" dependencies (for new Gradle) as "runtime" dependencies
                    configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") }
                }
            }
        }
        }
    }

    // Ensure that the publish task depends on assembly
    tasks.all { task ->
        if (task instanceof AbstractPublishToMaven) {
            task.dependsOn assemble
        }
    }

    // Configure the destination repository with
    // S3 URL and access credentials
    publishing {
        // Properties properties = new Properties()
        // properties.load(file('maven.properties').newDataInputStream())

        repositories {
            maven {
                url "s3://androidsdk.mydomain.com.s3.amazonaws.com"
                credentials(AwsCredentials) {
                    accessKey "myaccesskey"
                    secretKey "mysecretkey"
                }
            }
        }
    }

Here are the dependencies in the library's gradle.build file:以下是库的 gradle.build 文件中的依赖项:

    dependencies {
        api fileTree(include: ['*.jar'], dir: 'libs')
        api 'com.android.support:appcompat-v7:27.1.1'
        api 'com.android.support.constraint:constraint-layout:1.1.3'
        api 'com.android.support:design:27.1.1'
        api 'io.reactivex.rxjava2:rxandroid:2.1.0'
        api 'io.reactivex.rxjava2:rxjava:2.2.4'
        api 'com.github.instacart.truetime-android:library-extension-rx:3.3'
        api 'com.google.dagger:dagger-android:2.15'
        annotationProcessor 'com.google.dagger:dagger-android-processor:2.15'
        annotationProcessor 'com.google.dagger:dagger-compiler:2.15'
        api 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
        api 'com.google.firebase:firebase-core:16.0.7'
        api 'com.google.firebase:firebase-messaging:17.3.4'
    }

I was thinking that the generated POM file below might not match the library's dependencies, but they do.我在想下面生成的 POM 文件可能与库的依赖项不匹配,但它们确实如此。 The "scope" tags in the POM file should remove the need for "transitive=true" right? POM 文件中的“范围”标签应该不需要“transitive=true”,对吧?

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mydomain</groupId>
  <artifactId>my_library</artifactId>
  <version>1.3</version>
  <packaging>pom</packaging>
  <dependencies>
    <dependency>
      <groupId>com.android.support</groupId>
      <artifactId>appcompat-v7</artifactId>
      <version>27.1.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.android.support.constraint</groupId>
      <artifactId>constraint-layout</artifactId>
      <version>1.1.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.android.support</groupId>
      <artifactId>design</artifactId>
      <version>27.1.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.reactivex.rxjava2</groupId>
      <artifactId>rxandroid</artifactId>
      <version>2.1.0</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>io.reactivex.rxjava2</groupId>
      <artifactId>rxjava</artifactId>
      <version>2.2.4</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.github.instacart.truetime-android</groupId>
      <artifactId>library-extension-rx</artifactId>
      <version>3.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.dagger</groupId>
      <artifactId>dagger-android</artifactId>
      <version>2.15</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.nostra13.universalimageloader</groupId>
      <artifactId>universal-image-loader</artifactId>
      <version>1.9.5</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.firebase</groupId>
      <artifactId>firebase-core</artifactId>
      <version>16.0.6</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.firebase</groupId>
      <artifactId>firebase-messaging</artifactId>
      <version>17.3.4</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

You should be able to resolve this by changing your POM XML generation so that the <packaging> section is setup as aar rather than pom : 您应该能够通过更改POM XML生成来解决此问题,以便<packaging>部分设置为aar而不是pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.humanvideoboard</groupId>
  <artifactId>hvb_library</artifactId>
  <version>1.0</version>
  <packaging>aar</packaging>

However, now that I'm re-examining this, the cause for why it works with transitive dependencies is by the use of implementation vs api when building the library or when building the thing which is using the library. 但是,现在我正在重新检查它,它与transitive依赖关系一起工作的原因是在构建库时或在构建使用库的东西时使用implementation vs api If your library is exposing types from its dependencies as part of its public API, then those build dependencies need to be handled correctly in your library build. 如果您的库将其依赖项中的类型作为其公共API的一部分公开,则需要在库构建中正确处理这些构建依赖项。 See this page for more information. 有关更多信息,请参阅此页面

I've faced similar issue but my problem was that in the publication block i used the 'library' function instead of 'maven' function我遇到过类似的问题,但我的问题是在发布块中我使用了“库”函数而不是“maven”函数

In my library build.gradle i have such block:在我的库 build.gradle 我有这样的块:

afterEvaluation{
   publishing {
       publications {
            maven(MavenPublication) { // here I had library(MvenPublication) which caused the packaing to be pom instead of aar
           artifacts = ["build/outputs/aar/library-release.aar"]
       }
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM