Cannot add subproject to gradle buildscript classpath in 7.3 - gradle

I have a subprojectA and subprojectB. There are some artifacts from subprojectA that i need to build subprojectB. It seems that after upgrading to 7.3, i can no longer configure it like this.
Getting the error 'Cannot transition to state Configure as already transitioning to this state.'
May I know if there is an alternative or a solution to the error?
subprojectb build.gradle:
buildscript {
dependencies {
classpath project(':subprojectA')
}
}
plugins {
...
}
...

The solution is to make subprojectA an included build instead of a subproject, then use the GAV coordinates instead of the project dir.
//build.gradle
buildscript {
dependencies {
classpath 'com.example:subprojectA:1.0'
}
}
plugins {
...
}
...
// settings.gradle
includeBuild('./subprojectA')
https://docs.gradle.org/current/userguide/structuring_software_products.html#connecting_components

Related

Gradle precompiled script plugin: External Quarkus plugin dependency not found

Background
I am currently developing a gradle multi-project with multiple quarkus microservices. In order to bundle my quarkus dependencies I use a precompile script plugin with kotlin-dsl. Given the configuration below, executing quarkusBuild works fine.
Problem
Executing the quarkusDev task for a microservice subproject fails with
Unable to find quarkus-gradle-plugin dependency in project ':microservice'
Do you have any idea why this happens? I have put hours into this and I still do not see why it fails. https://github.com/quarkusio/quarkus/issues/12509 seems to be related, but the suggested solution did not work for me. Any help is greatly appreciated!
Edit
I realize there might be a difference between gradle.plugin.io.quarkus:quarkus-gradle-plugin:2.2.3.Final and io.quarkus:gradle-application-plugin:2.2.3.Final, but swapping the dependencies doesnt help much.
Configuration
This is a minimal version of my project which allows to reproduce the error.
This minimal example can also be checked out here: https://github.com/lorenzjosten/gradle-plugin-quarkus
rootProject
- buildSrc
- src/main/kotlin
quarkus-conventions.gradle.kts
build.gradle.kts
settings.gradle.kts
gradle.properties
- microservice
- src/...
build.gradle.kts
build.gradle.kts
settings.gradle.kts
gradle.properties
rootProject/buildSrc/src/main/kotlin/quarkus-conventions.gradle.kts
plugins {
java
id("io.quarkus")
}
val quarkusUniverseBomVersion: String by project
dependencies {
implementation(enforcedPlatform("io.quarkus:quarkus-universe-bom:$quarkusUniverseBomVersion"))
implementation("io.quarkus:quarkus-kotlin")
implementation("io.quarkus:quarkus-resteasy-reactive")
implementation("io.quarkus:quarkus-resteasy-reactive-jackson")
implementation("io.quarkus:quarkus-hibernate-reactive-panache")
implementation("io.quarkus:quarkus-reactive-pg-client")
implementation("io.quarkus:quarkus-smallrye-reactive-messaging-amqp")
implementation("io.quarkus:quarkus-arc")
testImplementation("io.quarkus:quarkus-junit5")
}
rootProject/buildSrc/build.gradle.kts
val quarkusPluginVersion: String by project
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
maven("https://plugins.gradle.org/m2/")
gradlePluginPortal()
}
dependencies {
implementation("io.quarkus:gradle-application-plugin:${quarkusPluginVersion}")
}
rootProject/buildSrc/gradle.properties
quarkusPluginVersion=2.3.0.Final
rootProject/microservice/build.gradle.kts
plugins {
id("quarkus-conventions")
}
rootProject/settings.gradle.kts
include("microservice")
rootProject/build.gradle.kts
plugins {
idea
}
repositories {
mavenCentral()
maven("https://plugins.gradle.org/m2/")
gradlePluginPortal()
}
allprojects {
apply(plugin = "idea")
idea {
module {
isDownloadSources = true
isDownloadJavadoc = true
}
}
}
rootProject/gradle.properties
quarkusUniverseBomVersion=2.2.3.Final
The Gradle plugin likely cannot find the Java dependency:
// https://mvnrepository.com/artifact/io.quarkus/quarkus-universe-bom
implementation("io.quarkus:quarkus-universe-bom:2.2.3.Final")
It was a bug that should be fixed with quarkus release version 2.4.CR1
See Github issues
https://github.com/quarkusio/quarkus/issues/20595
https://github.com/quarkusio/quarkus/issues/20531

Gradle: Configure Repository for transitive dependencies

imagine you have to go through proxy repositories for all dependency resolutions, because you are behind a proxy.
For most repositories, this can be easily configured within the build.gradle file:
buildscript {
repositories { ... }
}
and
repositories { ... }
and even in settings.gradle the
pluginManagement {
repositories { ... }
}
but it seems that transitive dependencies are still downloaded through jCenter.
Where can I configure the repositories for transitive dependencies?
Update: I still try to find the real root cause of my problem. It could be that it has to do with the way I've build my build script - the dependencies are defined in a script plugin of a sub project.
I still don't know why my system behaves this way, but here is a solution which works for me:
create a file called init.gradle in USER_HOME/.gradle/ and add your repositiories like this:
allprojects {
buildscript {
repositories { ... }
}
repositories { ... }
}

Gradle share properties in multi-project

