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 7.3.2 added a constraint and it show as a depencendy update #576

Closed
ErwanLeroux opened this issue Dec 22, 2021 · 8 comments
Closed

Comments

@ErwanLeroux
Copy link
Collaborator

ErwanLeroux commented Dec 22, 2021

Hello, I noticed something when upgrading from gradle 7.3 to 7.3.2, log4j-core is shown as an update even if the dependency is not in the project

The following dependencies have later milestone versions:
 - org.apache.logging.log4j:log4j-core [2.16.0 -> 2.17.0]
     https://logging.apache.org/log4j/2.x/

It took me a while to understand that it was because Gradle added a constraint in 7.3.2, to help mitigate https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-45105
Mitigations for log4j vulnerability in Gradle builds (logj4:2.16.0) gradle/gradle#19300

Should the plugin tell us about this constraint if we can't do anything about it ? And if no, how can we configure the plugin to ignore that particular constraint, like we can do with
Could the report be more explicit that the update is from a constraint instead a dependency ?

I made a project to reproduce the context : https://github.com/ErwanLeroux/dU-mcve but it can resumed as

plugins {
    java
    id("com.github.ben-manes.versions") version "0.39.0"
}

tasks.withType<com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask> {
    checkConstraints = true
}

I look forward to ear from you, I really like this plugin :)

@ben-manes
Copy link
Owner

The checkConstraints feature was contributed by @anuraaga, so he might have recommendations on how we should handle this case. The comment indicates that not matching is desired for transitive scenarios in order to detect these type of problems. Of course he wrote that assuming the build author added that intentionally, whereas Gradle's own is surprising noise. I think to differentiate we'd have to resolve the dependency graph to see if it was listed transitively. It could be confusing regardless of what we do, so I am not sure about the best approach here.

if (supportsConstraints(copy)) {
for (DependencyConstraint constraint : copy.dependencyConstraints) {
Coordinate coordinate = Coordinate.from(constraint)
// Only add a constraint to the report if there is no dependency matching it, this means it
// is targeting a transitive dependency or is part of a platform.
if (!coordinates.containsKey(coordinate.key)) {
coordinates.put(coordinate.key, declared.get(coordinate.key))
}
}
}

@anuraaga
Copy link
Collaborator

From what I can tell Gradle adds the constraint to the buildscript dependencies, not the project dependencies.

gradle/gradle@6aeddcf

checkConstraints was added mostly to support platform BOM projects, and also for normal constraints in project dependencies which tend to be less common but still useful to check - I suspect constraints are used very rarely in buildscript and it was definitely not a use case in mind when originally writing the feature. The only time I've ever tried to use constraints in buildscript was to try to work around some apache httpclient dependency conflicts in jib and nexus publishing plugins, but couldn't actually get it to work 😅 But such a case also wouldn't really need to then be updated as it's usually fixing to an old version intentionally.

So I believe it should be possible to modify supportsConstraints to exclude the buildscript, which if I'm not mistaken is a configuration with the name classpath.

private boolean supportsConstraints(Configuration configuration) {

@ben-manes Does that sound about right?

@ben-manes
Copy link
Owner

If that’s the right approach, then I think when providing the configuration we could instruct whether it’s from the buildscript.

/** Evaluates the dependencies and returns a reporter. */
DependencyUpdatesReporter run() {
Map<Project, Set<Configuration>> projectConfigs = project.allprojects.collectEntries { proj ->
[proj, proj.configurations + (Set) proj.buildscript.configurations]
}
Set<DependencyStatus> status = resolveProjects(projectConfigs)

@anuraaga
Copy link
Collaborator

Ah proj.buildscript.configurations cool didn't know about that. Indeed it seems more appropriate to handle it structurally then.

@ben-manes
Copy link
Owner

@ErwanLeroux you're welcome to submit a PR (+ unit test) if you'd like to make this change. If you prefer, you could sniff for log4j only to ignore it if a buildscript configuration.

@ErwanLeroux
Copy link
Collaborator Author

@ben-manes I'm working on it, starting with the unit-test :)

@ben-manes
Copy link
Owner

Wonderful! Thank you 🙂

FYI, you can increment the plugin's version and then use gradle publishToMavenLocal. In your sample build, then add mavenLocal() to retrieve your new version. This makes it easy to iterate outside of a unit test.

ErwanLeroux added a commit to ErwanLeroux/gradle-versions-plugin that referenced this issue Dec 27, 2021
ErwanLeroux added a commit to ErwanLeroux/gradle-versions-plugin that referenced this issue Dec 27, 2021
ErwanLeroux added a commit to ErwanLeroux/gradle-versions-plugin that referenced this issue Dec 27, 2021
ErwanLeroux added a commit to ErwanLeroux/gradle-versions-plugin that referenced this issue Dec 30, 2021
ErwanLeroux added a commit that referenced this issue Dec 30, 2021
@ErwanLeroux
Copy link
Collaborator Author

solved in #577

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants