48 Replies
⌛
This post has been reserved for your question.
Hey @oSumAtrIX! Please useTIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here./close
or theClose 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.
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.
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
Are you using Kotlin or Java? I'm confused.
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
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.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?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.
depends on Kotlin
Other JVM languages can use Java records, yes.
There's
java.lang.Integer
. If for some reason Integer were introduced in later version of Java you would have the same problem.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.
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.
The libraries and the VM belong together
Record, lol.
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?Java is backwards compatible where it counts.
var is specified in the Java 10 specs.
Android isn't Java.
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.
If you are willing to break the spec and write your own compiler, yes
Do what Google recommends and use Kotlin.
no
Features are unimplemented by default
That's great. I use it at my job as well, I like the language.
Because it wasn't available in Java 8
it's there since 10 IIRC
For what?
Oh, you mean the block in Gradle.
Maybe but it would
- be an effort that isn't worth it just for
var
- rely on which version you are compiling withI 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.
It wouldn't have been possible without major changes to the spec
Because Kotlin is compiled to Java bytecode.
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
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.
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
What happens if you remove that?
Oh, I have Android Studio apparently.
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 nameCompatibility with older versions of Android.
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 itWell, I've just created a project targeting Andoird 5.0 and it's set to Java 8.
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 JavaI 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.
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.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.
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)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
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💤
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.
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
💤
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.