|
41 | 41 | driver loads on JDK 25. Revisit only if a release appears with a jre suffix at or above |
42 | 42 | java.version. --> |
43 | 43 | <mssql.jre.version>11</mssql.jre.version> |
| 44 | + |
| 45 | + <!-- The -release scala-maven-plugin passes to scalac, and on to javac for the .java sources |
| 46 | + that live under src/main/scala. It bounds which JDK API our own sources may reference. |
| 47 | +
|
| 48 | + Kept aligned with java.version: there is no supported configuration below it. The test |
| 49 | + runner aborts unless it finds exactly that JDK, every Dockerfile is eclipse-temurin:25, |
| 50 | + and every CI job sets java-version 25 - so a build host on an older JDK does not exist, |
| 51 | + and capping this lower would only hide APIs we are entitled to use. |
| 52 | +
|
| 53 | + Still a separate property rather than a direct ${java.version} reference, because the two |
| 54 | + express different constraints. java.version is the JDK we target and ship on; this is the |
| 55 | + highest -release the *compiler* will accept, which is the spec version of the JDK actually |
| 56 | + running scalac - not a property of the Scala version. The same scalac 2.12.21 accepts up |
| 57 | + to 17 on JDK 17, up to 21 on JDK 21 and up to 25 on JDK 25. So whenever java.version moves |
| 58 | + ahead of the JDK on the build host, the two must be able to come apart; wiring this to |
| 59 | + ${java.version} would make that impossible to express. That is exactly what happened on |
| 60 | + 2026-07-03: java.version had just gone to 25 while a build host was still on 21, scalac |
| 61 | + rejected -release 25 with "'25' is not a valid choice for '-release'", and the symptom was |
| 62 | + read as a Scala-version limit. maven-enforcer-plugin now fails fast on that case instead. |
| 63 | +
|
| 64 | + Caveat: on Scala 2.12 this only widens the visible API surface, it does not raise the |
| 65 | + class-file version. 2.12 emits Java 8 class files whatever -release says, so a Scala class |
| 66 | + that calls a Java 25 method fails at run time with NoSuchMethodError instead of at load |
| 67 | + time with UnsupportedClassVersionError. Getting that check back needs Scala 2.13+. javac |
| 68 | + does honour it, so the .java sources under src/main/scala track this value. --> |
| 69 | + <scalac.release>25</scalac.release> |
44 | 70 | </properties> |
45 | 71 |
|
46 | 72 | <modules> |
|
192 | 218 | <configuration> |
193 | 219 | <scalaVersion>${scala.compiler}</scalaVersion> |
194 | 220 | <charset>${project.build.sourceEncoding}</charset> |
195 | | - <!-- Pin scalac's -release independently of ${java.version}. javac needs -release 25 |
196 | | - for JDK 25, but the Scala 2.12.21 compiler only accepts -release up to 17 (its |
197 | | - max supported Java API/target). Without this, scala-maven-plugin derives -release |
198 | | - from maven.compiler.target (=${java.version}=25) and passes an unsupported |
199 | | - -release 25 to scalac, failing the build with |
200 | | - "'25' is not a valid choice for '-release'". Scala 2.12 emits Java 8 bytecode |
201 | | - regardless, so this only bounds the visible JDK API surface; the classes still run |
202 | | - on JDK 25. Bump this only when moving to a Scala version that supports a higher |
203 | | - -release. --> |
204 | | - <release>17</release> |
| 221 | + <!-- Set explicitly because scala-maven-plugin otherwise derives -release from |
| 222 | + maven.compiler.target (= ${java.version}), which would demand a JDK 25 build host. |
| 223 | + See the scalac.release property for the ceiling rule and its caveats. --> |
| 224 | + <release>${scalac.release}</release> |
205 | 225 | <displayCmd>true</displayCmd> |
206 | 226 | <!-- Optimized JVM settings for faster Scala compilation --> |
207 | 227 | <jvmArgs> |
|
298 | 318 | </execution> |
299 | 319 | </executions> |
300 | 320 | </plugin> |
| 321 | + <!-- Fail fast when the build JDK is older than scalac's -release. scalac cannot target a |
| 322 | + release newer than the JDK running it, so without this check the build dies minutes |
| 323 | + later inside scala-maven-plugin with "'25' is not a valid choice for '-release'" - |
| 324 | + which reads as a Scala-version limit rather than a stale build host, and was misread |
| 325 | + that way on 2026-07-03. The bound is ${scalac.release} itself, not a literal, so the |
| 326 | + rule can never drift from the actual constraint. |
| 327 | +
|
| 328 | + No custom <message>: the rule's default text is strictly more useful here, naming the |
| 329 | + detected version, its JAVA_HOME and the required range, e.g. |
| 330 | + Detected JDK version 17.0.5 (JAVA_HOME=...) is not in the allowed range [25,). |
| 331 | + A custom message would replace that rather than add to it. --> |
| 332 | + <plugin> |
| 333 | + <groupId>org.apache.maven.plugins</groupId> |
| 334 | + <artifactId>maven-enforcer-plugin</artifactId> |
| 335 | + <version>3.5.0</version> |
| 336 | + <executions> |
| 337 | + <execution> |
| 338 | + <id>enforce-build-jdk</id> |
| 339 | + <phase>validate</phase> |
| 340 | + <goals> |
| 341 | + <goal>enforce</goal> |
| 342 | + </goals> |
| 343 | + <configuration> |
| 344 | + <rules> |
| 345 | + <requireJavaVersion> |
| 346 | + <version>[${scalac.release},)</version> |
| 347 | + </requireJavaVersion> |
| 348 | + </rules> |
| 349 | + </configuration> |
| 350 | + </execution> |
| 351 | + </executions> |
| 352 | + </plugin> |
301 | 353 |
|
302 | 354 |
|
303 | 355 |
|
|
0 commit comments