Confusion regarding Java/Kotlin versions

48 Replies
JavaBot
JavaBotOP12mo ago
This post has been reserved for your question.
Hey @oSumAtrIX! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
szatkus
szatkus12mo ago
Kotlin has its own stdlib, so for the most of the time a target version isn't that important. If Android supports 11 you can keep it that way. For non-Android projects I would just take the latest LTS.
dan1st
dan1st12mo ago
If you compile something for Java 11, it typically also runs with Java 21 but if you want to use Java 21 library features, you need Java 21 or later IIRC most Kotlin features work with Java 8 or later then you need to compile for JDK 21 What do you count as a language feature? Language features don't compile to bytecode. Source code compiles to bytecode ok so you are talking about syntax
szatkus
szatkus12mo ago
Are you using Kotlin or Java? I'm confused.
dan1st
dan1st12mo ago
if you want to use Java N syntax features, you need to compile to Java N or newer same for library features ? Var is a special case. It doesn't work for most features. The target version must be greater than or equal to the source version
szatkus
szatkus12mo ago
Kotlin has val and var, you don't need to worry about the underneath version of Java. Also Android has first class support for Kotlin, so I don't see any reason to use Java.
dan1st
dan1st12mo ago
The specification tells you what is valid Java code. If you compile for Java 11, you can only use valid Java 11 code. var was already in Java 11. But that doesn't apply to all language features. code that is valid by the Java language specification of JDK 11 You can compile to Java 8 bytecode but that doesn't allow you to use Java 21 features Language features also require (in almost all cases) library features and these libraries aren't available in older versions For example if you want to use records, you need java.lang.Record to be available which isn't the case if you run it with older Java versions ? Similarly, sealed classes require the corresponding bytecode field because all records must extend Records, there are semantic things about records (e.g. reflection is different) I think you fundamentally misunderstand how Java works javac compiles for a JVM so the code is for a specific JVM Because records aren't just syntax it does Records have specific things that are enforced at runtime records are deserialized differently which wasn't supported in older Java versions no Records are not about syntax ? I have no idea why you make statements about java.exe Records are a language and VM feature Which question?
szatkus
szatkus12mo ago
Being able to compile targeting a much older version isn't that important in practice. If you need it for one reason or another use Kotlin.
dan1st
dan1st12mo ago
depends on Kotlin Other JVM languages can use Java records, yes.
szatkus
szatkus12mo ago
There's java.lang.Integer. If for some reason Integer were introduced in later version of Java you would have the same problem.
dan1st
dan1st12mo ago
Whether Kotlin supports it is another story records aren't about a keyword yes but the feature of records isn't just syntax. It's a language and VM feature You can only use java.lang.Record if that class is available The JLS sais that all records must extend java.lang.Record No. It's a special type of classes.
szatkus
szatkus12mo ago
In theory it could be possible to attach the Record class to the result code, just like Kotlin does it with its own stdlib, but I very doubt anyone would put their time to make it possible.
dan1st
dan1st12mo ago
The libraries and the VM belong together
szatkus
szatkus12mo ago
Record, lol.
dan1st
dan1st12mo ago
If you have a JDK N VM, you need JDK N libraries The VM needs libraries. Like String or Thread as obviously obvious examples ok so which language feature? What's your definition of backwards compatible?
szatkus
szatkus12mo ago
Java is backwards compatible where it counts.
dan1st
dan1st12mo ago
var is specified in the Java 10 specs. Android isn't Java.
szatkus
szatkus12mo ago
There's just a reasonable assumption that people in general don't need to compile their to much older version, and if they do they are ready to make some sacrificies.
dan1st
dan1st12mo ago
If you are willing to break the spec and write your own compiler, yes
szatkus
szatkus12mo ago
Do what Google recommends and use Kotlin.
dan1st
dan1st12mo ago
no Features are unimplemented by default
szatkus
szatkus12mo ago
That's great. I use it at my job as well, I like the language.
dan1st
dan1st12mo ago
Because it wasn't available in Java 8 it's there since 10 IIRC
szatkus
szatkus12mo ago
For what? Oh, you mean the block in Gradle.
dan1st
dan1st12mo ago
Maybe but it would - be an effort that isn't worth it just for var - rely on which version you are compiling with
szatkus
szatkus12mo ago
I don't know much about Android, but it's been always a bit backward, yeah? If it only supports Java 11 set it to 11 and don't worry.
dan1st
dan1st12mo ago
It wouldn't have been possible without major changes to the spec
szatkus
szatkus12mo ago
Because Kotlin is compiled to Java bytecode.
dan1st
dan1st12mo ago
You haven't really asked questions that haven't been answered. You mainly made statements saying your opinion is different from what Java does You can set the target higher than the source
szatkus
szatkus12mo ago
Probably something related to how Gradle extensions are stacked on each other. I don't have an answer to that. It's just 4 lines of code.
dan1st
dan1st12mo ago
You need to set the target to the version that's included/listed in the class file. As I already said, you need to have target >= source which one? idk about what Kotlin requires. I don't think Kotlin has a thing for Java's --source
szatkus
szatkus12mo ago
What happens if you remove that? Oh, I have Android Studio apparently.
dan1st
dan1st12mo ago
sourceCompatibility refers to javac's --source. This means "The source code should be compiled such that it adheres to the language spec of version N". targetCompatibility refers to javac's --target. This corresponds to an integer included in the class files. The target version must be greater than or equal to the source version. After all, if you compile something with Java 21, it probably doesn't work on 11. Also, there is no reason to use these options any more. --release is the preferred option. then target must be 21 or later or javac rejects it or EJC if you use that You could use a keyword in a variable name
szatkus
szatkus12mo ago
Compatibility with older versions of Android.
dan1st
dan1st12mo ago
For example if you wrote a Java 2 application and had int enum = 1337;. This wouldn't work with Java 6. Unless you did --source 1.2 or similar. Well I'm sure many people did before enums were introduced or int default = 123; If you originally wrote Java 7 code and that old Java 7 code had int default = 123; in it
szatkus
szatkus12mo ago
Well, I've just created a project targeting Andoird 5.0 and it's set to Java 8.
dan1st
dan1st12mo ago
then you could still compile it with JDK 8 by saying --source 7 --target 8 for being able to use newer Java language and platform features You can still use newer libraries I think And you might want to have Java 21 on your machine and use it to compile Java 8 code. This works with --release 8 (or the old --source 8 --target 8) idk correct for what? Well I don't know what exactly you mean. Specifying source and target isn't just for breaking changes. It makes sure all people in the project are compiling with the same baseline (again, --release is better) I don't think you need sourceCompatibility for that. I doubt kotlinc has a --source for Java
szatkus
szatkus12mo ago
I try to play with those settings and I have weird errors. Kotlin libraries aren't compatible with older versions of Java. That may answer you question.
dan1st
dan1st12mo ago
I think you don't even need targetCompatibility - jvmTarget should already do that unless other tooling accesses it in some way ofc idk about your tooling As I said, these are specific to javac. If you don't use javac, you probably don't need them unless other tooling expects them.
szatkus
szatkus12mo ago
It seems that Kotlin provides libs compatible with jvmTarget version. So the reason why this block is needed is probably because Kotlin relies on the Java plugin to finish its work.
dan1st
dan1st12mo ago
Both of these are arguments for javac. What else did you expect? expectedly ? Which library is involved in what? targetCompatibility is about the --target argument for javac. Similar with --source what about it? --source and --target are only about the classes being compiled. Not about libraries So? What's the question about that? Do you need jvmTarget? If you want to specify what Java versions your Kotlin code should be capable of running with, yes I don't know what you want I think there's some default probably the Java version installed on your machine - meaning it's different for different developers making the result of your compilation unpredictable if you omit it Do you want the result of the compilation to be dependent on the Java version the dev has installed? Note that Kotlin may emit different bytecode with different target versions Well - if you don't add it, then people may use a newer Java version than you and call libraries that aren't available to you then set it to 11 Or if someone compiles it with JDK 21 on their machine, they might get errors yes the java block is only - for Java code in the project (and the class files resulting from it) - other tooling reading that part (whatever that may be)
JavaBot
JavaBotOP12mo ago
jvmTarget = '17'
jvmTarget = '17'
minSdk 21
minSdk 21
dan1st
dan1st12mo ago
idk maybe they want something from JDK 17? idk about Android so I can neither confirm nor deny that. As I said, Android isn't Java (it just pretends to be) Java source code* Java refers to the source code, stdlibs (including Swing), VM, tooling and probably also other things
JavaBot
JavaBotOP12mo ago
sourceCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_17
dan1st
dan1st12mo ago
Also I think Android doesn't even care about the class file version anyways..? Because that's part of the Kotlin and Java plugins this isn't specific to Android this isn't even made for Android If you specify a JVM target that's too new (or omit it), it might generate bytecode relying on new things existing which may result into other errors further down the line. As I said: You only need the source and target compatibility if you either have Java code you are compiling or if other tooling expects it to exist/reads it. If nothing else relies on it, probably But there could be something else in your build.gradle that reads it if there's an android {} block, that probably has stuff specifically changing Android things idk what you are doing in your project great You could still use some Gradle plugin that accesses this config. I can't tell you what your Gradle plugins are doing. You could try setting it to both 6 and 22 and see what happens If both of them work and you can run it on the oldest Android version you care about, it should be fine checking versions 6 and 22 is pretty fool proof that would be more of a thing of it either breaking completely or not at all if it doesn't break, there's pretty certainly nothing relying on it in your project if something does break, something relies on these versions tbh I would keep the jvmTarget for the reasons I specified earlier For the source and target compatibility, it's unlikely they are used but idk what these plugins are doing (I think the Kotlin plugin should only use jvmTarget` and the Android plugin should mainly care about what the compiled code looks like) that's why I picked it if something is relying on that, it should fail
JavaBot
JavaBotOP12mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
dan1st
dan1st12mo ago
if something in your build process is relying on the source/target version and you set it to 6, it will fail or actually just remove the Java plugin from the build.gradle and the corresponding configuration Can you show the build.gradle? and if you have multiple such files, include both
JavaBot
JavaBotOP12mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.

Did you find this page helpful?