I have a kotlin multiplatform project and I need to serialize a class. I have included the following dependency in my commonMain and androidMain and iosMain respectively in my multiplatform gradle file:
//commonMain
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:0.20.0"
//androidMain
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
//iosMain
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:0.20.0"
This is the class I want to serialize:
#Serializable
class Test {
fun toJsonTestClass() = Json.stringify(Test.serializer(), this)
var value1:Double = 0.toDouble()
companion object {
fun buildClass(value1 : Double):Test {
val test = Test()
test.value1 = value1
return test
}
fun fromJsonTestClass(json:String) = Json.parse(Test.serializer(), json)
}
}
And in another class (TrialClass), this is how I am testing it:
val test = Test()
val testToJson = test.toJsonTestClass() //<- This is where the error is pointing to.
println(testToJson)
But when I run it, I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: kotlinx/serialization/json/Json
at Test.toJsonTestClass(Test.kt:28)
at TrialClass.main(TrialClass.kt:4)
Caused by: java.lang.ClassNotFoundException: kotlinx.serialization.json.Json
I get no issues when having the imports in my class, but when running I get the above mentioned error.
Any help or advice will be highly appreciated.
For my case, I did everything right - code & configuration. And gradle clean didn't help, I ended up with the magic Invalidate Caches / Restart from IntelliJ IDEA.
Your class is probably being obfuscated. You have two options:
Add the #Keep annotation above the class:
#Serializable
#Keep
class Teste {
// ...
}...
or add it to your module's proguard:
-keep (path_to_the_class).test.** { *; }
Related
Edit: Found out that MockK is causing this issue. I guess it is duplicating these files when I'm mocking my API request. When I remove MockK and/or Mockito. I do not get these errors. Any ideas?
Getting this error stating that there are these duplicate meta data files. I tried adding the packagingOptions block in my build.gradle file to exclude these files, but then my tests won't run at all. Is there a way to manually remove the duplicates? Where would these files be located? Any help is greatly appreciated. I am lost lol.
Tests:
#RunWith(AndroidJUnit4::class)
class ViewModelTests {
#get:Rule(order = 1)
val testRule = ActivityScenarioRule(MainActivity::class.java)
private lateinit var viewModel: NewsViewModel
private lateinit var repositoryImpl: RepositoryImpl
private val context = InstrumentationRegistry.getInstrumentation().targetContext
#Before
fun setUp() {
val newsDao = NewsDatabase.getDatabase(context).myDao()
val newsApi = mockk<NewsApi>()
viewModel = mockk()
repositoryImpl = RepositoryImpl(newsApi, newsDao)
}
#Test
fun test_empty_database() = runBlocking {
assertEquals(0, repositoryImpl.getNewsFromDatabase.value?.size)
}
}
Error:
Execution failed for task ':app:mergeDebugAndroidTestJavaResource'.
A failure occurred while executing com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
6 files found with path 'META-INF/LICENSE.md' from inputs:
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-params/5.8.2/ddeafe92fc263f895bfb73ffeca7fd56e23c2cce/junit-jupiter-params-5.8.2.jar
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.8.2/c598b4328d2f397194d11df3b1648d68d7d990e3/junit-jupiter-engine-5.8.2.jar
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.8.2/4c21029217adf07e4c0d0c5e192b6bf610c94bdc/junit-jupiter-api-5.8.2.jar
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.8.2/b737de09f19864bd136805c84df7999a142fec29/junit-platform-engine-1.8.2.jar
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.8.2/32c8b8617c1342376fd5af2053da6410d8866861/junit-platform-commons-1.8.2.jar
- /Users/sammorton/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter/5.8.2/5a817b1e63f1217e5c586090c45e681281f097ad/junit-jupiter-5.8.2.jar
Adding a packagingOptions block may help, please refer to
https://developer.android.com/reference/tools/gradle-api/7.3/com/android/build/api/dsl/ResourcesPackagingOptions
for more information
I create an arr of my library module and use it in another application.
On one of the singleton class from my aar I get NoClassDefFoundError for its usage
This is my singleton class
object SharedPrefTask {
fun doSomeWork() {
/////
}
}
This is the class where I use the singleton
class ConfigController(val mContext: Context) {
private var prefTask: SharedPrefTask = SharedPrefTask
fun fetchConfig() {
val configs = prefTask.doSomeWork()
}
}
Is there something which is wrong here?
I get the exception
Fatal Exception: java.lang.NoClassDefFoundError: <clinit> failed for class m0.g; see exception in other thread
at b.a.<init>(ConfigController.kt:2)
The issue was due obsfucation from the obsfucation of proguard
Adding the rule helped resolve this
-keeppackagenames com.exaple.**
I don't know what's wrong with below problem?
Code:
CategoryDAO.kt
#Dao
interface CategoryDAO {
#Query("select * from CategoryDesign")
suspend fun getCategory(): MutableLiveData<List<CategoryDesign>>
}
CategoryDesign.kt
#Entity
data class CategoryDesign (
#PrimaryKey
var categoryDesignID:String,
var designImage:String,
var designTitle:String){
constructor() : this("","","")
override fun toString(): String {
return designTitle
}
}
Press Run App button will show error like below:
error: Not sure how to convert a Cursor to this method's return type (androidx.lifecycle.MutableLiveData<java.util.List<com.squall.searchdesigner.model.CategoryDesign>>).
public abstract java.lang.Object getCategory(#org.jetbrains.annotations.NotNull()
w: [kapt] Incremental annotation processing requested, but support is disabled because the following processors are not incremental: androidx.room.RoomProcessor (DYNAMIC), android.databinding.annotationprocessor.ProcessDataBinding (DYNAMIC).
dependencies:
dependencies {
def room_version = "2.2.3"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
}
It's seems like you can use only LiveData return type. Maybe Room not allows you to use MutableLiveData?
Thank you all.
I used below code and rebuild project and invalidate caches seems solve this problem.
#Dao
interface CategoryDAO {
#Query("select * from CategoryDesign")
fun getCategory(): LiveData<MutableList<CategoryDesign>>
}
I have a separate Android library in a separate project for an Android app. However I link the library directly (referencing the library module directly by path or the generated AAR) I get the following error:
A problem was found with the configuration of task ':app:kaptDevelopDebugKotlin'.
> Cannot write to file '/home/m0skit0/Repos/repo/app-android/app/build/intermediates/data-binding/develop/debug/bundle-bin' specified for property 'dataBindingArtifactOutputDir' as it is a directory.
e: error: cannot access ActivityDeparturesBinding
class file for com.blablabla.databinding.ActivityDeparturesBinding not found
Consult the following stack trace for details.
com.sun.tools.javac.code.Symbol$CompletionFailure: class file for com.blablabla.databinding.ActivityDeparturesBinding not found
* What went wrong:
Execution failed for task ':app:kaptDevelopDebugKotlin'.
This shows just after the task :app:transformDataBindingWithDataBindingMergeArtifactsForDevelopDebug
However the class does exist, with full canonical name. It belongs to the the library and it is correctly auto generated (without any errors) by Android's Data Binding processor on both projects. The library compiles correctly on its own. There's no further stacktrace even if the compilation is run with --stacktrace.
I have tried linking the library with compile, implementation and api, all with the same result.
Gradle version is 4.4.
UPDATE:
Updating to Gradle 5 did not solve the problem. Renaming the XML did not solve the problem.
I've also found that the error happens only when I reference the ActivityDeparturesBinding class in my code, even if the part where it is referenced is never actually called. Only importing it without referencing it does not cause the error.
UPDATE2:
This is the activity that uses the layout:
class DeparturesActivity : BaseVinPlateActivity<DeparturesViewModel, ActivityDeparturesBinding>() {
companion object {
fun getStartIntent(context: Context) = Intent(context, DeparturesActivity::class.java)
}
#Inject
override lateinit var viewModel: DeparturesViewModel
override val layout: Int = R.layout.activity_departures
override fun injectThis(component: ActivityComponent) {
component.inject(this)
}
override fun getToolbarTitleId(): Int = R.string.departures_title
override fun initializeDataBindings(dataBinding: ActivityDeparturesBinding) {
dataBinding.viewmodel = viewModel
}
}
abstract class BaseVinPlateActivity<T: BaseVinPlateViewModel, U: ViewDataBinding> : CompoundsBaseActivity() {
protected abstract var viewModel: T
protected abstract val layout: Int
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == BARCODE_RESULT_CODE_ACTIVITY && resultCode == Activity.RESULT_OK) {
val barcodeResult = data?.getStringExtra(BARCODE_RESULT_ACTIVITY)
viewModel.setBarcodeResult(barcodeResult)
}
}
override fun initializeView() {
super.initializeView()
val dataBinding = inflateDataBinding<U>(layout)
initializeDataBindings(dataBinding)
with (viewModel) {
setBindValidator(Validator(dataBinding))
loadData()
}
}
protected abstract fun initializeDataBindings(dataBinding: U)
}
If I remove the initializeDataBindings() function, the error is gone. Note that commenting only the body of the function is not enough, I had to remove the whole function.
This smells like a compiler/tools bug.
I know it's late but I'd like to say that something similar happened to me, in my case I have a library module which was using a third party library, and then in my app module I'm using dagger for injecting dependencies, and I was getting this issue because, I believe dagger couldn't find this thrid party library's class because it wasn't directly implemented in the app's dependencies. So in my case what got it sorted was to change the way I was adding the third party library into my local library module in order to use api instead of implementation.
We could bypass the compilation error in a couple of ways (there are probably more ways). The best way we came up with is converting the abstract function into an abstract lambda property.
Parent class:
abstract class BaseVinPlateActivity<T: BaseVinPlateViewModel, U: ViewDataBinding> : CompoundsBaseActivity() {
protected abstract val initializeDataBinding: U.() -> Unit
// Rest of code
}
Child class:
class DeparturesActivity : BaseVinPlateActivity<DeparturesViewModel, ActivityDeparturesBinding>() {
override val initializeDataBinding: ActivityDeparturesBinding.() -> Unit = { viewmodel = this#DeparturesActivity.viewModel }
// Rest of code
}
I'm trying to implement Dagger 2 in a test app to learn Clean Architecture and dependancy injection in Kotlin language.
EDIT :
I can compile thanks to #Logain, but I have always the static member problem with Dagger in my singleton (see below my TaskWorker), so I'm looking for how can I fix this error
But i got a problem, my DaggerComponent is well generated when i do a rebuild, but not when i want to run my app for testing, it fails and disappears. It fails with this error :
Error:(21, 29) Unresolved reference: DaggerInjectorComponent
Error:Execution failed for task ':app:compileDebugKotlinAfterJava'.
> Compilation error. See log for more details
While when i do a rebuild, this task is passed correctly
:app:compileDebugKotlinAfterJava
So i don't understand why it fails.
Here is my InjectorComponent :
#Singleton
#Component(modules = arrayOf(ContextDaggerModule::class, LocalStoreDaggerModule::class))
interface InjectorComponent {
fun inject(realmLocalStore: RealmLocalStore)
fun inject(taskWorker: TaskWorker)
}
ContectDaggerModule :
#Module
class ContextDaggerModule (val app: Application) {
#Provides
#Singleton
fun provideContext(): Context = app
#Provides
#Singleton
fun provideApplication(): Application = app
#Provides
#Singleton
fun provideResources(): Resources = app.resources
}
LocalStoreDaggerModule :
#Module
class LocalStoreDaggerModule {
#Provides
#Singleton
fun provideLocalStore(context: Context): LocalStore {
return RealmLocalStore(context)
}
}
I think the problem is caused because I inject dependencies in Object-declarations but all elements are static and Dagger does not appreciate it.
So, i try to hack it with a simple override getter and injecting data but nop.
Here is my "hack" :
object TaskWorker {
// #Inject lateinit var localStore: LocalStore
// Not work cause it's a static variable
var localStore: LocalStore? = null
#Inject
get() = localStore
// some cool function
}
I follow this code and this tutorial
I use these dependencies :
// Dagger2
compile 'com.google.dagger:dagger:2.11'
kapt 'com.google.dagger:dagger-compiler:2.11'
provided 'org.glassfish:javax.annotation:10.0-b28'
Make sure you are using:
kapt {
generateStubs = true
}
Due to some limitations on kapt
Or just try with:
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
You don't need this.
kapt {
generateStubs = true
}
Just apply the plugin:
apply plugin: 'kotlin-kapt'
and add the dependencies:
compile androidDependencies.dagger2
compile androidDependencies.dagger2Android
kapt androidDependencies.dagger2Kapt
sometimes the tasks fail with errors like that. Try to clean and as last resort use invalidate and restart. Most of the times it works.