Resolve dependencies for multiple configurations - gradle

Code speaks better than words, say I have the following build.gradle:
apply plugin: 'java'
apply plugin: 'eclipse'
configurations {
optionalDependency
}
dependencies {
compile 'group:artifact:1.0'
optionalDependency 'group:artifact:1.2'
}
eclipse.classpath.plusConfigurations += [configurations.optionalDependency]
Eclipse will now get both the 1.0 version and the 1.2 version of the artifact. Is there a way to tell gradle that I do not want both configurations, but rather resolve as though they were one?

Just have one extend the other. If you want the compile configuration to include dependencies in the optionalDependecy configuration then simply do the following.
configurations {
optionalDependency
compile.extendsFrom optionalDependency
}

Related

Can I specify in gradle that I only want to use a certain plugin for tests?

I have a project and for testing purposes only I want to standup a quick websocket server. Spring Boot seems like the simplest way to do that, but I don't want to include the plugin in my implementation, only for tests. I can't seem to find documentation on something like this, but in general I've found the answer to the question "can gradle do this" is usually yes.
So how would I go about specifying to only use the 'org.springframework.boot' plugin for test builds?
I've tried placing the plugins {} block inside a test {} block but that doesn't work.
I'm pretty sure you may just apply the org.springframework.boot plugin in the regular way and it won't effect your build artifacts.
However, it is possible to apply plugins dynamically, if you are afraid that they might have undesired side-effects on build artifacts. The old plugin mechanism actually worked this way by default and separated the resolution of plugins from their application to the Project instance:
// This part resolves the plugin
buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.3.2.RELEASE'
}
}
// This part applies the plugin
apply plugin: 'org.springframework.boot'
This way it was possible to apply a plugin based on a condition:
if (testMode) {
apply plugin: 'org.springframework.boot'
}
Using the new plugins block to apply plugins, this is not possible directly, as the plugins block is a special block that does not allow custom code:
// This is not allowed!
plugins {
if (testMode) {
id 'org.springframework.boot' version '2.3.2.RELEASE'
}
}
The solution is to tell the plugins block to resolve a plugin without applying it automatically. This can then be done dynamically using apply plugin::
plugins {
id 'org.springframework.boot' version '2.3.2.RELEASE' apply false
}
if (testMode) {
apply plugin: 'org.springframework.boot'
}
You don't have to use org.springframework.boot plugin: just use io.spring.dependency-management plugin. This way, you will be able to declare spring-* related dependencies in your testImplementation configuration, without any impact on the implementation configuration.
plugins {
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-websocket'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.boot:spring-boot-dependencies:2.2.0.RELEASE"
}
}
Then in your test sources, you will be able to declare SpringBoot application and other websocket-related stuff (controllers)
EDIT what org.springframework.boot is actually doing, is to change the packaging of the main jar artifact by declaring the bootJar task, see Springboot plugin reference. In your case you don't need this, as far as I understand, if you just want to run some Spring application in test sourceset.

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'
}

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

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'
}

How to configure a plugin to depend on a specific version of gradle?

I am writing a set of Gradle plugins, but I want to control the specific versions of groovy and gradle that are used.
I don't want the plugins to depend on whatever versions of Gradle/Groovy are installed, like the following would do:
dependencies {
compile localGroovy()
compile gradleApi()
}
Another reason I don't want to use the local method - when you use a proper dependency specification, Gradle then knows about the source code for those libs and the IDE plugins can hookup the source automatically.
Below are the relevant sections of my build script:
allprojects { Project iProject ->
apply plugin: 'idea'
apply plugin: 'maven'
repositories {
jcenter()
}
}
subprojects { Project iProject ->
apply plugin: 'groovy'
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.2'
}
}
project(':eclipsei2g') {
group = 'eclipsei2g'
version = '0.0.1-SNAPSHOT'
dependencies {
compile 'org.gradle:gradle-core:2.0'
}
}
project(':g2idea13') {
group = 'g2idea13'
version = '0.0.1-SNAPSHOT'
dependencies {
compile 'org.gradle:gradle-core:2.0'
compile 'org.gradle-plugins:gradle-ide:2.0'
}
}
When I run this I get an error resolving the gradle-ide dependency:
Could not resolve all dependencies for configuration ':g2idea13:compile'.
> Could not find org.gradle:gradle-ide:2.0.
Searched in the following locations:
http://jcenter.bintray.com/org/gradle/gradle-ide/2.0/gradle-ide-2.0.pom
http://jcenter.bintray.com/org/gradle/gradle-ide/2.0/gradle-ide-2.0.jar
Required by:
g2idea13:g2idea13:0.0.1-SNAPSHOT
There doesn't seem to be anything on the jcenter repository since 0.9 for the plugins stuff.
I also tried 'org.gradle:gradle-ide:2.0'.
Is this even how I should be doing this? Is there another way to specify a specific gradle version? Am I just using the wrong repository? I couldn't even get gradle-core to resolve on mavenCentral(). Is there an official Gradle repository somewhere that I should be using?
gradleApi() is the way to go. There isn't currently a public list of dependencies for Gradle plugins.

Resources