如何将本地的.jar文件依赖添加到build.gradle文件中?

812

我尝试将本地的 .jar 文件依赖项添加到我的 build.gradle 文件中:

apply plugin: 'java'

sourceSets {
    main {
        java {
            srcDir 'src/model'
        }
    }
}

dependencies {
    runtime files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
    runtime fileTree(dir: 'libs', include: '*.jar')
} 

你可以看到我将.jar文件添加到了referencedLibraries文件夹中,链接如下:https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1/referencedLibraries

但问题是,当我在命令行上运行命令:gradle build时,会出现以下错误:

error: package com.google.gson does not exist
import com.google.gson.Gson;

这是我的整个仓库:https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1


你确定要使用运行时而不是编译时吗? 编译文件(...) - Gabriele Mariotti
3
如果无法构建JAR包,则看起来是编译依赖关系。 尝试: compile files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')如果仍有问题,请尝试绝对路径,因为那也可能是问题所在。 - homik
1
这个Stack Overflow问题最终给了我需要的答案。 - craned
这个回答解决了你的问题吗?Android Studio:如何将jar文件添加为库? - Mahozad
22个回答

971
根据文档,本地 jar 依赖项使用相对路径,如下所示。 Groovy 语法:
dependencies {
    implementation files('libs/something_local.jar')
}

Kotlin 语法:

dependencies {
    implementation(files("libs/something_local.jar"))
}

11
@Gubatron,现在有文档记录了此事:http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:file_dependencies - David Moles
12
我想补充一点,对于那些使用相对路径引用我们的jar包的人: 在Groovy中需要使用双引号而不是单引号来评估路径,因此您的依赖项应该是: dependencies { compile files("libs/something_local.jar") }。 - specialk1st
所以我正在使用相同的东西,但是我遇到了编译错误(看起来它在那里找不到jar文件)。如果我提供绝对路径,它就可以正常工作。 - RV_Dev
2
请注意 - 如果您的jar包中有外部依赖项,则必须构建一个shadow jar才能以这种方式使用它,但是,如果将其发布到本地maven仓库,则不需要这样做。 - wieczorekm
1
值得一提的是,示例中的libs/目录是基于git仓库的根目录。 - undefined
显示剩余5条评论

559

如果您确实需要从本地目录获取那个.jar文件,请在您的模块gradle文件中添加以下内容(而不是应用程序gradle文件):

repositories {
   flatDir {
       dirs("libs")
   }
}


dependencies {
   implementation("gson-2.2.4")
}

然而,作为实际Maven仓库中的标准.jar文件,为什么不尝试一下呢?

repositories {
   mavenCentral()
}
dependencies {
   implementation("com.google.code.gson:gson:2.2.4")
}

6
我来寻找正是这个,但我发现我的本地仓库无法解析传递依赖关系。(Gradle 2.7,示例POM是由minecraftforge.net提取的com.mojang:authlib:1.5.21) - Karl the Pagan
1
如果您有多个目录中的本地jar文件,则需要将它们全部添加到flatDir中。例如:flatDir { dirs 'libs1','libs2','libs3'} - Dhumil Agarwal
15
我有一个 gradle.build 文件 - 什么是 "app gradle file" 和 "module gradle"? - Lealo
2
有没有人能更新答案,附上指向官方Gradle文档中描述这些功能的部分的链接? - kuza
3
看起来 implementation(":gson:2.2.4") 是实现它的方式。 - Eng.Fouad
显示剩余5条评论

365

你也可以这样做,它会包含本地存储库中的所有JAR文件。这样你就不必每次都指定它。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

3
这是用于编译lib目录中所有jar包的工具。它是完美的解决方案 (y) - Sheraz Ahmad Khilji
1
除非您计划与具有不同依赖项集的不同模块共享该libs目录,例如不将服务器代码与客户端代码放在一起,或者在不同的子模块中拥有多个版本的依赖项。 - Ajax
2
请注意,dir 可以是绝对路径。另外,我不得不使用“includes”代替“include”。 - eriel marimon
11
对于 Gradle 7+ 版本,请使用 implementation fileTree(dir: 'lib', includes: ['*.jar'])(或根据您的需求选择api)。 - m02ph3u5
有人可以帮忙定义flatDir并且仅添加依赖项,因为实现fileTree不会添加本地libs/jar文件吗?@gradle 6.5 - PruthviRaj Reddy
显示剩余2条评论

60
以下方法适用于我:

compile fileTree(dir: 'libs', include: '*.jar')

请参考 Gradle文档

重要的是要记住,如果您不想让特定的库与您的项目一起编译,那么您将需要记住从libs文件夹中删除它...我不喜欢这种方法,因为除非我进入库,否则我看不到我添加了哪个库。 - Jesus Dimrix
2
这与@Nightwolf的答案有何不同之处? - Trenton
2
在类型为org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler的对象上找不到参数[directory 'libs']的compile()方法。 - ieXcept
如何访问特定模块的文件夹?我想将依赖项添加到“app”模块,以访问另一个模块文件夹中的某个aar文件。意思是:library/build/outputs/aar/library-release.aar - android developer
Gradle的新版本不再支持“compile”,我们需要使用“implementation”代替。因此,类似于“implementation fileTree(dir: 'libs', include: ['*.jar'])”这样的语句。 - Farshad Bakhshandegan Moghadda
这是一个简单的fileTree规范,所以,适用于fileTree规范的所有内容也适用于这个规范,因此你可以使用compile fileTree(dir: 'libs', include: '*.jar', exclude: 'junit.jar')这样的方式来排除任何特定的项目。 - mahee96

50

