Manage Resolution Conflicts

The MicroEJ Gradle plugin adds specific rules for compilation, building, resolving dependencies, versioning, and publishing.

Gradle comes with a powerful dependency manager. One of its job is to resolve the conflicts in the dependency graph, to determine which version should be added to the graph. By default, Gradle selects the highest version amongst all the versions requested for a dependency. There are ways to influence the dependencies resolution, but we believe additional rules should be added to provide a better and safer conflict resolution.

Note

You can learn more on the Gradle conflicts resolution and the way to configure it in the official documentation.

The MicroEJ Gradle plugin adds the 2 following rules:

  • The resolution fails when a dependency is requested with 2 incompatible versions in the graph, according to the Semantic Versioning specification. So, it means that if 2 versions do not have the same major version, the build fails. For example, this dependency graph makes the build fail because the moduleC dependency is requested in 2 incompatible versions:

    digraph mygraph {
    bgcolor="transparent"
    fontname="Helvetica,Arial,sans-serif"
    node [
        shape = box
        width = 1.5
        color = "#7dc5dc"
        style = filled
        fontname="Helvetica,Arial,sans-serif"
    ]
    edge [fontname="Helvetica,Arial,sans-serif"]
    "rootModule" -> "moduleA:1.0.0"
    "moduleA:1.0.0" -> "moduleC:2.0.0"
    "rootModule" -> "moduleB:1.0.0"
    "moduleB:1.0.0" -> "moduleC:3.0.0"
}

  • The resolution fails when a transitive dependency is resolved with a higher minor version than the one declared. For example, this dependency graph makes the build fails because the moduleA dependency is resolved in version 1.1.0 (the highest one), which is higher than the direct declared version (1.0.0):

    digraph mygraph {
    bgcolor="transparent"
    fontname="Helvetica,Arial,sans-serif"
    node [
        shape = box
        width = 1.5
        color = "#7dc5dc"
        style = filled
        fontname="Helvetica,Arial,sans-serif"
    ]
    edge [fontname="Helvetica,Arial,sans-serif"]
    "rootModule" -> "moduleA:1.0.0"
    "rootModule" -> "moduleB:1.0.0"
    "moduleB:1.0.0" -> "moduleA:1.1.0"
}

If you want to come back to the Gradle default behavior, these 2 rules can be disabled by setting the microejConflictResolutionRulesEnabled property of the microej configuration block to false in the project build file:

microej {
  microejConflictResolutionRulesEnabled = false
}