diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java
index d2a945aa69ef1..861f1ba4c889f 100644
--- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java
+++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java
@@ -108,10 +108,16 @@ public static Project findIncludedProject(Project project, ExternalModuleDepende
}
}
- final Gradle parentGradle = project.getRootProject().getGradle().getParent();
- if (parentGradle != null) {
- return findIncludedProject(parentGradle.getRootProject(), dependency);
- } else {
+ try {
+ final Gradle parentGradle = project.getRootProject().getGradle().getParent();
+ if (parentGradle != null) {
+ return findIncludedProject(parentGradle.getRootProject(), dependency);
+ } else {
+ return null;
+ }
+ } catch (IllegalStateException ise) {
+ // This can happen if the project itself is in an included build, which means that the root-project
+ // is not yet known, so `DefaultGradle.getRootProject()` throws an ISE.
return null;
}
}
@@ -134,9 +140,15 @@ private static Project findIncludedBuildProject(IncludedBuild ib, ExternalModule
}
final DefaultIncludedBuild.IncludedBuildImpl dib = (DefaultIncludedBuild.IncludedBuildImpl) ib;
- final Project rootProject = dib.getTarget().getMutableModel().getRootProject();
+ try {
+ final Project rootProject = dib.getTarget().getMutableModel().getRootProject();
- return findLocalProject(rootProject, dependency);
+ return findLocalProject(rootProject, dependency);
+ } catch (IllegalStateException ise) {
+ // This can happen if the project itself is in an included build, which means that the root-project
+ // is not yet known, so `DefaultGradle.getRootProject()` throws an ISE.
+ return null;
+ }
}
public static Path serializeAppModel(ApplicationModel appModel, Task context, boolean test) throws IOException {
diff --git a/integration-tests/gradle/src/main/resources/included-build/README.txt b/integration-tests/gradle/src/main/resources/included-build/README.txt
new file mode 100644
index 0000000000000..0da9a18327639
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/README.txt
@@ -0,0 +1,2 @@
+Reproducer for https://github.com/quarkusio/quarkus/pull/38607: IllegalStateException when resolving project deps
+Test class: io.quarkus.gradle.IncludedQuarkusBuildTest
diff --git a/integration-tests/gradle/src/main/resources/included-build/build.gradle b/integration-tests/gradle/src/main/resources/included-build/build.gradle
new file mode 100644
index 0000000000000..8f02b1f3c280a
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/build.gradle
@@ -0,0 +1,45 @@
+buildscript {
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+apply plugin: 'java'
+
+group = 'com.quarkus.demo'
+version = '1.0'
+
+
+subprojects {
+
+ apply plugin: 'java'
+ group = 'com.quarkus.demo'
+
+ test {
+ dependsOn 'cleanTest'
+ useJUnitPlatform()
+ forkEvery 1
+ systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
+ }
+
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
+ }
+}
diff --git a/integration-tests/gradle/src/main/resources/included-build/depend-on-included-build/build.gradle b/integration-tests/gradle/src/main/resources/included-build/depend-on-included-build/build.gradle
new file mode 100644
index 0000000000000..56bce7831ed16
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/depend-on-included-build/build.gradle
@@ -0,0 +1,7 @@
+plugins {
+ id 'java-library'
+}
+
+dependencies {
+ implementation("com.quarkus.includedbuild:included-quarkus:1.0")
+}
\ No newline at end of file
diff --git a/integration-tests/gradle/src/main/resources/included-build/gradle.properties b/integration-tests/gradle/src/main/resources/included-build/gradle.properties
new file mode 100644
index 0000000000000..8f063b7d88ba4
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/gradle.properties
@@ -0,0 +1,2 @@
+quarkusPlatformArtifactId=quarkus-bom
+quarkusPlatformGroupId=io.quarkus
\ No newline at end of file
diff --git a/integration-tests/gradle/src/main/resources/included-build/included/build.gradle b/integration-tests/gradle/src/main/resources/included-build/included/build.gradle
new file mode 100644
index 0000000000000..be108ef7bd8e0
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/included/build.gradle
@@ -0,0 +1,45 @@
+buildscript {
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+apply plugin: 'java'
+
+group = 'com.quarkus.directinclude'
+version = '1.0'
+
+
+subprojects {
+
+ apply plugin: 'java'
+ group = 'com.quarkus.directinclude'
+
+ test {
+ dependsOn 'cleanTest'
+ useJUnitPlatform()
+ forkEvery 1
+ systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
+ }
+
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
+ }
+}
diff --git a/integration-tests/gradle/src/main/resources/included-build/included/nested/build.gradle b/integration-tests/gradle/src/main/resources/included-build/included/nested/build.gradle
new file mode 100644
index 0000000000000..f9d92822f25f1
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/included/nested/build.gradle
@@ -0,0 +1,45 @@
+buildscript {
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+apply plugin: 'java'
+
+group = 'com.quarkus.includedbuild'
+version = '1.0'
+
+
+subprojects {
+
+ apply plugin: 'java'
+ group = 'com.quarkus.includedbuild'
+
+ test {
+ dependsOn 'cleanTest'
+ useJUnitPlatform()
+ forkEvery 1
+ systemProperty "java.util.logging.manager", "org.jboss.logmanager.LogManager"
+ }
+
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ }
+
+ dependencies {
+ implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
+ }
+}
diff --git a/integration-tests/gradle/src/main/resources/included-build/included/nested/included-quarkus/build.gradle b/integration-tests/gradle/src/main/resources/included-build/included/nested/included-quarkus/build.gradle
new file mode 100644
index 0000000000000..0bd1d61cab161
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/included/nested/included-quarkus/build.gradle
@@ -0,0 +1,7 @@
+plugins {
+ id 'java-library'
+ id 'io.quarkus'
+}
+
+dependencies {
+}
diff --git a/integration-tests/gradle/src/main/resources/included-build/included/nested/settings.gradle b/integration-tests/gradle/src/main/resources/included-build/included/nested/settings.gradle
new file mode 100644
index 0000000000000..6c11c8c710d3a
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/included/nested/settings.gradle
@@ -0,0 +1,20 @@
+pluginManagement {
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+ //noinspection GroovyAssignabilityCheck
+ plugins {
+ id 'io.quarkus' version "${quarkusPluginVersion}"
+ }
+}
+
+rootProject.name = 'nested'
+
+include ':included-quarkus'
diff --git a/integration-tests/gradle/src/main/resources/included-build/included/settings.gradle b/integration-tests/gradle/src/main/resources/included-build/included/settings.gradle
new file mode 100644
index 0000000000000..898e196ebef05
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/included/settings.gradle
@@ -0,0 +1,23 @@
+pluginManagement {
+ repositories {
+ mavenLocal {
+ content {
+ includeGroupByRegex 'io.quarkus.*'
+ includeGroup 'org.hibernate.orm'
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ }
+ //noinspection GroovyAssignabilityCheck
+ plugins {
+ id 'io.quarkus' version "${quarkusPluginVersion}"
+ }
+}
+
+includeBuild 'nested'
+
+rootProject.name = 'included'
+
+include ':dependency'
+include ':included-quarkus'
diff --git a/integration-tests/gradle/src/main/resources/included-build/settings.gradle b/integration-tests/gradle/src/main/resources/included-build/settings.gradle
new file mode 100644
index 0000000000000..c454fa6792bfa
--- /dev/null
+++ b/integration-tests/gradle/src/main/resources/included-build/settings.gradle
@@ -0,0 +1,5 @@
+rootProject.name = 'include-quarkus-build'
+
+includeBuild 'included'
+
+include ':depend-on-included-build'
diff --git a/integration-tests/gradle/src/test/java/io/quarkus/gradle/IncludedQuarkusBuildTest.java b/integration-tests/gradle/src/test/java/io/quarkus/gradle/IncludedQuarkusBuildTest.java
new file mode 100644
index 0000000000000..4e2f66edaf975
--- /dev/null
+++ b/integration-tests/gradle/src/test/java/io/quarkus/gradle/IncludedQuarkusBuildTest.java
@@ -0,0 +1,48 @@
+package io.quarkus.gradle;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+
+import org.assertj.core.api.SoftAssertions;
+import org.assertj.core.api.junit.jupiter.InjectSoftAssertions;
+import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Reproducer for {@code IllegalStateException} when
+ * Quarkus project is in an included Gradle build.
+ */
+@ExtendWith(SoftAssertionsExtension.class)
+public class IncludedQuarkusBuildTest extends QuarkusGradleWrapperTestBase {
+ @InjectSoftAssertions
+ SoftAssertions soft;
+
+ @Test
+ public void test() throws Exception {
+
+ final File projectDir = getProjectDir("included-build");
+
+ Path prjDir = projectDir.toPath();
+ Path target1 = prjDir.resolve("included").resolve("gradle.properties");
+ Path target2 = prjDir.resolve("included").resolve("nested").resolve("gradle.properties");
+ Files.deleteIfExists(target1);
+ Files.deleteIfExists(target2);
+ Files.copy(prjDir.resolve("gradle.properties"), target1);
+ Files.copy(prjDir.resolve("gradle.properties"), target2);
+
+ soft.assertThat(runGradleWrapper(projectDir, "clean", "jar", "--no-build-cache").unsuccessfulTasks())
+ .isEmpty();
+
+ try {
+ soft.assertAll();
+ } catch (AssertionError ex) {
+ try (Stream files = Files.walk(prjDir)) {
+ files.map(Path::toString).sorted().forEach(System.err::println);
+ }
+ throw ex;
+ }
+ }
+}