您可以尝试在Gradle中重复使用本地Maven存储库:

  • 将jar文件安装到本地Maven存储库中:

    mvn install:install-file -Dfile=utility.jar -DgroupId=com.company -DartifactId=utility -Dversion=0.0.1 -Dpackaging=jar

  • 检查您是否已经将该jar文件安装到~/.m2/本地Maven存储库中

  • 在您的build.gradle文件中启用您的本地Maven存储库:

    repositories {
      mavenCentral()  
      mavenLocal()  
    }
    
    dependencies {  
      implementation ("com.company:utility:0.0.1")  
    }
    
    • 现在您应该已经启用了jar文件,可以在项目中进行实现

1
这个在其他方法都失败时帮了我一个大忙! - User3
2
虽然这个方法可行,但这只是一个权宜之计,不应在自动化生产/阶段环境中使用,因为这会增加构建系统中具有 .m2 文件夹(Maven 安装)的额外依赖。 - saurav.varma
当我尝试运行Gradle命令时,出现了错误:无法解析POM,已经看到doctype。 - SledgeHammer
在将值用双引号括起来后,对我起了作用。mvn install:install-file -Dfile="utils-1.0.5.jar" -DgroupId="com.company" -DartifactId=commons -Dversion="3.1.3" -Dpackaging=jar - undefined

37

针对使用 Kotlin DSL 的人提供的解决方案

到目前为止添加的解决方案对于原始发布者来说很棒,但是在使用 Kotlin DSL 时需要先将其翻译成可用的形式。以下是我如何使用 Kotlin DSL 将本地 .JAR 添加到构建中的示例:

dependencies {
    compile(files("/path/to/file.jar"))
    testCompile(files("/path/to/file.jar"))
    testCompile("junit", "junit", "4.12")
}

请记住,如果您使用的是Windows系统,那么反斜杠需要进行转义:

...
compile(files("C:\\path\\to\\file.jar"))
...

并且请记住,引号必须为双引号而不是单引号。


2020年更新:

Gradle更新已经废弃了compiletestCompile,推荐使用 implementationtestImplementation。 因此,对于当前的Gradle版本,以上依赖块将如下所示:

dependencies {
    implementation(files("/path/to/file.jar"))
    testImplementation(files("/path/to/file.jar"))
    testImplementation("junit", "junit", "4.12")
}

1
+1 对我有用!你知道如何在不生成 jar 文件的情况下执行相同的操作吗?(假设我已经生成了 jar 文件) - KareemJ
2
@KareemJeiroudi 我可能误解了你的问题,但如果你是在谈论如何将一个模块作为项目的依赖项,你可以这样做:compile(project(":MyProject")),其中"MyProject"在你的settings.gradle文件中定义为include("MyProject") - Jonathan E. Landrum

36

已接受的答案不错,但是在我的多项目Gradle构建中,我需要使用相同的第三方Java库,但需要进行不同的库配置。

在我的'allprojects'闭包中,在'dir'路径元素中添加'$rootProject.projectDir',这意味着每个子项目引用相同的'libs'目录,而不是特定于该子项目的版本:

//gradle.build snippet
allprojects {
    ...

    repositories {
        //All sub-projects will now refer to the same 'libs' directory
        flatDir {
            dirs "$rootProject.projectDir/libs"
        }
        mavenCentral()
    }

    ...
}

Quizzie进行了编辑:将"${rootProject.projectDir}"更改为"$rootProject.projectDir"(在最新的Gradle版本中有效)。


2
但是如何在库的build.gradle文件中引用这个libs文件夹呢?对此有什么帮助吗? - jeevs
1
只需将"${rootProject.projectDir}"更改为"$rootProject.projectDir"即可使其再次正常工作。 - Quizzie
6
请使用双引号而不是单引号,因为后者无法插值。 - F. P. Freely
1
这个方法帮了我。 - Shreyash
1
这里的所有答案都对我有很大帮助。这种模式是我们正在使用的,它使得团队中的人们在处理分支时只需将JAR文件放入该目录即可轻松完成。 - Lucy
更简单地使用 rootDir - smac89

20

简短版:

dependencies {
    implementation fileTree('lib')
}

16

这个问题已经被详细回答了。不过我还想补充一些令人惊讶的事情:

"gradle dependencies"任务不会列出任何文件依赖关系。尽管您可能认为会列出来,因为它们毕竟已在“dependencies”块中指定...

因此,不要依赖于此输出来检查您引用的本地lib文件是否正常工作。


3
哇,真希望我三个小时前就读了你的回答!谢谢。这是Gradle团队为我们开发者设置的另一个难点。 - georgiecasey

14

一个简单的方法是

compile fileTree(include: ['*.jar'], dir: 'libs')

它将会编译应用中libs目录下的所有.jar文件。


fileTree是否适用于libs文件夹中的所有子目录?例如,libs/sping/spring.jar中有几个jar包,在这种情况下,它是否也包括spring.jar? - mgr
不,它不应该。从技术上讲,也不应该,因为我们正在提供'dir:libs'而不是libs的子目录。 - ZygoteInit
在这种情况下,如何以最小的任务量从子目录中获取所有库(因为我们的项目包含如此多的子目录)。 - mgr
嘿 @mallikgm,抱歉回复晚了,你尝试在目录路径中添加通配符,例如 compile fileTree(include: ['.jar'], dir: 'libs') 吗? - ZygoteInit
2
这与@Nightwolf的答案有何不同? - Trenton
我认为这是最好的解决方案。如果您使用Intellij“android”新项目类型生成它,则此内容已经在您的build.gradle中。 - John Henckel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接