Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gradle quarkusGenerateCode task is failling to resolve dependencies #39073

Closed
rmanibus opened this issue Feb 29, 2024 · 12 comments
Closed

Gradle quarkusGenerateCode task is failling to resolve dependencies #39073

rmanibus opened this issue Feb 29, 2024 · 12 comments
Labels
area/gradle Gradle kind/bug Something isn't working

Comments

@rmanibus
Copy link
Contributor

rmanibus commented Feb 29, 2024

Describe the bug

since quarkus 3.7 the gradle task quarkusGenerateCode is failing to resolve dependencies if the version is provided via a bom:

        dependencies {
            implementation enforcedPlatform(project(':bom'))
            annotationProcessor platform(project(':bom'))
            testAnnotationProcessor platform(project(':bom'))
            compileOnly "org.projectlombok:lombok"
            annotationProcessor "org.projectlombok:lombok"
            testCompileOnly "org.projectlombok:lombok"
            testAnnotationProcessor "org.projectlombok:lombok"
        }

bom dependencies block:

dependencies {
    api enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
    constraints {
        api "org.projectlombok:lombok:1.18.30"
    }
}

This was working up to quarkus 3.6

Expected behavior

lombok code generation is working with gradle

Actual behavior

build and dev mode are failing with:


* What went wrong:
Execution failed for task ':main-partition:quarkusGenerateCode'.
> Could not resolve all dependencies for configuration ':main-partition:quarkusProdCompileOnlyConfiguration'.
   > Could not find org.projectlombok:lombok:.
     Required by:
         project :main-partition

How to Reproduce?

https://github.com/rmanibus/quarkus_39073

run gradlew build or gradlew quarkusDev

Output of uname -a or ver

No response

Output of java -version

openjdk version "21.0.2"

Quarkus version or git rev

3.8.1

Build tool (ie. output of mvnw --version or gradlew --version)

gradle

Additional information

No response

@rmanibus rmanibus added the kind/bug Something isn't working label Feb 29, 2024
@quarkus-bot quarkus-bot bot added the area/gradle Gradle label Feb 29, 2024
Copy link

quarkus-bot bot commented Feb 29, 2024

/cc @glefloch, @quarkusio/devtools

@rmanibus rmanibus changed the title Gradle quarkusGenerateCode task is failling to resolve some dependencies Gradle quarkusGenerateCode task is failling to resolve dependencies Feb 29, 2024
@rmanibus
Copy link
Contributor Author

rmanibus commented Mar 5, 2024

@glefloch any idea about this one ?

@rmanibus
Copy link
Contributor Author

I found the issue, I was missing:

        dependencies {
[...]
            compileOnly platform(project(':bom'))
 
        }

Not sure why the issue appeared with the quarkus upgrade.

closing this, sorry for the confusion

@FWest98
Copy link
Contributor

FWest98 commented Jun 4, 2024

I ran into this issue as well, and while there is the simple fix of adding the BOM to the compileOnly configuration, this does not seem to be ideal and a bit unconventional for Gradle - and in case of Quarkus might have further unintended side effects since it affects the application model.

At its root, the issue is caused by the quarkus<Env>CompileOnlyConfiguration not being resolved. This configuration normally only extends the compileOnly configuration, which is not intended to be resolvable on its own (hence canBeResolved = false). Instead, the compileOnly configuration is intended to be composed with other configurations and then be resolved (such as combined with implementation to form compileClasspath - in which case the BOM is taken from implementation before resolving the compileOnly dependencies). So it seems a bit weird to want to resolve the compileOnly in isolation (somewhat), but there might be valid usecases.

However, in this case, this configuration is only used (and resolved) in the GradleApplicationModelBuilder, where it is used to resolve dependencies to form the application model for further Gradle stuff. In particular, it seems to separately resolve the quarkus<Env>RuntimeClasspathConfiguration , quarkus<Env>RuntimeClasspathConfigurationRuntime, and quarkus<Env>CompileOnlyConfiguration configurations. Here, the first extends from the (resolvable) runtimeClasspath configuration, the second defines its own platform, which leaves the third configuration potentially unresolvable.

It seems like the compileOnly is treated separately from the others to be able to flag these dependencies as COMPILE_ONLY. However, this then requires resolving the configuration, which fails without a platform. Would there be another way to achieve the same? I could think of, for example:

  • Making a single configuration that combines the three configurations above and letting Gradle resolve all those at once. Then marking the compile only dependencies can be done by inspecting the unresolved dependencies, since the logic only uses the group/name/classifier anyway (so not the version)
  • Apply a platform to quarkus<Env>CompileOnlyConfiguration just as is done for the platform configuration? This might be the easiest "behind the scenes" fix, similar to the in-Gradle workaround, but this will mark the entire Quarkus BOM as "compile only" which might have unintended side-effects (and is why I'm hesitant to apply the workaround)

@maxandersen
Copy link
Member

what am I missing in thinking that gradle should follow the target platform both during compile and implementation?

whats the "gradle way" of doing this?

@FWest98
Copy link
Contributor

FWest98 commented Jun 5, 2024

Normally, in Gradle, the compileOnly configuration is merged with others (such as implementation) to form the compileClasspath and runtimeClasspath. So, then any dependencies in compileOnly will only be resolved once they are merged with implementation (and possibly others), so defining a platform in implementation will then transparently affect both the compile and runtime classpaths.

So the "odd thing" that Quarkus is doing, is to resolve compileOnly on its own - it's not meant for that essentially. At least, that's my understanding.

@aloubyansky
Copy link
Member

Normally, in Gradle, the compileOnly configuration is merged with others (such as implementation) to form the compileClasspath and runtimeClasspath

compileOnly shouldn't leak into runtimeClasspath. As you mentioned in a previous comment, we need to capture compileOnly dependencies to set the COMPILE_ONLY flag, some extensions rely on that.

So it looks like we need to apply all the version constraints resolving compile only. For now it's

            project.getConfigurations().register(compileOnlyConfigurationName, config -> {
                config.extendsFrom(project.getConfigurations().getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME));
                config.shouldResolveConsistentlyWith(getDeploymentConfiguration());
                config.setCanBeConsumed(false);
            });

so shouldResolveConsistentlyWith(getDeploymentConfiguration()) doesn't seem to be enough.

@aloubyansky
Copy link
Member

#41007 appears to fix the reproducer provided by @rmanibus

@maxandersen
Copy link
Member

awesome - so I was thinking about this bug and realized this must have been a recent change as it should have failed in other situations in past. Does that match? that some change "recently" broke this or are we saying we always had this bug and just now triggered it in the latest red hat quarkus build by "chance" ?

@maxandersen
Copy link
Member

@aloubyansky is #41007 a new thing or a fix to regression? just to know if we think this was by chance avoided for 3-4 years or due to change on gradle integration side we missed? (in any case - a test case might be good so we don't get caught again)

@aloubyansky
Copy link
Member

It's probably a regression after introducing compile-only dependencies in the ApplicationModel for Web bundler use-cases

@maxandersen
Copy link
Member

@aloubyansky gotcha - makes sense and triage/backport should go to 3.8 LTS too then i reckon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/gradle Gradle kind/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants