简体   繁体   English

Gradle/Maven/Android:通过 maven 使用库时找不到库私有依赖项

[英]Gradle/Maven/Android: Library-private dependency not found when library is used via maven

I have a SampleApp with a library module attached:我有一个带有库模块的 SampleApp:

:app
:library

The library is using the following dependency and the following code:该库使用以下依赖项和以下代码:

implementation "com.google.android.gms:play-services-safetynet:17.0.1"

----

import android.content.Context
import com.google.android.gms.safetynet.SafetyNet

class ClassUsingSafetynet {
    fun trigger(context: Context) {
        SafetyNet.getClient(context)
    }
}

The SampleApp is calling trigger somewhere: SampleApp 在某处调用trigger

val triggerClass = ClassUsingSafetynet()
triggerClass.trigger(context)

This works without problems as long as the SampleApp declares its dependency directly on the library module:只要 SampleApp 直接在库模块上声明它的依赖关系,这就没有问题:

implementation project(path: ':library')

But if I deploy the library aar to my local maven and declare the dependency accordingly like this:但是,如果我将库 aar 部署到本地 maven 并相应地声明依赖项,如下所示:

implementation ('com.myapplication:library:1.0.3@aar') { transitive = true }

I get the following crash我遇到以下崩溃

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/safetynet/SafetyNet;
        at com.library.ClassUsingSafetynet.trigger(ClassUsingSafetynet.kt:10)
        at com.myapplication.MainActivity.onCreate$lambda-0(MainActivity.kt:38)

Here is the publish gradle task:这是发布 gradle 任务:

afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {

                groupId 'com.myapplication'
                artifactId 'library'
                version '1.0.3'
                artifact 'build/outputs/aar/library-release.aar'

                pom.withXml {
                    def dependenciesNode = asNode().appendNode('dependencies')

                    configurations.api.allDependencies.each {
                        def dependencyNode = dependenciesNode.appendNode('dependency')
                        dependencyNode.appendNode('groupId', it.group)
                        dependencyNode.appendNode('artifactId', it.name)
                        dependencyNode.appendNode('version', it.version)
                    }
                }
            }
        }
        repositories {
            mavenLocal()
        }
    }
}

I have tried to use api instead of implementation for the SafetyNet dependency.我尝试使用api而不是 SafetyNet 依赖项的implementation No difference.没有不同。

I have tried to set/not set {transitive = true} .我试图设置/不设置{transitive = true} No difference.没有不同。

I have tried to set/not set @aar .我试图设置/不设置@aar No difference.没有不同。

I have tried to not create the pom file.我试图不创建 pom 文件。 No difference.没有不同。

No ProGuard is applied for now. ProGuard暂时没有申请。


What's especially strange to me is that "SafetyNet" is a private dependency of the library.对我来说特别奇怪的是“SafetyNet”是库的私有依赖项。 My app doesn't even need to know about it.我的应用程序甚至不需要知道它。

The published POM file needs to declare all runtime dependencies of the library, not just its API dependencies.发布的 POM 文件需要声明库的所有运行时依赖项,而不仅仅是它的 API 依赖项。 In other words, you need to use the following when adding dependencies to the POM:换句话说,在向 POM 添加依赖项时需要使用以下内容:

    configurations.releaseRuntimeClasspath.allDependencies.each {
        // …
    }

The following is a misunderstanding:以下是误区:

"SafetyNet" is a private dependency of the library. “SafetyNet”是库的私有依赖项。 My app doesn't even need to know about it.我的应用程序甚至不需要知道它。

Your app should indeed not have to worry about this “private dependency” but it still has to (be able to) make it available to the library at runtime – as the library doesn't work without it because it still is a dependency of the library.您的应用程序确实不必担心这种“私有依赖性”,但它仍然必须(能够)在运行时将其提供给库——因为库没有它就无法工作,因为它仍然是图书馆。

I've successfully tested this change with a small dummy Android project.我已经用一个小的虚拟 Android 项目成功地测试了这个变化。 Let me know if you can't get your build to work with the above information;如果您无法让您的构建使用上述信息,请告诉我; then I can add a self-contained, working sample project to my answer.然后我可以在我的答案中添加一个独立的、有效的示例项目。


That said, I wonder why you manually (a) specify the published artifact and (b) create the POM?也就是说,我想知道您为什么要手动 (a) 指定已发布的工件和 (b) 创建 POM? The following should work automagically (tested as described above):以下应该自动工作(如上所述测试):

    release(MavenPublication) {
        groupId 'com.myapplication'
        artifactId 'library'
        version '1.0.3'

        from components.release
    }

See alsothe docs .另请参阅文档

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

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