V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
tongpeng1995
V2EX  ›  问与答

maven 应该如何声明依赖?

  •  
  •   tongpeng1995 · 2017-03-11 11:10:12 +08:00 · 3749 次点击
    这是一个创建于 2799 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我写了一个 Android 库,封装了公司上一些常用的控件,其中该库也引用了其他第三方的控件。

    姑且把这个库称为Library A,然后引用了一个第三方库Gson,我想在工程Project1中引用Library A,以便提高效率。

    现在我把Library A打包成一个 AAR ,然后复制到工程Project1中,然后调用Library A里面的方法。编译没有问题,但是一运行,就会报一个 ClassNotFoundException的错误,表示找不到第三方库Gson

    但是如果我在Project1中加多一句compile 'com.google.code.gson:gson:2.8.0就不会崩溃了。

    最开始我以为是没把Gson打包到Library A中,解包Library A的 AAR 也是没有发现Gson的 jar 。所以一开始走了弯路,想办法把Gson的 jar 打包到Library A。在网上找到一个android-fat-aar的脚本,说是可以把第三方库也打包到 AAR 中。但是,打包完却又总是报Multiple dex files define的错误。

    最后在 stackoverflow 上看到一个回答,说不应该把第三方的库打包进 AAR ,这些依赖应该由 maven 来处理。

    接下来就根据这个教程搭建了一个私有的 maven 仓库,并且把Library A上传到私有仓库中。

    并且在Project1中用compile 'com.example:LibraryA:1.0.0'这种形式成功引用到Library A。但是一运行还是继续报ClassNotFoundException的错误。

    接着找到资料,说是要通过 pom.xml 来传递依赖。然后在找到一个build.gradle示例,是这样写的:

    忽略无关的语句

    def libraryGroupId = 'com.example'
    def libraryArtifactId = 'LibraryA'
    def libraryVersion = '1.0.0'
    
    publishing {
        publications {
            aar(MavenPublication) {
                groupId libraryGroupId
                version libraryVersion
                artifactId libraryArtifactId
                artifact("$buildDir/outputs/aar/${artifactId}-release.aar")
                //generate POM file
                pom.withXml {
                    def root = asNode()
                    def dependenciesNode = root.appendNode('dependencies')
                    //Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
                    configurations.compile.allDependencies.each {
                        if (it.group != null) {
                            def dependencyNode = dependenciesNode.appendNode('dependency')
                            dependencyNode.appendNode('groupId', it.group)
                            dependencyNode.appendNode('artifactId', it.name)
                            dependencyNode.appendNode('version', it.version)
                            dependencyNode.appendNode('scope','compile')
                        }
                    }
                }
    
            }
    
        }
    
    }
    
    
    artifactory {
        contextUrl = 'http://localserver:8081/artifactory'
        publish {
            repository {
                repoKey = 'libs-release-local'
                username = artifactory_username
                password = artifactory_password
            }
            defaults {
                publications('aar')
                publishArtifacts = true
                properties = ['qa.level': 'basic', 'q.os': 'android', 'dev.team': 'core']
                publishPom = true
            }
    
        }
    }
    

    执行后在私有的 maven 仓库上,的确看到如下的 dependency

    <dependency>
     <groupId>com.android.volley</groupId>
     <artifactId>volley</artifactId>
     <version>1.0.0</version>
     <scope>compile</scope>
    </dependency>
    <dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>2.8.0</version>
     <scope>compile</scope>
    </dependency>
    ......省略其他依赖
    

    但是一调用又崩溃了,又提示找不到类。

    然后我看了一下Project1的依赖,发现只引用了Library A,并没有引用Library A的依赖。

    依赖

    com.exmaple:Library:1.0.0并没有像com.android.support:appcompat-v7:25.2.0一样列出所需的依赖。

    折腾了好几天愣是没搞明白 maven 的依赖到底要怎么写。故请教一下各位,有没有朋友遇到过这样的问题?

    我想要实现的效果,就是可以在新的项目中直接compile 'com.example:LibraryA:1.0.0就可以引用我自己的库,而不用再去声明Library A所需要的依赖

    谢谢:)

    7 条回复    2019-03-14 15:17:58 +08:00
    kaneg
        1
    kaneg  
       2017-03-11 14:04:50 +08:00 via iPhone
    你的新 project 没有写 pom ?
    tongpeng1995
        2
    tongpeng1995  
    OP
       2017-03-11 15:30:25 +08:00
    @kaneg 没呀,新 Project 为什么要写 pom ? pom 不是库才需要写的么?
    ArthurKing
        3
    ArthurKing  
       2017-03-11 15:32:48 +08:00
    maven 项目不写 pom 文件?是我 out 了?
    tongpeng1995
        4
    tongpeng1995  
    OP
       2017-03-11 15:35:09 +08:00
    @ArthurKing 求指点,我对 maven 并不熟悉😂,刚接触不久,一直没搞明白如何声明依赖。
    nonesuccess
        5
    nonesuccess  
       2017-03-11 18:09:35 +08:00 via Android
    @tongpeng1995 找个 maven 入门教程看看吧,至少先知道为什么 pom 文件是必须的再说
    kaneg
        6
    kaneg  
       2017-03-11 19:35:27 +08:00 via iPhone
    @tongpeng1995 这就是你的新项目找不到 class 的原因,要把新项目都纳入 maven 的体系,依赖传递的特性才能起作用
    jackleeforce3615
        7
    jackleeforce3615  
       2019-03-14 15:17:58 +08:00
    在 Project 1 中的 build.gradle 里面使用 transitive = true,如
    compile ('com.example:LibraryA:1.0.0 ){ transitive = true }
    或者
    compile(group: 'com.example', name: 'LibraryA', version: '1.0.0', ext: 'aar') {
    transitive = true
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5398 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 06:57 · PVG 14:57 · LAX 22:57 · JFK 01:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.