JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.36k stars 1.12k forks source link

Unsupported Java 8? #2112

Open soywiz opened 2 years ago

soywiz commented 2 years ago

https://github.com/korlibs/korge-next/runs/6829604895?check_suite_focus=true#step:7:7449

I'm getting this stacktrace when running it with Java8:

e: java.lang.NoSuchMethodError: java.lang.Integer.parseUnsignedInt(Ljava/lang/CharSequence;III)I
    at androidx.compose.compiler.plugins.kotlin.inference.SchemeStringSerializationReader.number(Scheme.kt:342)
file or directory '/Users/runner/work/korge-next/korge-next/korge-compose/src/posixMain/kotlin', not found
    at androidx.compose.compiler.plugins.kotlin.inference.SchemeKt.deserializeScheme$item(Scheme.kt:209)
file or directory '/Users/runner/work/korge-next/korge-next/korge-compose/src/nativeMain/kotlin', not found

Is this intended?

kirill-grouchnikov commented 2 years ago

Compose needs 11 at least. This is documented.

kirill-grouchnikov commented 2 years ago

https://github.com/JetBrains/compose-jb/tree/master/tutorials/Getting_Started#new-project-wizard

soywiz commented 2 years ago

Thanks for the info! Maybe it could check the runtime before and providing a meaningful error when configuring the plugin? Also, is it final the JVM 11 version requirement? Any chance to allow Java8? Since this is Kotlin targeting 1.8 should be easy right?

kirill-grouchnikov commented 2 years ago

Java 11 has been out since 2018

igordmn commented 2 years ago

Supporting Java 8 will add some burden. For example we won't be able to use the new API, which was added in JDK 9-11, and we have to live with the bugs, which were fixed in the newer versions of JDK. JDK 11 is a balance between the need for a lower version and a burden which this support adds.

Maybe it could check the runtime before and providing a meaningful error when configuring the plugin

This check was in the past, probably something is broken, or accidentally removed. We will fix this.

soywiz commented 2 years ago

Oh, that's a pity. The Kotlin compiler still supports Java8, as well as proguard and all the other plugins I was using. So including compose would force users of my libraries to migrate to Java11.

I used to believe that by using Kotlin you could target Java8 and only get APIs available there so avoiding using APIs not available by mistake, and that Kotlin already provide a lot of goodies to make development enjoyable even in Java8. I also thought that Java8 had many patch releases fixing bugs, while still allowing people to using Java 11 or greater if they want.

kirill-grouchnikov commented 2 years ago

Do you have users who are stuck on Java 8 in their environment and can't upgrade to Java 11 or later?

soywiz commented 2 years ago

I believe that some people might be stuck with Java8 because old software and incompatibilities introduced in Java9 (like module visibility and things).

We also have very low level libraries like one for time management or data structures that could be used by potentially any Kotlin developer and some even for other JVM languages.

Also it is more likely that a normal user is able to run a jar built for Java8 than one for Java11 even nowadays.

Unfortunately I don't have specific numbers about how many users would be affected, but sometime ago we published a Java11 version by mistake and some users were affected and reported it not working by incompatible signatures of APIs existing in both versions (ie. some ByteBuffer API).

AlexeyTsvetkov commented 2 years ago

@soywiz please note, that you can target JDK 8 (bytecode & api, not runtime) in your library or application code, JDK 11 is needed:

Also it is more likely that a normal user is able to run a jar built for Java8 than one for Java11 even nowadays.

Is that really a "normal" desktop user? We provide a way to package an app to deb/msi/dmg package, so that end users would not think about JDK at all. They would just use a compose application like any other desktop software. For example, Intellij 2022.2 & all related IDEs runs on JDK 17, while previous versions ran on JDK 11 for a while. I don't think, that end users cared about that, and Intellij has a lot of users. Moreover, using the latest JDKs would be beneficial for end users, as newer JDKs contain new low pause GCs, performance optimisations, bug fixes & security fixes. Some of bug fixes are really important. For example, there is an important accessibility related fix, which only landed in JDK 18 https://github.com/openjdk/jdk18/pull/72 Without it accessibility on Windows with HiDPI display is unusable.

AlexeyTsvetkov commented 2 years ago

