I made a Kotlin Multiplatform Mobile project using android studio and ran into the following error after importing SQLDelight:
e: This version (1.0.1) of the Compose Compiler requires Kotlin version 1.5.21 but you appear to be using Kotlin version 1.5.30 which is not known to be compatible. Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
I followed this question, however everything they mentioned I had already done correctly.
After going file by file and failing to find where I had declared that version I decided to compare my project to one of the sample projects.
After going through the files again I found that I was using sqlDelightVersion 1.5.2 in my App grade.properties and they used 1.4.2 After changing it from 1.5.2 to 1.4.2 everything compiles.
Question is, why would something like this happen if SQLDelight has nothing to do with jetpack compose?
Jetpack Compose is tightly bound to kotlin compiler version and it probably won't change soon (although, AFAIK, Google is talking to Jetbrains about stabilizing compiler plugin APIs for that NOT to happen. My source on that is a one of the Q&As with compose team).
If you want to use SQLDelight or any other library that is based on some other version of kotlin - you probably have to force proper kotlin version on gradle level (like here)
Related
I have a question regrading RxJava2 support in WhorlWind.
I am converting a project which uses Whorlwind from Rx1 -> Rx2. My current Whorlwind version in my root project gradle is 1.0.1, which according to their github CHANGELOG.MD is the only version.
https://github.com/square/whorlwind/commit/769ad313154df46ce07638dc79bd46ae14e5fbfb
As you can see, the commit above has made the changes to support rxjava2 however I am not able to find a version number to update in my gradle. There must be some key concept I'm missing because how I understand it, the Whorlwind library on my machine will remain at the RxJava1 build until I update the gradle to bring in some new Whorlwind library.
Thanks
I ran into the same issue with that library, what I did to move forward was to use the library the same way that the sample app that they have uses it. By adding the library to your project and referencing the library from there.
See their build.gradle here:
https://github.com/square/whorlwind/blob/master/whorlwind-sample/build.gradle
https://github.com/square/whorlwind/commit/47961437c611abc4ec88c900cdb6621ef6662b1c
In the gradle.properties, Square lists a snapshot of a newer version that supports Rx2. I'm not sure why they don't list it in the ChangeLog or ReadMe
I have some android sdks already written in java.
I am wondering if it is unsafe to rewrite them in Kotlin. I imagine that if the $kotlin_version is different between my code and my customer one, it mays not compile. Am I right ? (same for kotlin android-studio plugin)
Since kotlin for Android is more mature and since Gradle provides tools that helps us implementing dependencies in shorter scope, this question is not relevant anymore.
I have a game that I am working on that uses the LibGDX game framework. Currently the platforms I am targeting are Desktop (PC, Mac, Linux) via a platform independent jar and Android.
The project is hosted at https://github.com/NoxHarmonium/project-whiplash Feel free to take a look if you need to.
The bulk of the code is in a module called core and is written entirely in Kotlin. This module is linked into both the Desktop and Android projects.
This works fine for Android versions 7.1+ and for desktop. For all other versions of Android I get a pile of java.lang.NoClassDefFoundError exceptions on anonymous functions such as this:
val objectObservable = this.observableCache.computeIfAbsent(assetRef, fun(assetRef: AssetRef): Observable<T> {
return Async.start(fun(): T {
...
}).observeOn(this.eventLoopScheduler)
})
Exception Sample:
java.lang.NoClassDefFoundError: com.projectwhiplash.utils.assets.LibGdxDataManager$objectMapFromYaml$objectMapObservable$1
It seems to be caused by an incompatibility with the JVM that Kotlin targets by default (1.8) and the JVM level that older versions of Android support (1.6). I could be wrong but this explains why the latest version of Android works as it supports a later version of the JVM.
The solution should be as simple as forcing Kotlin to emit JVM byte code as version 1.6 but I can't seem to work it out. If you compile Kotlin directly into an Android, this seems to be handled by using the kotlin-android Gradle plugin. Unfortunately I can't use this plugin for the core module because it should not have any Android dependencies.
I tried to override the JVM version using the build settings mentioned at https://kotlinlang.org/docs/reference/using-gradle.html#compiler-options like this:
compileKotlin {
kotlinOptions {
jvmTarget = "1.6"
}
}
However, it did not seem to work no matter which Gradle file I placed it in. In fact I get a "Cannot resolve symbol 'kotlinOptions'" error shown by Intellij when I try it. It is possible that the Kotlin team have changed something and the documentation has not been updated.
I can override the Kotlin settings manually in the Intellij module settings but it gets overridden every time I sync the gradle project and is not a good long term solution. The project is designed to be IDE independent.
Does anyone know how I could set up the core module for max compatibility with older versions of Android?
I currently have the minimum API level set to 9 as this is the current LibGDX default but I'm willing to set this higher if it would be too difficult to target such a low API level.
Edit 1:
I just extracted the jar file produced by the core module and examined the class files using the javap tool.
I ran the following command on a random class file
java -verbose foo.class
and it output text with the following text
...
minor version: 0
major version: 50
...
using this question List of Java class file format major version numbers? I determined that the class file is actually targeting JVM 1.6.
Therefore my original theory is wrong and there is another reason why older Android versions cannot load classes generated by Kotlin lambdas.
It looks like you are using functionality that only exists within the JDK 8 library. Specifically the computeIfAbsent() method on the Map class.
Because of this, even though your code has been compiled down to JVM 1.6 compatibility, the underlying implementation on Android devices is missing that functionality and thus the reason for the NoClassDefFoundError exception you were seeing.
Updated: You can see in the javadoc located at https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function- that the computeIfAbsent() has only been around since JDK 8
I like the Kotlin REPL in Idea / Android-Studio - but as an Android Developer I often run into Stub! problems here. When writing unit-tests I am using unmock to work around this problem. Is there a way to use the same method used there for the Kotlin REPL plugin?
[
All android (and java.lang.*) classes are placeholders in an Android project. This is because android does not use standard java class files to store the compiled code and there is no way to directly run this code on a computer.
You simply can't use the REPL with android classes, they will only exist on an actual device or emulator.
If you do not care about correctness, then you can use Robolectric's implementation of Android by adding it as a dependency to the project.
To make sure it does not collide with the actual implementation you should probably do this with a separate module dedicated to the REPL.
Robolectic's dependency used by unmock is: org.robolectric:android-all:7.1.0_r7-robolectric-0
The problem is that the Kotlin REPL in IDEA is provided by the Kotlin IDEA plugin, which has no notion of Android per se, but only looks at what's in the classpath, which in this case is the android.jar containing the stubs that throw the exception you mentioned.
Using unmock or even the integrated Android support for removing exceptions from the stubs in tests (see here at the end of "Mock Android dependencies") won't work as that only affects your Gradle build.
The only solution I can think of is to either open an issue on the Kotlin tracker or dig through the source code of the REPL function in the Kotlin plugin and send a Pull Request.
This message appears on project sync.
I've tried to clean and rebuild the project, but no success.
I'm using latest plugin version 0.12.275, "org.jetbrains.kotlin:kotlin-gradle-plugin:0.12.213" and "org.jetbrains.kotlin:kotlin-stdlib:0.12.213"
I've tried with the stable version 0.12.200 for both plugin and library, but I get the same error.
I'm using Android Studio AI-141.1972460 (canary channel).
Looks like the problem was in my *.aar lib, that was included in the project - it was compiled with an old version of Kotlin. I've upgraded the libary to the latest Kotlin version and it works now.
This issue was resolved with the updated library as mentioned by #ookami.kb
About the error message...
The "unsupported format" error comes when the ABI version number of the class files created by Kotlin does not match the expected used by the Kotlin compiler. This is no longer an issue with Kotlin 1.0 Betas since the ABI number will not change again for 1.0. But, there will be one forced recompile at 1.0 release candidate to ensure no old compiler bugs affect libraries or code and everything is rebuilt clean. Afterwards no issues such as this will exist.
Therefore if a library is not up to date with the same ABI, or hits this last "1.0 recompile" you may run into a similar error. The solution is always to find the updated library.
More about this in the Kotlin 1.0 Beta 4 announcement "What's Next" section:
After the Beta period is over, there will an RC and then 1.0.
We would really like to make sure that no code compiled with
pre-release versions of Kotlin are kept around after 1.0, so the RC
compiler will force recompilation of all the old code. We will
coordinate with library maintainers outside JetBrains to make sure
that all the widely-used libraries will be recompiled in time.
We’ll also take the opportunity to remove some legacy at this point:
remove all the deprecations that we have accumulated in the process of evolving our libraries,
remove all the deprecations from the generated code (you might not have heard of those, but they exist!),
get rid of some legacy bytecode peculiarities that were found during the beta,
move some of the stdlib code around so that the packages there have
more structure.
After that point, the only compatible changes to the
standard library are deprecations and additions (this does not include
reflection APIs). We are running an open review for the library API to
make sure we haven’t missed anything important.
This is Kotlin bug with new plugin version