Adding sub project dependency in gradle works weirdly, IntelliJ - gradle

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.

Related

Failure when applying custom external gradle plugin to multi-module gradle project

I'm having a hard time applying my custom external gradle plugins to an existing multi-module project. My project's structure looks like this:
my-app/
├─ buildSrc/
│ ├─ build.gradle.kts
├─ module1/
│ ├─ build.gradle.kts
├─ module2/
│ ├─ build.gradle.kts
├─ settings.gradle.kts
I've now implemented a couple of custom binary plugins which live in another repository and publishing them to mavenLocal() like so:
Plugin Repo Code
gradlePlugin {
plugins {
create("plugin") {
id = "organization.gradle.my-conventions"
implementationClass = "organization.gradle.MyConventionsPlugin"
version = "0.0.1"
}
create("plugin2") {
id = "organization.gradle.my-other-conventions"
implementationClass = "organization.gradle.MyOtherConventionsPlugin"
version = "0.0.1"
}
}
}
Main Project Code
In my main project, I've configured settings.gradle.kts to resolve plugins from mavenLocal and apply one of the plugins (let's say plugin1) in the build.gradle.kts of module1. This looks like this:
plugins {
id("organzation.gradle.MyConventionsPlugin") version "0.0.1"
}
This doesn't work though. I end up getting a stacktrace saying:
> Failed to apply plugin class 'org.jetbrains.kotlin.gradle.scripting.internal.ScriptingGradleSubplugin'.
> Cannot run Project.afterEvaluate(Action) when the project is already evaluated.
I tried the same way of applying the plugins in a non multi-module project (i.e. a single build.gradle.kts) and the plugins are applied as expected. So this most likely has to do with the multi-module aspect of it and some additional config?

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

gradle local jar dependency not working

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

Gradle - Include multiple WAR projects in an EAR

So I'm trying to create a root level ear project that will include multiple war projects and I can't seem to get it to work. To pare it down to the simplest level, lets suppose I have a directory structure like this:
myEar/
├── build.gradle
├── myWar1
│ ├── build.gradle
│ └── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── foo
│ │ └── hello.java
│ ├── resources
│ └── webapp
│ ├── test.html
│ └── WEB-INF
│ └── web.xml
├── myWar2
│ ├── build.gradle
│ └── src
│ └── main
│ ├── java
│ │ └── com
│ │ └── foo
│ │ └── hello.java
│ ├── resources
│ └── webapp
│ ├── test.html
│ └── WEB-INF
│ └── web.xml
├── settings.gradle
└── src
└── main
└── application
└── application.xml
Each build.gradle file in the myWarX subporjects is simply this:
defaultTasks 'war'
apply plugin: 'war'
When I run gradle from inside the myWar1/2 folder I get the expected output:
jar -xvf myWar1.war
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: WEB-INF/
created: WEB-INF/classes/
created: WEB-INF/classes/com/
created: WEB-INF/classes/com/foo/
inflated: WEB-INF/classes/com/foo/hello.class
inflated: WEB-INF/web.xml
inflated: test.html
Now at the root project level myEar, I have the following settings.gradle file:
include ":myWar1", ":myWar2"
and build.gradle looks like this:
defaultTasks 'assemble'
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
apply plugin: 'ear'
}
dependencies {
deploy project(path: ':myWar1', configuration: 'archives')
deploy project(path: ':myWar2', configuration: 'archives')
}
Now when I run this, it builds an myEar.ear file sure enough but both the war projects are being listed as myWar1/2.ear in the archive. In addition, if I expand out those ear files, it is missing things like the html files and the web.xml:
jar -xvf myEar.ear
created: META-INF/
inflated: META-INF/MANIFEST.MF
inflated: myWar1.ear
inflated: myWar2.ear
inflated: application.xml
inflated: META-INF/application.xml
jar -xvf myWar1.ear
created: META-INF/
inflated: META-INF/MANIFEST.MF
created: com/
created: com/foo/
inflated: com/foo/hello.class
inflated: META-INF/application.xml
It seems like there should be a simple solution to this but I can't for the life of me find it. Any help would be gratly appreciated.
Thanks,
Marcus.
ok I'm an idiot. It was because I am applying the 'ear' plugin to allprojects. If I replace:
allprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
apply plugin: 'ear'
}
with simply
apply plugin 'ear'
everything works as intended.

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