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; + } + } +}