I’m basically just trying to do what’s described in Maven - How to build multiple Independent Maven projects from one project. The accepted answer for that question describes how to use a Maven POM with pom packaging and a list of modules.
I need to do the same thing, but with Gradle. What I actually have is two separate projects which I currently have to cd into and build individually, and what I want to have is one directory (project) that contains the two projects and from which I can build them both at once. They’re not interdependent—they just generally will need to be built at the same time. Can this be done?
It looks like Rene Groeschke has the answer at https://github.com/breskeby/gradle-snippets/tree/master/multiparallel.
In summary, this is the project structure:
- maindir
build.gradle
settings.gradle
- subproject1
build.gradle
- subproject2
build.gradle
The top-level (maindir) build.gradle:
subprojects {
apply plugin:'java'
repositories {
mavenCentral()
}
}
Top-level settings.gradle:
include ':subproject1',':subproject2'
The subproject1 and subproject2 directories have their own build.gradle files, which work to build them separately.
One way would be to use (as Luke Daley suggests) Prezi Pride: https://github.com/prezi/pride.
See https://discuss.gradle.org/t/how-can-i-build-independent-projects-from-one-parent-directory/10632/2.
Related
At my work we use Maven. I am going to try gradle for the first time. We use a common parent pom for all project which has setting for commonly used maven plugins and few comon dependencies. Is there a similar option available in gradle?
My second question is regarding release management. We use maven release plugin, which works pretty good for us. Is there something similar available in Gradle?
To share stuff within multiple projects of the same build, use allprojects { ... }, subprojects { ... }, etc. Also, extra properties (ext.foo = ...) declared in a parent project are visible in subprojects. A common idiom is to have something like ext.libs = [junit: "junit:junit:4.11", spring: "org.springframework:spring-core:3.1.0.RELEASE", ...] in the top-level build script. Subprojects can then selectively include dependencies by their short name. You should be able to find more information on this in the Gradle Forums.
To share logic across builds, you can either write a script plugin (foo.gradle), put it up on a web server, and include it in builds with apply from: "http://...", or write a binary plugin (a class implementing org.gradle.api.Plugin), publish it as a Jar to a repository, and include it in builds with apply plugin: ... and a buildscript {} section. For details, see the Gradle User Guide and the many samples in the full Gradle distribution.
A current limitation of script (but not binary) plugins is that they aren't cached. Therefore, a build will only succeed if it can connect to the web server that's serving the plugin.
As to your second question (which should have been a separate question), there are a couple of third-party release plugins available, for example https://github.com/townsfolk/gradle-release.
The io.spring.dependency-management plugin allows you to use a Maven bom to control your build's dependencies:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.3.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
Next, you can use it to import a Maven bom:
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.1.RELEASE'
}
}
Now, you can import dependencies without specifying a version number:
dependencies {
compile 'org.springframework:spring-core'
}
I think the best way to do things like maven parent pom is to to use gradle "apply from".
Something like this:
allprojects { // or: subprojects { ... }
apply from: "gradle/script/common.gradle"
}
The link and be a related path or an URL. Hope it helps.
Reference:
Import a Gradle script from the root into subprojects
Super POM, Parent POM type of hierarchy management in Gradle
I too wanted this type of feature, I have created a plugin to provide this here: https://github.com/boxheed/gradle-pater-build-plugin
You can convert the Parent pom content in to Gradle init file very easily.
Gradle init script provides same functionality as Maven super/parent pom. The basic difference is that you can call init script
Run time
As many as of them This gives us flexibility to change the init
script on run time but doubt of not tracking the changes.
You need to take repository, distribution management, profiling and other checks like findbugs, checkstyle etc in to init script.
The detail is huge, You can find complete information here by me.
http://www.scmtechblog.net/2015/12/how-to-migrate-parent-pom-from-maven-to.html
I have explained about gradle release plugin which is similar to maven release plugin.
to achive your goal you could apply the concept of 'multiproject build' explained in the gradel user guide here
Basically you can create an umbrella project which define a set of common configurations by creating a gradle.build file and a gradle.settings file.
The build file contains the properties, dependencies and plugins commons to all projects, the settings.gradle defines what subprojects inherits those configurations.
Moreover, to have an idea of the gradle plugin ecosystem you could check this source.
It is currently not possible, if you want the parent to be cached locally and stored in a Maven repository.
I have added feature request here:
http://forums.gradle.org/gradle/topics/support_for_gradle_parent_shared_between_projects_cached_locally
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.
Disclaimer: I'm very new to Gradle and Dependency Management. I tried reading the documentation but just couldn't get through the sheer amount of information. I also couldn't find anything useful to answer my question, so sorry if this has been answered before, I tried searching...
So my situation is as follows: I have one Java project that's supposed to give me a standardized way of using program configurations using JSON files. This project has a dependency on Gson. So far so good, I simply added compile 'com.google.code.gson:gson:2.6.2' to that projects dependencies and all's fine, the library shows up as External Library in Idea, and I can use it and stuff.
Now I want to use that project in other projects to make use of the configuration stuff. And I can not for the life of me figure out how to add the project or the library jar to other projects using Gradle.
I tried things like copying the library jar to the libs folder of the projects to use it in and adding compile files('./libs/myLibrary-0.0.1.jar') to the dependencies list, or adding the jar as a library via the Project Structure thing in Idea. None of these methods worked, and I'm at my wits end.
Any help would be appreciated.
If you or your company have a central binary repository, such as artifactory. Then you should set up publishing your jar there.
But since you haven't mentioned a central repository, I'll assume that you don't have one, and are simply trying to get your dependency to work on a single machine. In that case, what I suggest doing is this:
Add the maven-publish plugin to your dependency project:
apply plugin: 'maven-publish'
Also make sure that you define the group, version and name variables of your project (see here). You'll need them later. Then add a publishing definition that will tell maven-publish to publish all classes:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
Using these settings you should now be able to run the publishToMavenLocal task. Do it. If successful, the dependency jar should now be in your local maven repository (~/.m2/repository)
Now, add mavenLocal as a repository in the project that needs the dependency:
repositories {
mavenLocal()
}
(you might want to add additional repositories here, such as mavenCentral())
Also add your jar's group, name, and version just like your gson dependency:
compile 'yourgrou:yourname:yourversion.
Gradle should now be able to fetch the dependency from the local maven repo.
You have couple of options. First and easy is to build your base project and available in your local maven repository and use it. To make your project available is your local maven repo, use maven plugin. In your build.gradle file, add the following.
apply plugin: 'maven'
Now use gradle clean build install to publish the jar to your local repo. Remember that install task is the one actually put your jar into your local.Then head over to your other project which depends on this one and tell it to look into your local maven repo by adding mavenLocal to the repositories.
repositories {
mavenCentral()
mavenLocal()
}
Another option is, if you are using centralized repo in your company, you can publish your base jar and use it in the other project. Check out the documentation.
I have 5 subprojects in my modules directory, each having a build.gradle file:
modules :
aSubProject
bSubProject
cSubProject
dSubProject
eSubProject
and my settings.gradle includes all 5 projects, but project b is dependent on the build output jar of project e (say eSubProject.jar),
How can I avoid the alphanumeric execution order in Gradle?
What you want to do is to tell gradle how the projects are related to each other. In the dependencies of each project you can add a dependency to another subproject.
For example:
dependencies {
compile project(':eSubProject')
}
Gradle will make sure that the projects are compiled in the proper order.
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.