We, GradleX, just released the new <org.gradlex.jv...
# community-news
j
We, GradleX, just released the new org.gradlex.jvm-dependency-conflict-resolution Gradle plugin 2.0 This redesigned plugin combines the functionality of the
org.gradlex.java-ecosystem-capabilities
and
dev.jacomet.logging-capabilities
plugins. And it has a ton of improvements! A highlight is the new
jvmDependencyConflicts
DSL that lets you express resolution strategies and metadata patching for Java projects in a concise way (compared to Gradle's generic dependency APIs).
Copy code
jvmDependencyConflicts {
    conflictResolution { select(JAVAX_ACTIVATION_API, "com.sun.activation:jakarta.activation") }
    logging { enforceSlf4JSimple() }
    patch { module("com.googlecode.json-simple:json-simple").removeDependency("junit:junit") }
}
Check it out, if you suffer from dependency hellish things in Java projects (props to @Louis Jacomet and @benedikt for making this happen!)
ā¤ļø 4
šŸŽ‰ 7
v
Nice, I have three questions / remarks: • the doc has in the title "Version Unspecified" • the first sentence of "JVM Dependency Conflict Detection" says "that support the other two plugins", but there is only one other plugin • If you now apply
org.gradlex.java-ecosystem-capabilities
and
dev.jacomet.logging-capabilities
, how do you migrate properly? Just remove them and apply
org.gradlex.jvm-dependency-conflict-detection
instead? Or
org.gradlex.jvm-dependency-conflict-detection
and
org.gradlex.jvm-dependency-conflict-resolution
? Are the new ones a true superset, or will something be lost?
And • is there a problem reported if the logging DSL is not used but there is a conflict? So for example if you have a project where log4j-core is used as logging framework and you have some dependency that uses slf4j-api, will you get some conflict reported or will you just loose the slf4j loggings unless you use the logging DSL to bring in the right bridge library?
t
Similarly, doc says:
The benefits described above are achieved through three different plugins
but then only lists 2 plugins
j
Thanks for the feedback! Will address the things you both found in the docs. These are indeed not completely polished yet. Yes,
org.gradlex.jvm-dependency-conflict-resolution
is a superset/replacement for the two old ones. Remove the two and use that one instead.
org.gradlex.jvm-dependency-conflict-detection
is a "base" plugin. You automatically get that. For certain scenarios you maybe just want to use that (just the metadata rules, not resolution). But I suspect that most folks want the whole package. Applying the old and new plugins together is not really defined. I'll take a note. Maybe we should add a check. Logging behaves like in the "old" logging plugin: If you do not make a selection via the DSL (or via other Gradle core API) you'll get a conflict error.
l
Note that replacing the previous plugins with the new one requires an updated configuration. We used the 2.0 version to rework the DSLs and regroup them. Another thing to add to the documentation is migration recipes.
v
We used the 2.0 version to rework the DSLs and regroup them.
Iirc I only apply them so far but didn't use the DSL šŸ™‚
Another thing to add to the documentation is migration recipes.
Sounds helpful šŸ™‚
Maybe we should add a check.
Maybe you should add capabilities šŸ˜„
If you do not make a selection via the DSL (or via other Gradle core API) you'll get a conflict error.
Maybe I asked wrongly. • If I depend on
log4j-core
and
slf4j-api
, there is no notification that something is bad (slf4j not forwarded to log4j) • If I depend on
log4j-core
and
slf4j-simple
, there is no notification that something is bad (two logging implementations) • Only if I depend on
log4j-slf4j-impl
and
slf4j-simple
, I get notification that two slf4j implementations are present
Even using
enforceLog4J2()
and depending on
slf4j-simple
and
log4j-core
does not make the build fail. I thought those
enforce...
calls would also bring in the necessary bridging libraries or at least complain that they are missing?
t
Fwiw, if you don't add
jul-to-slf4j
or
log4j-jul
you could also have "something bad" with JUL not being forwarded to another logging implementation. This goes beyond just adding capabilities though, so I'd say out of scope for that plugin (the plugin could add a capability to make all logging implementations conflict with each other, but again that will never "detect" java.util.logging or the newer java.util.System.Logging)
v
Yes, JUL is of course always special, and for that you even have to add code to make it work just adding the bridge library is not enough. But for example
enforceLog4J2()
could add a metadata rule that makes
slf4j-api
depend on
log4j-slf4j-impl
.
Practically
enforceLog4j2()
doing implicitly
Copy code
patch {
    module("org.slf4j:slf4j-api") {
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-slf4j-impl")
    }
}
as well as the according others for JCL and others if there are more
t
Yes, JUL is of course always special, and for that you even have to add code to make it work just adding the bridge library is not enough.
Fwiw, the JDK Platform Logging API uses service loader so all you have to do is add the dependency though.
That said, I think I like your proposal of automatically patching dependencies.
v
> Fwiw, the JDK Platform Logging API uses service loader so all you have to do is add the dependency though. JPL, yes. JUL does not but requires that you set a system property before any call to a JUL class is made.
So
enforceLog4j2()
could add a dependency on
log4j-jpl
and
log4j-jul
and just hope that the system property for the latter is set properly šŸ™‚
From a quick look, probably something like this when doing `enforceLog4j2()`:
Copy code
patch {
    module("log4j:log4j") {
        addCapability("ch.qos.reload4j:reload4j")
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-1.2-api")
    }
    module("ch.qos.reload4j:reload4j") {
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-1.2-api")
    }
    module("org.apache.logging.log4j:log4j-1.2-api") {
        addCapability("ch.qos.reload4j:reload4j")
    }
    module("org.slf4j:slf4j-api") {
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-slf4j2-impl")
    }
    module("org.apache.logging.log4j:log4j-core") {
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-jul")
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-jpl")
    }
    module("commons-logging:commons-logging") {
        addRuntimeOnlyDependency("org.apache.logging.log4j:log4j-jcl")
    }
}
conflictResolution {
    selectHighestVersion("ch.qos.reload4j:reload4j")
}
šŸ‘ 1
I guess noone took this as feature request from here already? šŸ˜„ Btw. the "Opening an Issue" link in the docs is also broken.