For some weird reasons, I'm using local filetree based jars in the gradle classpath.
from sub-module(project), I want to exclude one of the local jar. but I'm missing the syntax for it, can someone provide me correct syntax to exclude the local jar file(s) as a transitive dependency here?
dependencies {
implementation(project(":my-simple-project")) {
exclude fileTree(dir: "../lib/", include: ["axis2-1.7.8/axis2-transport-http-1.7.8.jar"])
}
}
OR
dependencies {
implementation(project(":my-simple-project")) {
exclude files("../lib/axis2-1.7.8/axis2-transport-http-1.7.8.jar"])
}
}
I got an error as
* What went wrong:
A problem occurred evaluating project ':my-simple-project'.
> Could not find method exclude() for arguments [directory '../lib/'] on DefaultProjectDependency{dependencyProject='project ':my-simple-project'', configuration='default'} of type org.gradle.api.internal.artifacts.dependencies.DefaultProjectDependency.
You can only exclude module dependencies, not file dependencies.
If you cannot resolve your dependencies from public repositories like Maven Central or JCenter, you can create a local Maven repository (even inside your project structure) and resolve the files directly from there:
repositories {
maven {
url uri("${projectDir}/lib")
}
}
dependencies {
implementation 'org.apache.axis2:axis2-transport-http:1.7.8'
}
Please note, that you must modify the directory structure in your lib folder to match the Maven directory structure (or alternatively define an Ivy repository with a custom structure).
You can exclude nested jar using the following syntax:
fileTree(dir: 'lib').exclude {details ->
(details.file.canonicalPath.contains("axis2-1.7.8")
&& details.file.canonicalPath.contains('axis2-transport-http-1.7.8'))}
OR
fileTree(dir: 'lib').exclude { details ->
details.file.text.contains('axis2-transport-http')
}
Reference : Gradle fileTree exclude all except certain directories
I'm attempting to include a generated pom.xml in the jar that I'm creating with gradle.
So far, in my parent project, I have
subprojects {
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
from(components.java)
}
}
}
}
and in the sub-project I have:
tasks.build.dependsOn install
sourceSets {
main {
resources {
srcDirs = [ "src/main/resources", "build/poms" ]
}
}
}
This will generate ./build/poms/pom-default.xml, but it will not add it to the JAR.
Creating a dependency on an earlier phase than build creates circular dependencies (and I don't know whether this is the problem anyway).
Also, I'd like the pom.xml to show up inside META-INF with name pom.xml (not pom-default.xml), so this may not be the right approach anyway.
Somehow I'm thinking it can't be as complicated as this looks?
You should be able to include the POM in your JAR by adding the following to your subprojects closure:
jar {
into("META-INF/maven/${project.group}/${project.name}") {
from generatePomFileForMavenPublication
rename { it.replace('pom-default.xml', 'pom.xml') }
}
}
If you already have a jar closure, you can add it there. This automatically creates a task dependency on the generatePomFileForMavenPublication task, so that the POM file is there when the JAR is created.
The sourceSets part from your question would not be required for this.
(Side note: It would not be strictly necessary to do this at all, because the Maven publish process will publish the POM as an individual artifact anyway.)
I have tried to add my local .jar file dependency to my build.gradle file:
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')
}
And you can see that I added the .jar files into the referencedLibraries folder here: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1/referencedLibraries
But the problem is that when I run the command: gradle build on the command line I get the following error:
error: package com.google.gson does not exist
import com.google.gson.Gson;
Here is my entire repo: https://github.com/WalnutiQ/wAlnut/tree/version-2.3.1
According to the documentation, use a relative path for a local jar dependency as follows.
Groovy syntax:
dependencies {
implementation files('libs/something_local.jar')
}
Kotlin syntax:
dependencies {
implementation(files("libs/something_local.jar"))
}
If you really need to take that .jar from a local directory,
Add next to your module gradle (Not the app gradle file):
repositories {
flatDir {
dirs("libs")
}
}
dependencies {
implementation("gson-2.2.4")
}
However, being a standard .jar in an actual maven repository, why don't you try this?
repositories {
mavenCentral()
}
dependencies {
implementation("com.google.code.gson:gson:2.2.4")
}
You could also do this which would include all JARs in the local repository. This way you wouldn't have to specify it every time.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
The following works for me:
compile fileTree(dir: 'libs', include: '*.jar')
Refer to the Gradle Documentation.
You can try reusing your local Maven repository for Gradle:
Install the jar into your local Maven repository:
mvn install:install-file -Dfile=utility.jar -DgroupId=com.company -DartifactId=utility -Dversion=0.0.1 -Dpackaging=jar
Check that you have the jar installed into your ~/.m2/ local Maven repository
Enable your local Maven repository in your build.gradle file:
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation ("com.company:utility:0.0.1")
}
Now you should have the jar enabled for implementation in your project
A solution for those using Kotlin DSL
The solutions added so far are great for the OP, but can't be used with Kotlin DSL without first translating them. Here's an example of how I added a local .JAR to my build using Kotlin DSL:
dependencies {
compile(files("/path/to/file.jar"))
testCompile(files("/path/to/file.jar"))
testCompile("junit", "junit", "4.12")
}
Remember that if you're using Windows, your backslashes will have to be escaped:
...
compile(files("C:\\path\\to\\file.jar"))
...
And also remember that quotation marks have to be double quotes, not single quotes.
Edit for 2020:
Gradle updates have deprecated compile and testCompile in favor of implementation and testImplementation. So the above dependency block would look like this for current Gradle versions:
dependencies {
implementation(files("/path/to/file.jar"))
testImplementation(files("/path/to/file.jar"))
testImplementation("junit", "junit", "4.12")
}
The accepted answer is good, however, I would have needed various library configurations within my multi-project Gradle build to use the same 3rd-party Java library.
Adding '$rootProject.projectDir' to the 'dir' path element within my 'allprojects' closure meant each sub-project referenced the same 'libs' directory, and not a version local to that sub-project:
//gradle.build snippet
allprojects {
...
repositories {
//All sub-projects will now refer to the same 'libs' directory
flatDir {
dirs "$rootProject.projectDir/libs"
}
mavenCentral()
}
...
}
EDIT by Quizzie: changed "${rootProject.projectDir}" to "$rootProject.projectDir" (works in the newest Gradle version).
Shorter version:
dependencies {
implementation fileTree('lib')
}
The Question already has been answered in detail. I still want to add something that seems very surprising to me:
The "gradle dependencies" task does not list any file dependencies. Even though you might think so, as they have been specified in the "dependencies" block after all..
So don't rely on the output of this to check whether your referenced local lib files are working correctly.
A simple way to do this is
compile fileTree(include: ['*.jar'], dir: 'libs')
it will compile all the .jar files in your libs directory in App.
Some more ways to add local library files using Kotlin DSL (build.gradle.kts):
implementation(
files(
"libs/library-1.jar",
"libs/library-2.jar",
"$rootDir/foo/my-other-library.jar"
)
)
implementation(
fileTree("libs/") {
// You can add as many include or exclude calls as you want
include("*.jar")
include("another-library.aar") // Some Android libraries are in AAR format
exclude("bad-library.jar")
}
)
implementation(
fileTree(
"dir" to "libs/",
// Here, instead of repeating include or exclude, assign a list of paths
"include" to "*.jar",
"exclude" to listOf("bad-library-1.jar", "bad-library-2.jar")
)
)
The above code assumes that the library files are in libs/ directory of the module (by module I mean the directory where this build.gradle.kts is located).
You can use Ant patterns in includes and excludes as shown above.
See Gradle documentations for more information about file dependencies.
Thanks to this post for providing a helpful answer.
I couldn't get the suggestion above at https://stackoverflow.com/a/20956456/1019307 to work. This worked for me though. For a file secondstring-20030401.jar that I stored in a libs/ directory in the root of the project:
repositories {
mavenCentral()
// Not everything is available in a Maven/Gradle repository. Use a local 'libs/' directory for these.
flatDir {
dirs 'libs'
}
}
...
compile name: 'secondstring-20030401'
The best way to do it is to add this in your build.gradle file and hit the sync option
dependency{
compile files('path.jar')
}
The solution which worked for me is the usage of fileTree in build.gradle file.
Keep the .jar which need to add as dependency in libs folder. The give the below code in dependenices block in build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
You can add jar doing:
For gradle just put following code in build.gradle:
dependencies {
...
compile fileTree(dir: 'lib', includes: ['suitetalk-*0.jar'])
...
}
and for maven just follow steps:
For Intellij:
File->project structure->modules->dependency tab-> click on + sign-> jar and dependency->select jars you want to import-> ok-> apply(if visible)->ok
Remember that if you got any java.lang.NoClassDefFoundError: Could not initialize class exception at runtime this means that dependencies in jar not installed for that you have to add all dependecies in parent project.
For Gradle version 7.4 with Groovy build file
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation ':gson-2.2.4'
}
If you are on gradle 4.10 or newer:
implementation fileTree(dir: 'libs', includes: ['*.jar'])
Goto File -> Project Structure -> Modules -> app -> Dependencies Tab -> Click on +(button) -> Select File Dependency - > Select jar file in the lib folder
This steps will automatically add your dependency to gralde
Very Simple
Be careful if you are using continuous integration, you must add your libraries in the same path on your build server.
For this reason, I'd rather add jar to the local repository and, of course, do the same on the build server.
An other way:
Add library in the tree view. Right click on this one. Select menu "Add As Library".
A dialog appear, let you select module. OK and it's done.
I have inherited a codebase which I suspect was originally built with Gradle 4 (but I don't know for sure). I am using Gradle 5.5.1 and when I run gradle I get errors to do with publication to a Maven repo:
* What went wrong:
A problem occurred evaluating root project 'common'.
> Could not find method sourcesJar() for arguments [build_d1u03z05r8d12r3e8b5qq1fxm$_run_closure3$_closure13$_closure15$_closure16#190bc2b8] on object of type org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication.
Add sourcesJar task to custom Gradle plugin looks like a similar problem but it is a different error and their solution doesn't work anyway.
The relevant parts of my build.gradle are:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
}
}
repositories {
maven {
url 'http://repo.url'
credentials {
username "$username"
password "$password"
}
}
}
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
}
task testJar(type: Jar) {
from sourceSets.test.output
classifier = 'tests'
}
Okay I think I figured it out: https://docs.gradle.org/5.5.1/userguide/publishing_maven.html#publishing_maven:deferred_configuration says that a publishing block was executed after the rest of the project in Gradle 4, but not in Gradle 5.
So, changing
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
to
afterEvaluate {
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
}
got me a little further. With that change I then got this error:
* What went wrong:
A problem occurred configuring root project 'common'.
> Cannot create a Publication named 'sourcesJar' because this container does not support creating elements by name alone. Please specify which subtype of Publication to create. Known subtypes are: MavenPublication
https://discuss.gradle.org/t/cannot-create-a-publication-named-x/3726 and Gradle: Using 'maven-publish' plugin in custom standalone plugin seem to suggest that a prefix of project. should fix it.
So changing it to:
afterEvaluate {
artifact project.sourcesJar {
classifier "sources"
}
artifact project.testJar {
classifier "tests"
}
}
seems to work, though I'm a little iffy on the project. prefix.
In my case I had to add the following that Gradle was aware about the artifacts:
java {
withJavadocJar()
withSourcesJar()
}
Then I was able to use it this way:
publishing.publications {
mavenJava(MavenPublication) {
from components.java
}
}
Javadoc as well as Sources were published. There seems to be no need to add the afterEvaluate block.
In this block:
artifact sourcesJar {
classifier "sources"
}
artifact testJar {
classifier "tests"
}
remove the closures...just make it look like this:
artifact sourcesJar
artifact testJar
I would like to control which of my dependencies in a multi-project Java build are transitive. My current solution is to set up an "export" configuration in the root project:
allprojects {
configurations {
export {
description = 'Exported classpath'
}
compile {
extendsFrom export
}
}
}
Project A has multiple file dependencies:
dependencies {
compile files('A.jar', 'B.jar')
export files('C.jar')
}
Project B has a dependency on project A, but only C.jar should be on the classpath for compilation, so add:
dependencies {
export project(path: ':A', configuration:'export')
}
This produces the desired results, A.jar and B.jar are not on the class path, but C.jar is on the classpath for compilation.
I am unsure if this is "gradle" way of doing things. To configure transitivity, I would rather specify an attribute or a configuration closure to the dependency entries in project A, instead of using a different "export" configuration.
Is this possible for file dependencies, or is there another way to achieve this?
If I understand your scenario correctly, then yes it's easy to do this. Just add an options closure to the end of the dependency declaration to prevent transitive dependencies (I've changed A,B,C .jar to X,Y,Z because I'm guessing they don't coincide with projects A and B):
// Project A build.gradle
dependencies {
compile(files('X.jar', 'Y.jar')) { transitive = false }
export files('Z.jar')
}
Which would prevent X.jar and Y.jar from being added to the classpath for project B.
Alternatively, and I don't know how well this would work for you and don't really recommend it (just want you to know of the possibilities) you could do this in project B's build.gradle:
configurations.compile.dependencies.find { it.name == "A.jar" }.exclude(jar: it)
configurations.compile.dependencies.find { it.name == "B.jar" }.exclude(jar: it)
Hope that helps.