This check was in the past, probably something is broken, or accidentally removed. We will fix this

@igordmn we only have a check for creating a distribution. The exception in the issue came from the compiler plugin. The JDK, which runs the compiler, can be configured in multiple ways, so I don't think we can reliably check Kotlin compiler's JDK in Gradle plugin. This can be done in the compiler plugin, but then it should be done by the upstream.

AlexeyTsvetkov commented 2 years ago

BTW despite the requirement in the readme, a compose desktop app might actually run on JDK 8 (if you setup a separate JDK for running the compiler itself). In Compose 1.1 Skiko code, that previously used JDK 9 API for cleaning native objects was replaced with another implementation, which can work on JDK 8. However, some other parts might not work, and I don't know if we can or want to actually support JDK 8 as a runtime target

AlexeyTsvetkov commented 2 years ago

you can target JDK 8 (bytecode & api, not runtime) in your library or application code

Another clarification. Right now 1.2.* Compose Desktop Gradle plugin sets the target bytecode level to 11 by default, however this is not intended, the change was made during Compose 1.1 development, then reverted in 1.1 release, but I forgot to cherry-pick a few commits into the master. In particular this one https://github.com/JetBrains/compose-jb/commit/91fdcb8f9da001a747bc3736dd71543aac6ee53d

hfhbd commented 1 year ago

@soywiz I think, the default target is now fixed with the latest alphas (745+), which uses 1.8 by default if not set.

soywiz commented 1 year ago

@AlexeyTsvetkov Sorry for the delay. I wanted to try to reensure what happened to me, but forgot.

If I compile my code with jvmTarget="1.8" generated classes can be consumed by 1.8, but the Buffer API has some changes in return type that makes old code compatible but not the opposite. Please check the exception I get (compiled with JDK11 with target 1.8, but then later run with java8): Screenshot 2022-07-20 at 10 12 55

And now check the JDK classes:

Screenshot 2022-07-20 at 10 23 09

In JDK 11, Buffer.position is not final, and it is overriden in ByteBuffer, just to return a ByteBuffer. That overload is not available in JDK8, but still compiles. And thus, it is not safe to compile the target 1.8 with other SDK that is not the 1.8.

@hfhbd @AlexeyTsvetkov

https://github.com/korlibs/korge/runs/7420036536?check_suite_focus=true#step:8:6626 I get e: java.lang.UnsupportedClassVersionError: androidx/compose/compiler/plugins/kotlin/ComposeComponentRegistrar has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0 with 697f70cdd88ba88fe77eebda60c7e143f6ad1286bca75017421e93ad84fb87dfR21 : 1.2.0-alpha01-dev748

I'm also getting a strange error in iOS https://github.com/korlibs/korge/pull/485#issuecomment-1189664810 looks like a bug. Is this the repo to report that error, or should I report somewhere else?

kirill-grouchnikov commented 1 year ago

I don't think there's anything to report. They said it may or may not run, and not supported as a target.

soywiz commented 1 year ago

If you mean that Im using 1.7.10 instead of the supported 1.7.0: That error also happened on 1.6.20 and 1.7.0 with other versions. Strangely it runs fine on macos/linux/windows. Only related to ios, but not related to version mismatch

kirill-grouchnikov commented 1 year ago

Kotlin 1.7.10 is not supported. Java 8 is not supported.

soywiz commented 1 year ago

@kirill-grouchnikov the latest error I reported reproduces too on 1.7.0 and Java11

kirill-grouchnikov commented 1 year ago

Should be reported as a separate bug then so that it doesn't get lost in here

AyanoYuugiri commented 1 year ago

Supporting Java 8 will add some burden. For example we won't be able to use the new API, which was added in JDK 9-11, and we have to live with the bugs, which were fixed in the newer versions of JDK. JDK 11 is a balance between the need for a lower version and a burden which this support adds.

Maybe it could check the runtime before and providing a meaningful error when configuring the plugin

This check was in the past, probably something is broken, or accidentally removed. We will fix this.

but the only new API that i found used compiler's bytecode is the auto-generated StringConcatFactory and can be replaced with StringBuilder. I think the java 8 support can be remained, until some use of the new API.