Closed som-snytt closed 10 months ago
@som-snytt is this one you were thinking of tackling yourself...? I agree the current behavior is peculiar.
So far scalac always emitted a fixed classfile version, no matter what JDK was used at compile-time (unless -target
is set, or -release
which in turn sets -target
). Scala 3 does the same, for the record.
The failure mode is that compiled code can refer to JDK elements that don't exist on the JDK corresponding to the classfile version. The question is, does it make sense to turn that into a hard error now?
Yeah, although I described the current behavior as “peculiar”, that might not actually be sufficient justification for changing it now. One reason not to might be possible fragility around -release
. For example, someone might not have JDK 8 on their system at all.
I'm not sure what a JDK element is.
Are -release
and -target
orthogonal after all? What API I can call has nothing to do with class file features which may constrain how my Scala code is compiled. Well, the reason for target to follow release is not functional but practical, as it ensures that the class is loaded by the desired JVM version.
Normally, I don't care much. Why does javac do the natural thing? Only to support Java features. But Scala does not have feature dependencies; functionally, setting the release/target is a kind of niche optimization.
OTOH, arguably, defaulting to version 52 gives the misleading impression that the code will run on JDK 8, although it was compiled against later API. Oh, that's what lrytz meant by element. It seems to me that in fact release and target should correspond, and the question is whether release should default to ambient or 8.
(A moment ago, I was prepared to close the issue, but are we to believe that no one has ever accidentally published a jar without setting release, used new API, and some unsuspecting user saw an error only later in production?) (I can believe that because release is of relatively recent vintage, and entities stuck on JDK 8 are not rebuilding code, so they would never see the bad jar.)
I'm not sure what a JDK element is.
Sorry, I just meant API from the JDK. Lost my jargon during vacation.
the reason for target to follow release is not functional but practical
I agree
Why does javac do the natural thing?
Maybe because the compiler version is tied to the JDK? What happens if you run the Java 17 compiler on JDK 20?
question is whether release should default to ambient or 8
Yeah... trying to change this is probably not worth the risk. Say someone has been publishing a project using JDK 17 for a while, upgrades to 2.13.12, and then suddenly the artifacts no longer work for users on JDK 11.
Closing as a FAQ.
Oh... I was confused before. Yes, I'm okay with the status quo here.
Reproduction steps
Scala version: 2.13.12
Problem
Will you still need me? Will you still feed me, when I'm 64?
Since the default value for
-release
is20
under JDK 20, I would expect the class file version to reflect that.Noticed while comparing javac output.
scalac -target
defaults to 8 but follows-release
except for the default case. Note that 2.12 is fixed to target 8, but I don't recall any discussion about 2.13 target defaulting to default release value (which depends on the JVM in use).