gradle local jar dependency not working - gradle

I am pretty new to gradle.
This is my project configuration
Project
.
├── build.gradle
├── sub-project-1
│   ├── build.gradle
├── tests
│   ├── rest
│   └── unit
│   ├── build.gradle // Lets call this unit_build.gradle
My unit tests have a dependency on derby.jar, and the unit_build.gradle has the following:
dependencies{
..
testCompile fileTree(dir: "${System.getProperty('java.home')}/../db/lib", include: "derby.jar")
testCompile fileTree(dir: "${System.getProperty('java.home')}/../db/lib", include: "derbyclient.jar")
}
Note: We have our own repository and derby is not included in that. So we use it by adding it from local.
This works fine when I run a gradle build, followed by my test task.
But we also publish the jar to a test server and run it there where it fails with a class not found exception on derby.
What can be the reason? What should be done to fix this?
Gradle version - 1.12

this happens because you choose wrong target dependency configuration. I mean testCompile, instead of this you should use: testRuntime or testRuntimeClasspath

Related

From inside a Gradle dependency apply plugin to parent project

application is a Gradle based project made up of a collection of separate projects, each project published independently and individually added as dependencies based on application requirements:
.
└── application
├── build.gradle.kts
├── framework-lib1
│   └── build.gradle.kts
└── framework-lib2
└── build.gradle.kts
framework-lib2 is optional, it provides persistence capabilities, application can run without it.
framework-lib2 has dependencies on Liquibase/Postgres/Hibernate/SpringData and exposes them as api so they're consumable by application code.
build.gradle.kts for framework-lib2 applies Liquibase plugin, registering additional Liquibase related tasks to the Gradle context.
plugins {
id("org.springframework.boot") apply false
id("org.liquibase.gradle") version "2.0.4"
}
The problem is that these new Liquibase tasks are registered under the framework-lib2 grouping e.g. IntelliJ Gradle task UI.
Is there a way to apply the liquibase plugin from the dependency project to the project consuming the dependency?

grade subprojects & dependencies

This is definitely a beginner gradle question, but I just can't make it work.
I have a library and an application which depends on the library.
.
/ library
/ application
I can install the library through gradle install in ./library, then have the application depend on the library through the group/name/version, and pick up the library through the mavenLocal() repository in the application build.gradle, then build the app in the application folder. And that works.
But I'd like to have a project, and that I could have a single command to build the application and, if needed, the library too (similar to the maven -am flag).
Here's what I have right now, in the parent folder, build.gradle:
subprojects {
apply plugin: "java"
repositories {
mavenCentral()
}
}
project(':application') {
dependencies {
compile project(':library')
}
}
and in the same folder I have settings.gradle:
include ':library', ':application'
Again, if I go in the library folder and run gradle install, it works. I get the artifact in my ~/.m2.
But now with the configuration I described, if I go in the root folder and run gradle shadowJar.. and the shadowJar task is present only in application, then gradle tries to compile the library but fails, apparently because it doesn't pick up the library dependencies.
* What went wrong:
Execution failed for task ':library:compileJava'.
> Compilation failed; see the compiler error output for details.
the errors are like, for instance:
Task :library:compileJava FAILED
.../DateTimeAdapter.java:5: error: package javax.xml.bind.annotation.adapters does not exist
import javax.xml.bind.annotation.adapters.XmlAdapter;
and sure enough these are dependencies in the library/build.gradle =>
implementation 'com.fasterxml.jackson.core:jackson-core:2.8.8'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.8'
So my question is how do I specify the application dependency on library, so that I can run a single command and have maven build the library if needed, then the application.. I thought what I did would have gotten the first part through, but it fails, apparently due to library's transitive dependencies. I actually expect I need to handle a second part after that, which is how to specify the dependency in the application build.json. I may have to switch from specifying the maven group/name/version coordinates to the project name, but I didn't get that far yet.
I would definitely not want to list the library dependencies in the root gradle file: I'd like library to handle its dependencies, and application its dependencies, I'd like to keep the root gradle file small.
application is unable to see the dependencies of library because you have declared the Jackson dependencies as an implementation detail of library.
What you intended to do was expose your library and it's dependencies as an api for consumers.
Dependencies declared in the implementation configuration can be thought of as "private" meaning consumers of your library should not access methods/classes that use those dependencies otherwise they will face errors like the one you are. api is basically the opposite of implementation.
The api configuration is available via the java-library plugin.
Full working example for what you're trying to achieve (Kotlin DSL):
├── application
│   └── build.gradle.kts
├── build.gradle.kts
├── gradle
│   └── wrapper
│   ├── gradle-wrapper.jar
│   └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
│   └── build.gradle.kts
└── settings.gradle.kts
Root project build.gradle.kts:
subprojects {
apply {
plugin("java-library")
}
repositories {
jcenter()
}
}
settings.gradle.kts:
rootProject.name = "example-proj"
include("application")
include("library")
Library build.gradle.kts:
dependencies {
api("com.fasterxml.jackson.core:jackson-core:2.10.0")
api("com.fasterxml.jackson.core:jackson-databind:2.10.0")
}
Application build.gradle.kts:
dependencies {
implementation(project(":library"))
}

Gradle subproject dependency is not resolvable by project that needs it

