IntelliJ execute gradle test from root project - java

I've a gradle multiproject importend in my IntelliJ, and I want execute some test classes.
The structure is like:
root
|-module-a
|-module-b
module-a depends on module-b, so in the build.gradle
dependencies {
compile project('module-b');
}
When I use gradle from the shell everything it's ok, I have to go in the root project dir and write:
./gradlew :module-a:test
And everything it's been tested.
When I click "Run 'Tests' in 'module-a'" from IntelliJ I have this error:
A problem occurred evaluating root project 'module-a'.
> Project with path ':module-b' could not be found in root project ':module-a'.
So it seems, that IntelliJ is executing the gradle command from module-a and not from the root (this should be the correct behavior from what gradle wants).
How can execute this test inside IntelliJ? What I have to configure?

For a multi-project structure that looks like this
root
|-module-a
|-module-b
There is only one settings.gradle in the root folder, with the content:
include 'module-a', 'module-b'
The subproject folders do not contain a settings.gradle file. Then you refer to sibling projects as:
project(':module-b')
so your dependency would be declared as:
dependencies {
compile project(':module-b');
}
Please see here for more information about multi-project structure.

Related

Gradle multi-project setup in Eclipse

I will have the following setup:
MyRootProj
|
---- MyJavaProj1
|
---- MyJavaProj2
|
---- MyWebProj
I want to do the development on Eclipse and have installed BuildShip plugin.
From this discussion it seems that its not possible to create a multi-project setup in Eclipse for Gradle.
I tried the following steps:
I created a directory MyRootProj and inside that ran:
gradle init
This created the default files.
Then I modified the build.xml of MyRootProj to:
plugins {
id 'eclipse'
}
allprojects {
repositories {
mavenCentral()
}
apply plugin : 'eclipse-wtp'
apply plugin : 'java'
}
Till this point everything is fine.
Now following the steps in above link, I create MyJavaProj1 directory under MyRootProj and add a blank build.gradle inside it.
I then modify the settings.gradle file of MyRootProj to:
rootProject.name = 'MyRootProj'
include 'MyJavaProj1'
And then did a gradle refresh on the root project as recommended.
This creates the MyJavaProj1 with all the files. However, this does not have a Gradle recommended package structure for java projects already.
When I right click on eclipse project explorer and do a New -> Gradle Project, the project which gets created comes with src-main-java, src-main-test, etc. structure out of the box.
Why does that not happen with the way I am creating MyJavaProj1 above?
Long story short, I have created the root project. Now I want to create sub projects. However, I want to do it in Eclipse and I want the sub-projects to have autocreated Gradle recommended structure for Java Projects.

Understanding gradle dependencies

I have following structure:
ProjectA -> depends on ProjectB
ProjectB -> depends on ProjectC
compiling projectB everything works:
ProjectB/build.gradle:
dependencies {
compile project(':ProjectC')
}
ProjectB/settings.gradle:
include ':ProjectC'
project(':ProjectC').projectDir = new File(settingsDir, '../ProjectC')
However, compiling ProjectA it says it can not find ProjectC
ProjectA/build.gradle:
dependencies {
compile project(':ProjectB')
}
ProjectA/settings.gradle:
include ':ProjectB'
project(':ProjectB').projectDir = new File(settingsDir, '../ProjectB')
This will show following error:
Where:
Build file ProjectB\build.gradle
What went wrong:
A problem occurred evaluating project ':ProjectB'.
Project with path ':ProjectC' could not be found in project ':ProjectB'.
I Could only make it work including ProjectC in ProjectA. But this is not what I want.
I also tried to exclude on ProjectA but didnt work
ProjectA/build.gradle:
dependencies {
compile (project (':ProjectB')) {
exclude module: ':ProjectC'
}
}
But shows same error.
How can I fix this?
Multi-Project builds are not cascadable. You can have either one or no settings.gradle file in a multi-project build, but not multiple.
Besides that it is not working as expected, it can even get more confusing if you call Gradle from different directories. Gradle looks up (and to the side into directories called master) to find the nearest settings.gradle if none is specified. Then it evaluates the settings.gradle and checks whether the project in which your working directory is, is part of the multi-project build defined in that settings.gradle file. If so, it is executed in the context of the multi-project build, if not, it is executed as standalone build.
This means, if you call Gradle from inside ProjectA, you have a completely different build that probably als is configured differently, than if you call Gradle from inside ProjectB.
If you want to compose multiple multi-project builds into one build, you should instead use GradleBuild tasks or composite builds. In both cases the sub-build is completely independent and can itself be a multi-project build. Which one to use depends on the exact use-case.
With gradle you should be using only a single settings.gradle file. See Multiple settings gradle files for multiple projects building
Also just follow gradle multiproject documentation.

