Spring Boot Gradle Plugin "Blessed" Dependencies in a multi-project environment - gradle

In a multi-project Gradle environment, I have the usual buildscript block in my parent build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.7.RELEASE")
}
}
However, the dependencies which are supposed to be "blessed" (See 54.2 Declaring dependencies without versions) does not seem to be, since Gradle does not search for the correct version (because there is not version at all). I wonder if I am missing some additional configuration or it's just not possible at this moment to have "blessed" dependencies for a multi-project Gradle environment.

Applying spring-boot plugin to all projects (not just parent project) should help.
Try:
allprojects {
apply plugin: 'spring-boot'
}
EDIT: Andy and I posted the answers almost at the same time. But yes, either allprojects or subprojects should work fine, depending whether you parent project needs the plugin, or not.

You need to apply the Spring Boot plugin to every project that you want to use the Boot-provided dependency versions. As it's a multi-project build (and assuming you want to apply the plugin to every subproject), add the following to your build.gradle:
subprojects {
apply plugin: 'spring-boot'
}

Related

Artifact id resolved wrong

I am new to gradle and I am facing a weird problem while I’m trying to add a plugin in gradle. I know that we have to specify an if and version in plugin body for a gradle build, but I tried to add a plugin with some id and version. My question is..how does a gradle build know which artifact id to choose if there are multiple artifacts under same group id? I know that this might be a lame question...but I’m pretty new to gradle and I’d like to know your input.
Are you trying to apply the spring-boot-plugin?
If so, does the project you're trying to apply the plugin to have a buildscript block like this:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:2.0.4.RELEASE"
}
}
apply plugin: "org.springframework.boot"
or a plugin closure:
plugins {
id "org.springframework.boot" version "2.0.4.RELEASE"
}
With a buildscript block, Gradle knows where to find the plugin because I've specified a repository for it to go look for it. After resolving the dependency path it finds and downloads the plugin, then puts it on the classpath for use in build.gradle files. It then only needs to get applied, i.e. apply plugin: ....
With the plugins closure, things are a bit trickier. Plugins are published under a unique id, which is looked up and gradle resolves the specified version. I'm not too terribly knowledgeable about how this is done, but here, new plugin mechanism , describes some differences between buildscript {} apply plugin: ... and plugins {}.

Gradle : Something like Maven Parent POM

In our company, many of the different projects use similar technology stack and will have many common features.
So, we want to maintain the common features, dependencies etc. in one common file and refer it in the other projects.
In maven, it is something like creating a separate maven project with the common dependency information and refer that in the other projects as .
I want to do something similar to the maven parent project in gradle, which can be used by all different projects.
I googled for that, but could not find a concise information on how to do that.
We are not allowed to use external thirdparty plugins.
It would be great if someone could explain it how to do that.
in gradle you can do that, but for it you need to have external plugin, otherwise it is not possible at least for now. I have achieved it in this way:
buildscript {
repositories { jcenter() }
dependencies {
classpath 'com.netflix.nebula:nebula-dependency-recommender:4.3.0'
}
}
allprojects {
apply plugin: 'nebula.dependency-recommender'
apply plugin: 'groovy'
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
maven { url "http://repo1.maven.org/maven2/" }
maven { url "REPOSITORY_OF_YOUR_PARENT_POM.XML" }
}
dependencyRecommendations {
mavenBom module: 'YOUR_PARENT_POM_GROUP:YOUR_PARENT_POM_ID:YOUR_PARENT_POM_VERSION'
}
}
where:
REPOSITORY_OF_YOUR_PARENT_POM.XML - any system like nexus or something else accessible for maven
YOUR_PARENT_POM_GROUP - your parent pom project group (e.g. com.foo.bar.parent)
YOUR_PARENT_POM_ID - your parent pom id (e.g. projects-parent)
YOUR_PARENT_POM_VERSION - your parent pom project version (e.g. 1.0.1)
so, if the external dependency to netflix.nebula is fine , than you can go in this way
Gradle has many extension mechanisms for leveraging build logic located outside of the main script.
A simple thing that can be done is to use an external build script, which can be sourced from the local file system or through an URL, see the documentation on this topic.
If that solution gets too problematic, then you can move to packaging a real plugin that others can apply and potentially configure.
This will allow you to configure much more than dependencies for example.