I'm quite new to Gradle, trying to make multi-project. In root project declares all common libs (also their versions as properties) and apply plugins.
For example, root and child common projects.
In root's settings.gradle type:
rootProject.name = 'root'
include 'common'
In root's build.gradle type:
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
subprojects {
buildscript {
repositories {
mavenCentral()
}
}
apply plugin: 'kotlin'
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
}
And now I'd like to use another library only in specific child project. Do this in common's build.gradle:
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
}
It's work fine when running gradle commands from root's folder, but failed with message Could not get unknown property 'kotlin_version' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler when running from common's folder.
What I'm doing wrong? Or is there any way around? And what are best practices for sharing libs and properties in multi-project?
For me, it looks like common know nothing about it's "parent" project, all relations defined in root's settings.
The reason why Gradle cannot resolve the property is because the project in folder common is named commons. This is caused by a spelling mistake in common's settings.gradle. This is fortunately easy to fix (common/settings.gradle) :
rootProject.name = 'common'
Alternatively, just delete the common/settings.gradle, it's fully optional in this case.
Consider reading the official Gradle documentation for authoring multi-project builds and the guide create multi-project builds for more information and best practices around multi-project builds.

Gradle buildSrc and buildscript

We have a Gradle build that includes a buildSrc with some custom plugins. Those plugins apply yet other plugins. For example, our plugin applies com.android.tools.build:gradle. For annotation processing that library needs to be on Gradle's classpath during compilation. So, putting this in our main build.gradle works:
buildscript {
repositories {
google()
}
dependencies {
classpath "com.android.tools.build:gradle:$gToolsVersion"
}
}
However, that means that for a user to apply this plugin they must (1) apply our plugin and (2) add that buildscript boilerplate. It seems like that shouldn't be necessary. We can also add a project.buildscript block inside our plugin but that too seems unnecessary and, due to this bug is problematic: https://developer.android.com/studio/build/gradle-plugin-3-0-0.html?utm_source=android-studio#known_issues.
I added the com.android.tools.build:gradle dependency to buildSrc/build.gradle as a runtime dependency. It seems like that should work: I thought that tells Gradle that in order to run my plugin that library (and its dependencies) need to be on the classpath. However, gradle buildEnvironment (and the fact that our build fails) makes it clear that's not the case.
So, questions:
What's the difference between a runtime dependency specified in buildSrc/build.gradle and a classpath dependency specified in a buildscript block in a regular build.gradle?
How can I arrange things so that users can apply the plugin from buildSrc and not have to also add the buildscript block to their build.gradle?
I got a slightly different problem and found an acceptable solution that might help with for your second question: I wanted to apply the same repositories in the buildSrc/build.gradle and twice in the root build.gradle.
repositories.gradle in the project root:
repositories {
if (project.hasProperty('nexus')) {
maven {
url 'http://localhost:8081/repository/JCenter/'
}
maven {
url 'http://localhost:8081/repository/Maven_Google/'
}
} else {
jcenter()
google()
}
}
ext {
androidGradleBuildToolsDependency = 'com.android.tools.build:gradle:3.1.3'
}
buildSrc/build.gradle:
buildscript {
apply from: '../repositories.gradle'
}
allprojects {
apply from: '../repositories.gradle'
}
dependencies {
// androidGradleBuildToolsDependency is defined in repositories.gradle
implementation androidGradleBuildToolsDependency
}
Root build.gradle:
buildscript {
apply from: 'repositories.gradle'
}
allprojects {
// this line will also be executed from the build.gradles in subprojects, so the working
// directory isn't always the same, so we use the absolute path here
apply from: "${rootProject.projectDir}/repositories.gradle"
}
Note that you do not need the classpath dependency inside the buildscript block of the root build.gradle as you normally would. The implementation dependency in the repositories.gradle seems to auto apply it.
My solution probably doesn't work when the build.gradles are supplied via a dependency.
Stumbled upon this while digging into a tangential problem.
I've been successfully using buildSrc/build.gradle as the place to define dependencies that would normally belong in the root-project's buildscript classpath for a few of my projects.
You can see a working example here: https://github.com/episode6/chop/blob/develop/buildSrc/build.gradle
I used to use compile dependencie but just switched to runtimeClasspath which feels more appropriate and also works. I don't think your classpath dependencies were working because they would be on the classpath of the buildSrc project, but not compiled into or run along side it.
If you decide to go this route, you may run into the problem I was just digging into which only came up because of this approach.
When I tried this approach with the dokka plugin, I got the following error
Could not resolve all files for configuration ':detachedConfiguration1'.
> Cannot resolve external dependency org.jetbrains.dokka:dokka-fatjar:0.9.17 because no repositories are defined
I was able to workaround this by adding jcenter() to the root project's buildscript repositories: https://github.com/episode6/chop/blob/develop/build.gradle#L2

Gradle 2.12 - Injecting plugins into sub-projects fails

I have a standard Gradle setup with a root and sub-projects. In my root build.gradle, I would like to configure a plugin and inject it into some of the sub-projects, e.g:
project(':web-app'){
apply plugin: 'gwt'
buildscript {
repositories {
jcenter()
maven { url 'http://dl.bintray.com/steffenschaefer/maven'}
}
dependencies {
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'
}
}
gwt {
//Shared stuff goes in here ...
}
}
Unfortunately, I am getting:
A problem occurred evaluating root project 'XXXX'. Plugin with id
'gwt' not found.
What am I doing wrong? If I do the same in the sub-project(s) build.gradle, it works.
Bonus questions, if the above works at all:
How do I inject in several sub-projetcs? Seems like project(':a',':b'){...} does not work.
If the sub-project also has gwt{...} block, will it be merged with the stuff injected from the root? If so what takes precedence?
Thanks

Resources