I have the following project strucuture:
example
├── build.gradle
├── module1
│   ├── build.gradle
│   └── main
│   ├── java
│   │   ├── module-info.java
│   │   └── com.example.module1
│   │   └── Example.java
│   └── resources
│   └── application.yml
└── module2
├── build.gradle
├── main
│   ├── java
│   │   ├── module-info.java
│   │   └── com.example.module2
│   │   └── Example2.java
└── test
module1 build.gradle
repositories {
maven {
url 'http://download.osgeo.org/webdav/geotools/'
name 'Open Source Geospatial Foundation Repository'
}
maven {
url 'https://repo.boundlessgeo.com/main/'
name 'Boundless Maven Repository'
}
maven {
url 'http://repo.boundlessgeo.com/snapshot'
name 'Geotools SNAPSHOT repository'
mavenContent {
snapshotsOnly()
}
}
mavenCentral()
jcenter()
}
dependencies {
implementation "org.geotools:gt-main:$geotoolsVersion"
}
module2 build.gradle (depends on module1)
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation project(':module1')
}
The problem is that when resolving the dependencies for module2, it is unable to find the transitive dependencies of module1, and so I get the following error:
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':module2'.
> Could not resolve all files for configuration ':module2:runtimeClasspath'.
> Could not find org.geotools:gt-main:21.2.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/org/geotools/gt-main/21.2/gt-main-21.2.pom
- https://repo.maven.apache.org/maven2/org/geotools/gt-main/21.2/gt-main-21.2.jar
- https://jcenter.bintray.com/org/geotools/gt-main/21.2/gt-main-21.2.pom
- https://jcenter.bintray.com/org/geotools/gt-main/21.2/gt-main-21.2.jar
Required by:
project :module2 > project :module1
It looks like it is only searching for the transitive deps of module1 using the repositories declared in module2 instead of in module1.
Interestingly, if I change the dependency in module2 to:
dependencies {
compileClasspath project(':module1')
}
The dependencies are resolved. However this means that at runtime, module1 is not part of the classpath, so running the application still fails.
How can I fix this?
The problem is that project dependencies do not leak their repository locations when depended on.
The fix is to move the repositories into the root build.gradle. Something like:
subprojects {
repositories {
//https://docs.geotools.org/latest/userguide/build/maven/repositories.html
maven {
url 'http://download.osgeo.org/webdav/geotools/'
name 'Open Source Geospatial Foundation Repository'
}
maven {
url 'https://repo.boundlessgeo.com/main/'
name 'Boundless Maven Repository'
}
}
}
See the following github issues:
https://github.com/gradle/gradle/issues/4106
https://github.com/gradle/gradle/issues/8811

Adding sub project dependency in gradle works weirdly, IntelliJ

I have a gradle multi project.
'root' has 2 sub projects which named 'domain' and 'web'. 'web' needs to use classes which are declared in 'domain' project.
However whenever I add compile project(':domain') into dependencies of 'web'.
Intellij says 'root_main', 'root_test', 'web_main', 'web_test' are not imported from Gradle anymore, which I don't want to.
Could you tell me how I can add dependency 'domain' into 'web'?
The structure is below :
root
├── build.gradle
├── domain
│ ├── build.gradle
│ └── src
│ └── main
│ └── test
│
├── web
│ ├── build.gradle
│ └── src
│ └── main
│ └── test
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
'build.gradle' in root
version '1.0-SNAPSHOT'
allprojects {
group = 'com.sample.projects.multi'
apply plugin: 'java'
apply plugin: 'eclipse'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
}
'build.gradle' in domain
version '1.0-SNAPSHOT'
dependencies {
}
'build.gradle' in web
version '1.0-SNAPSHOT'
dependencies {
compile project(':domain')
}
For ppl who might have same issue with me, I resolved this by updating Intellij to newer one. Mine was 2017.1 and I updated it to 2018.1.

Gradle: Adding publish task of submodule as dependency to another submodule

My project layout is like this
A
├── B
│   ├── build.gradle
│   └── Example-0.0.1.jar
├── build.gradle
├── C
│   ├── build.gradle
│   └── src
│   └── main
│   └── java
│   └── com
│   └── sample
│   └── Hello.java
└── settings.gradle
Now, B uses maven-publish to publish Example-0.0.1.jar to local maven archives (i.e ~/.m2/repositories)
C is a java project. The Hello.java file uses the Example jar file.
I am using gradle 2.2 to build this project.
I have
$ cat A/build.gradle
allprojects {
repositories {
mavenCentral()
mavenLocal()
}
}
and
$ cat A/settings.gradle
include ':B'
include ':C'
and
$ cat A/B/build.gradle
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
groupId 'com.example'
artifactId 'abc'
version '0.0.1'
artifact 'Example-0.0.1.jar'
}
}
}
and
$ cat A/C/build.gradle
apply plugin: 'java'
apply plugin: 'maven'
dependencies {
compile project(':B')
compile 'com.example:abc:0.0.1'
}
Now, whenever I run any gradle command, I get the following error:
$ gradle tasks
Execution failed for task ':tasks'.
> Could not determine the dependencies of task ':C:compileJava'.
Is there any way such that task B:publishToMavenLocal be run before building of C in order to include the jar?
I was also stuck with the same issue.
Figured out a way to achieve this. I added following to parent build.gradle file and everything is now working as expected.
project(':project-B').tasks.compileJava.dependsOn project(':project-A').tasks.install
So now when i am executing the build, artifacts of project-A is being installed to local repository and then project-B is able to take them from there. Good Luck!!

Resources