Invalid classpath publish/ export dependency /ouat-contract. Project entries not supported

I am trying create an Gradle multi project similar to this structure
ouat-services
- ouat-contract
- ouat-servicesImpl (web project)
I followed the eclipse example and define my ouat-services settings.gradle as
include "ouat-contract", "ouat-servicesImpl"
In my ouat-servicesImpl build-gradle I define
dependencies {
compile project(':ouat-contract')
}
My problem starts when I try apply war plug-in in ouat-servicesImpl, I receive the following message in eclipse problem view:
Invalid classpath publish/ export dependency /ouat-contract. Project entries not supported
My ouat-services build.gradle
configure(subprojects) {
apply plugin: 'com.github.ben-manes.versions'
apply plugin: 'eclipse'
apply plugin: 'java'
version = '1.0'
sourceCompatibility = 1.8
targetCompatibility = 1.8
def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding
repositories {
jcenter()
mavenLocal()
mavenCentral()
}
jar {
manifest.attributes provider: 'Company'
}
}
configure(project(':ouat-servicesImpl')) {
apply plugin: 'checkstyle'
apply plugin: 'eclipse-wtp'
apply plugin: 'findbugs'
apply plugin: 'jacoco'
//apply plugin: 'jetty'
apply plugin: 'pmd'
apply plugin: 'war'
}
buildscript {
repositories {
jcenter()
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.10.1'
}
}
My ouat-servicesImpl build gradle was changed to:
dependencies {
compile project(':ouat-contract')
cxfArtifacts.each { artifact ->
compile "org.apache.cxf:$artifact:$cxfVersion"
}
springArtifacts.each { artifact ->
compile "org.springframework:$artifact:$springVersion"
}
testCompile "org.testng:testng:$testNGVersion"
testCompile "org.hamcrest:hamcrest-all:$hamcrestVersion"
testCompile "org.springframework:spring-test:$springVersion"
//WAR PLUGIN
providedCompile "javax.servlet:javax.servlet-api:$servletAPIVersion"
runtime "javax.servlet:jstl:$jstlVersion"
}
Is this an eclipse plug-in problem or I am doing something wrong?
Here's the magic steps I've discovered to make it work without messing with Project settings manually.
Run command: gradle cleanEclipse eclipse
as a result of this command Eclipse forgets that the project was supposed to have a gradle nature.
Add gradle nature back to the project by doing Configure -> Convert to Gradle Project.
as a result of this command the error reappears.
if incompatible plugin java version error appears then just delete .settings directory and refresh.
Run command: gradle cleanEclipseClasspath eclipseClasspath
this final step should get it fixed until the next time.
In my case, this was due to mixing "faceted" and non-faceted projects. The projects with the error had been converted to faceted form, and the project they referenced which it was complaining about had not been. You can configure the project to be faceted via use of the eclipse-wtp plugin, by adding this to your ouat-contract gradle file:
eclipse{
wtp{
facet{}
}
}
This will add facets for Java and a utility module when using the java and war plugins (see the EclipseWTPFacet documentation for more information on the defaults and manually adding facets if you aren't using the war plug-in). The utility module part is the key to avoid the error.
Note that within this block you can also access the facet file directly to perform manual XML manipulation if you need to do other things, like specify a particular Apache Tomcat Runtime or or similar
Once you make this change, you can use Eclipse to do Gradle -> Refresh All on ouat-contract within your workspace - once I did this, the error went away
I've also run into this problem long time ago. It really seems to be the problem related to the Eclipse plugin included in "Gradle IDE Pack" (as it works from the command line without problems).
My setup is probably way more complex than Yours (I'm including modules from one top-level gradle project into another top-level gradle project), but to overcome this specific error
Invalid classpath publish/ export dependency /my-project. Project entries not supported
... i excluded project dependency if some specific gradle property was missing:
if(project.hasProperty("myProjectRefAddedFromIDE")) {
println "NB! Build script started with property 'myProjectRefAddedFromIDE' - expecting that this project in IDE is configured to add the direct reference to my-project"
} else {
compile project(':my-project')
}
And to add the property "myProjectRefAddedFromIDE" only from IDE, i have configured eclipse plugin as follows:
Window -> Preferences -> Gradle -> Arguments -> Program arguments -> Use: ´-PmyProjectRefAddedFromIDE´
Just a warning: this will probably work for you, but there might be some other problem with Your setup, as for simple multi-module project (that doesn't include modules form another multi-module project) I don't have to use this workaround.
This works for me to remove the duplicate jar files from JRE System Library.
Steps Right click on Project and go to Build Path->configure build path->Libraries.
Remove the jars that are not in the classpath or duplicated in Maven dependency.

How to apply plugin to allprojects with new Gradle plugins mechanism?

Before Gradle 2.1 I could apply plugin to all projects by using allProjects closure (by prevoisly resolving the jar, of course):
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
}
allprojects {
apply plugin: "com.jfrog.artifactory"
}
With new publishing mechanism it looks like the plugins closure can't be used inside allprojects:
allprojects {
plugins {
id "com.jfrog.artifactory" version "3.0.1"
}
}
fails with:
"Could not find method plugins() for arguments [build_xxxx_run_closure1_closure4#yyyyy] on root project"
What are the rules of using plugins closure? Is the plugin applied to current project only? If so, how can I apply it to all projects without repeating the plugins closure inside each build?
The new plugins {...} syntax cannot be used within a allprojects {...} or subprojects {...} closure. Additionally, it can only be used within build scripts (no script plugins, init scripts, etc). If you want to avoid having to apply the plugin to each project individually I'd suggest using the old notation. This is an issue the Gradle team is aware of and a solution will be introduced in future versions.
Update: Starting with Gradle 3.0 you can do this in a slightly modified way. You still have to explicitly use apply() but you no longer have to deal with all the buildscript { } nonsense to get the plugin on your classpath. This also allows you to conditionally apply plugins. Check out the Gradle 3.0 release notes for more information.
plugins {
id 'my.special.plugin' version '1.0' apply false
}
allprojects {
apply plugin: 'java'
apply plugin: 'my.special.plugin'
}

How to add buildscript dependencies in custom plugin to project dependency?

I wrote a custom gradle plugin which comes with an additional compile step. For the compilation some classes of the plugin itself are needed, since it is an annotation processor.
I try to solve it by adding the plugin as a compile dependency this way:
// in the custom plugin
project.dependencies {
compile "com.thilko.spring:gradle-springdoc-plugin:0.1.SNAPSHOT"
compile localGroovy()
}
This solution is working but introduces duplication since I have to declare the same plugin version that is already declared in the build script section of the project that uses the plugin:
// build.gradle of the project that uses the plugin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "com.thilko.spring:gradle-springdoc-plugin:0.1"
}
}
apply plugin: 'springdoc'
Is there a way to reuse the dependencies defined in the buildscript section?
If you think it's worth it, you can declare an extra property inside the buildscript block (e.g. ext.springdocPlugin = "com.thilko.spring:gradle-springdoc-plugin:0.1.SNAPSHOT"), and then reuse it from outside (e.g. dependencies { compile buildscript.springdocPlugin }).
If you add the dependency to the pom of the your plugin, it will be added to the buildscript dependencies of the project you apply your plugin to.

Resources