When I ```implementation "org.jetbrains.kotlin:kot...
# gradle
u
When I
Copy code
implementation "org.jetbrains.kotlin:kotlin-reflect"
and it works fine Does it pick up the kotlin version from the applied kotlin gradle plugin? Or is that shorthand for latest?
t
Does it pick up the kotlin version from the applied kotlin gradle plugin?
Yes
u
nice thanks
btw is there a way to tell that is that fact? Since for example in my spring boot app I need
runtimeOnly "org.postgresql:postgresql"
which is also version-less & I presume its not kotlin jvm plugin that adds that and I can only guess it's one of the spring plugins .. but a guess nonetheless
v
It is coming from a plugin you should stop using. The Spring dependency management plugin is a relict from times when Gradle did not have built-in BOM support and by now does more harm than good. Even the author of that plugin recommends not to use it anymore, but the built-in BOM support using
platform(...)
. Besides that, Gradle has to know a version for a dependency. If you have a dependency twice in the tree with different versions (by default) the higher version is used. If you have it twice once with and once without version, the version wins. You can also have version constraints for libraries, which means it is no dependency, but if you add that dependency the version of the constraint is also used. If you use a BOM / platform this adds all the contained things as version constraints. (the Spring dependency management plugin does something similar, just in a bad way and some other bad things) So if you have a dependency with its version already, or a version constraint for that dependency, or a platform / BOM which contains it and thus a version constraint, you can use the dependency without version as it just uses the version already known. And if there is no such version you get an error. Using the latest version would be
+
as version or
latest.release
or
latest.integration
, depending on exact intended semantic.
❤️ 1
u
So now what exactly in spring boot + postgres case? Is there a bom which includes the postgres thing? Or should i version the postgres thingy explicitly?
v
I can hardly guess what your buildscript is looking like as you did not share it. But I already guessed that you apply the Spring Dependency Management plugin that does similar things to a BOM just in a bad way. Whether it works or not I have no idea I don't have in mind what Spring Boot BOM contains and what it does not, you have to read it or look at the docs. You can anytime use a version if you want to, and the higher one will win. But afair the sense of those Spring Boot compilations is, that they say the versions they list work together nicely, so most probably for things that are in there you should not use a version.
u
oh, sorry
Copy code
[versions]
kotlin = "2.1.0"

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }
kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }
spring-boot = { id = "org.springframework.boot", version = "3.4.1" }
spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.7" }

[libraries]
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
postgres = { module = "org.postgresql:postgresql" }
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web" }
spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa" }
spring-boot-openapi = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version = "2.7.0" }
Copy code
plugins {
    alias libs.plugins.kotlin.jvm
    alias libs.plugins.kotlin.spring
    alias libs.plugins.kotlin.jpa
    alias libs.plugins.spring.boot
    alias libs.plugins.spring.dependency.management
}

dependencies {
    implementation libs.kotlin.reflect
    implementation libs.spring.boot.starter.web
    implementation libs.spring.boot.starter.data.jpa
    implementation libs.spring.boot.openapi
    runtimeOnly libs.postgres
}
just most basic setup
Copy code
[versions]
kotlin = "2.1.0"
spring = "3.4.1"

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-spring = { id = "org.jetbrains.kotlin.plugin.spring", version.ref = "kotlin" }
kotlin-jpa = { id = "org.jetbrains.kotlin.plugin.jpa", version.ref = "kotlin" }
spring-boot = { id = "org.springframework.boot", version.ref = "spring" }

[libraries]
kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
postgres = { module = "org.postgresql:postgresql", version = "42.7.5" }
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring" }
spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa", version.ref = "spring" }
spring-boot-openapi = { module = "org.springdoc:springdoc-openapi-starter-webmvc-ui", version = "2.7.0" }
I mean I can obviously do this (and remove the dependency managemenet plugin), but should I? is there a bom for spring at all?
v
Did I say you should remove the dependency management plugin?
u
It is coming from a plugin you should stop using.
sounds like it 😄
v
Then why do you ask whether you should if I already told you so? 🙂 But no, the other changes in the version catalog you should not do, but you should use the Spring Boot BOM as I already said. The Spring Boot Gradle plugin even has a constant you can use. Just read the Spring Boot documentation it has all the info readily available.
u
I mean.. when I look at their docs, the first thing they say is to add the dependency management plugin https://docs.spring.io/spring-boot/gradle-plugin/getting-started.html
v
Well, they tell you wrong. Do you more trust outdated docs and outdated generator tools, or the Gradle experts you are talking to and the maintainer of that plugin who itself says you should not use it?
u
😄 Ofcourse I trust you guys, it's just you said to look at the docs which are readily available - and crap
v
No, just scroll down.
Below the bad version they show the good version
u
what?
Copy code
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.4.1'
}

apply plugin: 'io.spring.dependency-management'
this is the good version?
v
How do you think that is the good version? You still apply the bad plugin, just now additionally in a bad way.
u
Below the bad version they show the good version
.
v
If that is what you get from scrolling down, you are probably on the wrong page
u
okay I see, is using a bom preferred over the shared
version.ref
in catalogue? I mean I can never tell what's inside the bom
also, not sure why do I need to
implementation platform..
it if it is necessary & there's a spring boot gradle plugin .. why won't the plugin simply add it I'm new to boms
v
I mean I can never tell what's inside the bom
Sure you can, you can just read it.
is using a bom preferred over the shared
version.ref
in catalogue?
But again, whether you specify versions yourself or use the BOM is up to you. Iirc the sense of Spring Boot and the BOM is that they say "these versions properly work together we recommend you use those". Whether you follow that recommendation is up to you. Besides that you cannot use a "shared `version.ref`" except for the Spring-own modules. It defines versions for dozens of other dependencies and those are all different.
also, not sure why do I need to
implementation platform..
To use their BOM and thus the versions of the dependencies they recommend as "working together properly"
it if it is necessary
If you want to use their version recommendations, yes
there's a spring boot gradle plugin .. why won't the plugin simply add it
I don't know, ask them. Probably for the same reason they also have in the getting started docs and generator the Spring Dependency Management plugin. Why that is the case is a miracle to me when even the maintainer of the plugin tells to not use it anymore. Maybe it is due to legacy or backwards compatibility reasons. 🤷‍♂️
Btw. I also strongly recommend you switch to Kotlin DSL. By now it is the default DSL, you immediately get type-safe build script, actually helpful error messages if you mess up the syntax, and amazingly better IDE support if you use a good IDE like IntelliJ IDEA or Android Studio.
u
okay so the bom extends beyond the 1st party spring stuff that's what had me confused, as all the spring dependencies I use are
Copy code
spring-boot-starter-web = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring" }
spring-boot-starter-data-jpa = { module = "org.springframework.boot:spring-boot-starter-data-jpa", version.ref = "spring" }
version.ref = spring
anyways
v
You should probably read a bit about Spring Boot to get the idea
u
just to be sure -
implementation platform..
doesnt actually include any dependency, just a sort of map of version to use if said dependency were to be included?
v
exactly
u
okay, besides the spring boot usecase - i've seen it in jetpack compose as well but then if I were to use it - won't it break with transitive dependencies? I mean if I use compose platform 2.0, which includes say
foundation:2.0
and a 3rd party dependency depends on
foundation:2.1
directly, then I'll get the
2.1
anyways, correct?
v
yes, unless you changed configuration to fail on version conflict, or use an enforced platform (you should almost never do) or somewhere us a strict version, or use other things or plugins that influence the resolution. But generally speaking, yes
u
that doesn't inspire confidence 😄
okay so it's sort of like
version.ref
if that needs to be multiple numbers for some reason, gotcha but still I'd like to see what's in it, so I can say remove the exact versions, now I just guess & compile/hope
v
> that doesn't inspire confidence 😄 Well, Gradle is very mighty and give you much power. But with great power comes great responsibility. (✔️ Spiderman reference)
but still I'd like to see what's in it, so I can say remove the exact versions
It's a text file, read it
u
where
v
Or check their docs, I guess they have a list
Or just check
dependencies
output or a build
--scan
For dependencies you did not use you will not see an entry, but for the ones you used, you will also see the version constraint considered.
u
I'm wondering why is this at all necessary if spring 1.0 depends on jackson 1.0, and I explicitly include jackson 2.0, then 2.0 will be used & it will compile -- provided jackson is backwards compatible
v
Spring does not depend on all those
Also Spring Boot does not depend on all those
u
then why does it care what version jackson im using?
v
The Spring Boot team says "if you want to use these libraries, use those versions, we tested that they work together nicely"
Whether you follow that recommendation or not is up to you
u
yes but why would they not play nice, in general
if theres no dependency between them
v
Who says there isn't?
If you for example have libs A, B, and C. A and B are popular dependencies, C is a library both use. A1 uses C1, A2 uses C2, B1 uses C1. C2 got breaking changes so B1 cannot work with it. If you depend on A2 and B1 it will fail at runtime. Spring Boot is saying "if you use A use A1, if you use B use B1". So if you now just say "use A and B", you get versions that work properly together. But neither Spring nor Spring Boot use A or B.
u
but A cannot enforce B's version so I need to take care not to specify version for B for the A's bom to take over so I sort of need to make A the master of the B
v
The level is irrelevant, but yes otherwise. And again, it can enforce if you use an enforced platform you just shouldn't. And again, they are *recommendations
A the master of B? o_O
What are you talking about?
Spring Boot is the master of A and B. A and B are unrelated besides both using C
u
forget spring boot, just your A B C example; where A has a bom, B doesnt. so I need to take care not to specify B version for the A's bom to take over & make it all work so A('s bom) is in a sense managing B
also - you're hinging it all on semver correct? that major change means incompatible changes?
v
You cannot forget Spring Boot, as it was an example situation that Spring Boot tries to solve. A and B are unrelated
And A does not have a BOM
And A knows nothing about B
u
if it had one
v
Semver is irrelevant, but in my example it correlated
But the same is true if version 1.2.3.4.5 adds a breaking change compared to 1.2.3.4.4
Even if A had a BOM, it is unrelated to B, it does not even know about B, so why the heck should it say anything about B?
That's the whole point of the Spring Boot BOM to solve this clusterfuck, as I explained multiple times already.
Why do I have to say everything multiple times? Do you know how time-eating that is? That's btw. one of the characteristics of a help vampire.
u
well it's not getting through my skull
unrelated
in terms of gradle dependencies? anyways what I meant was if the bom is just a "collection of stuff you might probably be using" & I should obey it, in that sense that bom is master of the versions of the given stuff
v
Unrelated in any possible meaning
In the world-view of A, B is not a thing, it does not exist
u
yes but I expanded on your example - A,B & A has a bom; where A & B are not related in gradle dependency manner if my assumption that A's bom is "if you use A, you prooobably are using B, and if so, use version B:x" is correct, then that means you should let the bom manage B's version, which in turn means A's bom is super to B in a sense
v
That's not the situation though. The situation is, that A has not relation at all to B. It does not know about B. And it is in no way more or less likely that someone uses B just because it uses A or the other way around. They are just two totally independent things that have no relation at all, besides both using C.
And no, even with your assumption it does not really make sense that A says anything about B
It even cannot say something about all other dependencies that might maybe be used if it is used, that's just not its responsibility.
u
then I've no idea what we're talking about
v
I'm describing you the problem the Spring Boot BOM tries to solve. You insist on striking Spring Boot BOM from the equation and thus make the whole conversation moot.
u
well, because when I look at spring boot's bom, it for example references jackson - and spring boot depends on jackson
v
The Spring Boot BOM is not using Jackson.
The Spring Boot BOM is only a list of version constraints.
Some of the Spring Boot projects might use Jackson and also use the BOM for managing the versions
In thus those Spring Boot projects would be A and Jackson would be C
u
what? https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/3.4.1/spring-boot-dependencies-3.4.1.pom spring boot bom 3.4.1 references
Copy code
<dependency>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-bom</artifactId>
<version>${jackson-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
I'm asking why is this necessary, to have such bom which says spring 3.4.1 should use jackson 1.2.3, when spring 3.4.1 (the project) depends on jackson 1.2.3 In my noob brain it's redundant
v
You don't listen, do I really have to say it again?
It does not say that Spring 3.4.1 uses Jackson 1.2.3
Not even that Spring Boot 3.4.1 uses Jackson 1.2.3 if that is what you meant
That
<dependency>
tag is not within a
<dependencies>
tag. It is within a
<dependencyManagement>
tag. That means it is a version constraint and thus part of the BOM.
u
I know it doesnt say that. I get it's a suggestion to the consumer of both spring & jackson. BUT spring depends on jackson, so this unnecessary, isn't it?
v
It does not imply any dependency from any project to any other project
All it says is, "if someone is using this BOM, this is the recommended version for Jackson"
You don't have to use Spring
u
isn't the same thing said in terms of spring boot's dependency on jackson?
v
"Spring Boot" consists of dozens of things, what exactly are you talking about?
And no, it is not
You could also use the Spring Boot BOM alone without using anything else from Spring or Spring Boot
u
I get that "spring bom 1 is saying that (spring-boot-starter 2, spring-boot-data-jpa 3, jackson 4) are all playing nice" but spring-boot-starter 2 will have a dependency on jackson 4 so why is this necessary (to mention jackson in the bom at all)
v
so why is this necessary (to mention jackson in the bom at all)
Who says you are using spring-boot-starter at all?
Say you don't, then again nothing would be said about Jackson and which version is recommended
Anyway, I'm tired and try to debug something since hours just cannot concentrate on it due to this conversation. If you want a reasoning about the existence of Spring Boot BOM, ask the inventors or maintainers of Spring Boot BOM. This is a Gradle chat, not a Spring Boot chat.
Btw. most often and mainly a BOM is used for a different purpose. You usually have a BOM where you list your modules if you have multiple. So for example Jackson has a BOM where all the different Jackson modules are listed an nothing else. So you can use the BOM to define the version and then just use the other Jackson modules without version. In that scenario using the shared verison in the version catalog is basically the same. Another use for such a BOM if done properly is, for version alignment of the modules in Gradle, so to ensure that all modules of the project are always in the same version and not that someone accidentally uses
jackson-a
version 1 with
jackson-b
version 2, but either all version 1 or all version 2. The Spring Boot BOM is just for a different use-case that I described above.
u
that makes sense, to publish a jackson bom 1 which says (jackson-parsing 1, jackson-whatever 2, jackson-idk 3) are all a single release in a sense
but when it starts talking about non jackson stuff it doesnt make sense to me
sorry to bother you that much, thank you for you help, you were insightful
v
Yes, exactly. For Jackson BOM it does not make much sense to mention any other libs and it does not.
But the difference is, that the intention of the Spring Boot BOM is exactly this, to have exactly those 3rd party dependency versions defined that they tested work together nicely as a recommendation for you to use when you need those libraries.
If you don't want that, just don't use it. They are recommendations from tests they did. Whether you follow them by using their BOM is up to you
Previously you also did by using that plugin, just in a bad technical way.
With the
platform(...)
you do the same, just in a technically better way and without the other non-sense that plugin is doing.