Gradle precompiled script plugin: External Quarkus plugin dependency not found - gradle

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

Related

Cannot add subproject to gradle buildscript classpath in 7.3

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

build.gradle buildscript dependencies vs. dependencies?

Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ? and why they have to be listed with the syntax "implementation"? I've googled this and responses say the dependencies in the buildscript and used to "build the project" but I don't understand this? can anyone give a more clear picture and answer?
buildscript:
buildscript
{
repositories
{
maven {
url 'myMavenFeed'
credentials {
username "myUsername"
password myPassword
}
}
mavenCentral()
jcenter()
}
dependencies
{
classpath "com.microsoft.azure.sdk.iot:iot-device-client:1.14.1"
}
}
Dependencies block:
dependencies
{
compile group: 'com.microsoft.azure.sdk.iot', name: 'iot-device-client', version: '1.16.0'
}
Can someone explain to me how depedencies listed in the "buildscript" in the build.gradle file are different than regular dependencies listed in the dependencies block { } ?
Dependencies defined in the buildscript { } block are dependencies to use to build your project. These dependencies are available to use in your Gradle build file (build.gradle or build.gradle.kts)
Dependencies defined in the dependencies { } are for your application code.
So for your samples in your questions, does it make sense for Gradle (the build system) to have iot-device-client on its classpath? Why does a build system need iot-device-client on its classpath to build your project? It doesn't make sense therefore it should be removed.
Now let's say you are developing an application the requires some functionality or class from iot-device-client. You need a way to add this library to your application's code/classpath. You when then declare it as a dependency as you have done above:
dependencies {
implementation("com.microsoft.azure.sdk.iot:iot-device-client:1.16.0")
}
References:
External dependencies for the build script
Declaring depenedncies
and why they have to be listed with the syntax "implementation"?
implementation is known as a configuration: A Configuration represents a group of artifacts and their dependencies
There are many more configurations depending on the plugins you apply to your project. For example, if you apply the Java plugin:
plugins {
id("java")
}
The following configurations are available to use:
implementation
compileOnly
compileClasspath
...and many more
Each one has their own meaning/usage and I strongly suggest reading about them here.

Gradle Kotlin DSL multi project build with Java Modules

I'm creating a new project (using IntelliJ IDEA) that will be using:
Gradle as the build system
Kotlin DSL for build scripts
Java 9 modules for "organisation"
Kotlin as the primary language
I'm having problems setting up Gradle to properly build my project. Most examples I've found are for Groovy and not Kotlin DSL, and most only cover some of the features I want, but not all.
Right now I have two modules, core and lib, where the core module requires the lib module. My gradle build scripts are:
build.gradle.kts
plugins {
base
kotlin("jvm") version "1.3.41" apply false
}
subprojects {
afterEvaluate {
tasks.withType<JavaCompile> {
inputs.property("moduleName", extra["moduleName"])
options.compilerArgs.addAll(arrayOf("--module-path", classpath.asPath))
classpath = files()
}
}
repositories {
mavenCentral()
jcenter()
}
}
core/build.gradle.kts
extra.set("moduleName", "myproject.core")
plugins {
kotlin("jvm")
}
dependencies {
compile(kotlin("stdlib"))
compile(project(":networking"))
}
lib/build.gradle.kts
extra.set("moduleName", "myproject.lib")
plugins {
kotlin("jvm")
}
dependencies {
compile(kotlin("stdlib"))
}
Doing this, configuration fails with:
A problem occurred configuring project ':core'.
Cannot get property 'moduleName' on extra properties extension as it does not exist
If I remove the inputs.property() line the configuration succeeds, but the core compilation fails (lib compiles successfully) with :
Task :core:compileKotlin
e: Module myproject.lib cannot be found in the module graph
I assume the issue is is my root build.gradle.kts, but I cannot figure out how to make it work. Googling around, Kotlin DSL for Gradle is somewhat new and not as widely used, and documentation is pretty scarce.
Any advice would be appreciated!
Naturally after posting the question I found the solution. There exists a Gradle plugin that does exactly what's needed in this situation, with a KotlinDSL example: https://github.com/java9-modularity/gradle-modules-plugin/tree/master/test-project-kotlin
Using the plugin, all I needed to do is change the root build.gradle.kts file:
plugins {
base
kotlin("jvm") version "1.3.41" apply false
id("org.javamodularity.moduleplugin") version "1.5.0" apply false
}
subprojects {
apply(plugin = "org.javamodularity.moduleplugin")
repositories {
mavenCentral()
jcenter()
}
}
Note: Make sure that your module-info.java file is in the java src folder, and not in the kotlin src folder, otherwise the plugin will not detect the module.

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

Is it possible to restrict a gradle repository to a particular configuration?

I want to tie gradle repositories to specific configurations in my build.gradle file, e.g.:
repositories {
testCompile {
mavenCentral()
}
compile {
maven { url 'https://vetted-repo.example.com' }
}
}
I can't find a simple way to do this from the gradle documentation. Do I need to write my own plugin?
As of Gradle 5.1 this is now possible, from the release notes:
It is now possible to match repositories to dependencies, so that
Gradle doesn't search for a dependency in a repository if it's never
going to be found there.
Example:
repositories {
maven {
url "https://repo.mycompany.com"
content {
includeGroupByRegex "com\\.mycompany.*"
}
}
}
For the specific requirement of restricting a repository to a specific configuration such as compile, you could use the onlyForConfigurations property:
repositories {
maven {
url "https://vetted-repo.example.com"
content {
onlyForConfigurations "compile"
}
}
}
This is not supported by gradle at the moment. When resolving dependencies, gradle tries al listed repositories (from top to bottom) to resolve a dependency. Once the dependency is found it stops looking for it in other repositories
It is now possible to declare a repository filter in gradle. see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html#declaring_a_repository_filter this does exactly what you need here.

Resources