Gradle build fails

I have two Gradle projects, A and B. B is a simple Java application and is consumed by A as a compile project dependency. A is a web application.
Both A and B apply the java plugin, A applies the war plugin as well.
When building A, I get the following error:
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':war'.
> Configuration with name 'default' not found.
When separately building B I get no errors. When building from root, I get no errors either. The issue shows up only when building A.
I've also tried copying the B.jar to the lib folder of A and setting a dependency:
compile files("lib/B.jar")
The build in this case works fine.
What configurations do I need to include to avoid the error?
It's possible, when one subproject doesn't see another, if settings.gradle file is not on the parent directory for both subprojects and the subprojects in it are included via includeFlat. In this case you can call any task from your parent projects and all subprojects will know about each other, but it'll be unable to build separate subproject.
Any way, you need to show your project structure and build/settings files as well, to find out the problem.

How can I make sure that an included subproject runs before the main project in Gradle?

I have two Gradle projects with the following directory structure:
/baseDir
/first
/first/build.gradle
/second
/second/build.gradle
/second/settings.gradle
settings.gradle looks like this:
includeFlat "first"
When I do gradle build the second project is compiled after the first (main) project. I tried in the first project's build.gradle:
dependencies {
compile project(':first')
}
When doing gradle build I get an error that dependencies declared in the first project could not be found in the second one.
What I need is the following. When I do gradle buildon the second project I want that the first project will be build first and that first.jar is used as a dependency in the second project.
How can I do that?
Edit: When I set the following in my second project's settings.gradle:
includeFlat "first", "second"
then I get the following error while doing graddle clean:
FAILURE: Build failed with an exception.
* What went wrong:
Could not select the default project for this build. Multiple projects in this build have project directory '/Users/mg/Documents/Grails/GGTS3.6.3-SR1/second': [:, :second]
> Multiple projects in this build have project directory '/Users/mg/Documents/Grails/GGTS3.6.3-SR1/second': [:, :second]
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Edit: I create a sample project form demonstration: https://github.com/confile/Gradle-MultiProject-Test
you can let the build task depend on the build task of another project:
build{
dependsOn ':first:build'
}
Try this project settup:
root
settings.gradle
gradle.build
first
gradle.build
second
gradle.build
and put this in settings.gradle of your root:
include 'first'
include 'second'
You should move the block
dependencies {
compile project(':first')
}
to the second project's build.gradle.
This will build the first project and before the second project and second project could use first project's classes.

Gradle sub-project classes dependency

I've got several sub-projects in my gradle project:
Project
Common
Consumer1
Consumer2
.....
ConsumerN
My first - and main goal – is to include classes from Common project into resulting jar of every ConsumerN projects. So I can develop and test shared part (DB logic, some utils) independently in Common project and next other projects will get this classes (already tested) and include them into their jars.
Second goal is to make IntelliJ Idea to understand such dependency and work with it correctly.
Would you please suggest the "most conceptual and right way" to do this in gradle.
Assume You have the following project structure:
root
build.gradle
common
m1
m2
m3
settings.gradle
First of all You need to set a multimodule project - it's done in settings.gradle (this is a normal gradle script) and its content is as follows:
include 'm1', 'm2', 'm3', 'common'
Per project settings are done in dedicated build.gradle files, but the settings You asked can be done globally - in root build.gradle. Here's its content:
subprojects {
apply plugin: 'java'
}
subprojects.findAll { it.name != 'common' }.each {
configure(it) {
dependencies {
project(':common')
}
}
}
The question is what artifacts are produced from mN modules. If these are jar files You need to use fatjar or shadow plugin. If there are web applications war plugin is what You need.
Some further reading.
IntelliJ IDEA should handle these dependencies while importing the project using gradle wrapper.

Categories