Is there a way to somehow transform an optional (t...
# dependency-management
t
Is there a way to somehow transform an optional (transitive) dependency in the pom.xml of a (direct) dependency into a dependency constraint? Context: org.jooq:jooq has an optional dependency on jakarta.xml.bind:jakarta.xml.bind-api, optional in this case because that dependency is incompatible with Java 8, and it's only used for its annotations so shouldn't be needed at runtime (unless you want to take advantage of them, in which case you'd have to somehow have a dependency on them anyway). The problem is that JavaC emits a warning when they're not in the compile classpath. My idea was to use the org.gradlex.jvm-dependency-conflict-resolution plugin to "patch" org.jooq:jooq and declare jakarta.xml.bind:jakarta.xml.bind-api as compileOnlyApi dependency, but without specifying the version; ideally it could then use the one from the pom.xml as the default (through a dependency constraint, unless I have a dependency on it by other means), and I wouldn't have to hardcode the version and update it at the same time that I update org.jooq:jooq. This also means this "rule" could be "bundled" into a plugin, irrespective of the version of org.jooq:jooq used by the project in the end. (for now, I simply declare a compileOnlyApi dependency with a because() to document it, and I thus have a version declared in my catalog; this is very explicit and "noisy"; and it's ok because it's only happened once) Also, WDYT, should this be the default behavior of Gradle? (to have optional dependencies participate in version resolution)
v
This was the case long time ago and it was removed. Afair mainly to be more consistent with Maven resolution. "optional" dependencies are just a note for the user of the library that some features might need this dependency but their version is never included in version calculation, so it also is no longer in Gradle since years. I remember that the error prone compiler has some shortcomings when it comes to annotations, but actually this should be fixed in the error prone compiler. Annotations in compiled classes for which the class file is not present must be ignored by the compiler and runtime just as if they were not present. If any consumer wants to get the annotation and their value, then this consumer has to add the annotations to the classpath. So if the error prone compiler wants to consider specific annotations, it is the consumer and the one that is responsible to add the class files for those annotations to the classpath.
t
Ooh, actually that's nothing to do with Error Prone: this is a JavaC warning (that I turn into an error with -Werror). I'll update my message above. The thing is, an "annotation method not found" warning can be turned down with -Xlint:-classfile (and who knowns what kind of other warnings it could disable), but an "unknown enum constant" warning (for an enum constant referenced by an annotation (here)) cannot. My opinion is that those are fair warnings by JavaC (and well, we don't really have the choice here) and that annotations are part of your API so should always be on the compile classpath, and with Maven's awfully limited "scopes" that means also having them on the runtime classpath (with Gradle you can use compileOnlyApi).
v
Hm, interesting, either I forgot that detail or didn't know. I thought as the annotation is ignored also the arguments should be ignored if class file absent. 😕 Maybe that is actually a bug in
javac
?
t
Whether a bug or not wrt enums in annotations (this has been known for years), I feel like there should be a way to workaround the brokenness of Maven's optional and provided in Gradle. Is this information entirely lost? (wrt the other suppressable warning, and Maven's broken design: https://issues.apache.org/jira/browse/MNG-2205?focusedCommentId=16267311&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#c[…]1 ; and looking at the issue tracker for javac, look what I found: https://bugs.openjdk.org/browse/JDK-8305250 😉)
v
Yeah, that JDK bug is exactly what I mean, that imho shouldn't emit a warning if the whole annotation is absent as annotation being absent is fine. 🙂 But yeah, the information is lost. As I said, it was considered as constraint in the long passed past. The "proper work-around" would probably be to have GMM with the jaxb-api as compile only api, or to patch it in via component metadata rule. But afair there is no built-in way to use the dependency version from the pom.
• Maven optional dependencies are no longer brought in as constraints as this caused more harm than good and Maven simply ignores that information anyway.
t
that imho shouldn't emit a warning if the whole annotation is absent as annotation being absent is fine
Not exactly "fine" as it still emits a warning (a suppressable one for sure, but still something that's not considered "fine"; I'd rather say "recoverable")
But afair there is no built-in way to use the dependency version from the pom.
Too bad. Thanks anyway
👌 1
v
Not exactly "fine" as it still emits a warning
No, an absent annotation class should not emit a warning but just be ignored
The enum emits a warning, and that is this javac bug you found, that of course is not fine, but should be fine if the annotation is also absent