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.**
Related
In my android application am using MVVM architecture and using koin library for DI.
Below is my Repository class:
class JaiminRepository constructor(
private var remoteDataSource : RemoteDataSource,
private var enrollApiInterface : EnrollApiInterface
) {
...
}
Created module for is as below:
val jaiminRepositoryModule = module {
single {
JaiminRepository(get(),get())
}
}
For this I am getting error as :
Instance creation error : could not create instance for
[Singleton:'com.jaimin.sdk.repository.JaiminRepository']:
org.koin.core.error.NoBeanDefFoundException: |- No definition found
for class:'com.jaimin.api.RemoteDataSource'. Check your definitions!
org.koin.core.scope.Scope.throwDefinitionNotFound(Scope.kt:287)
org.koin.core.scope.Scope.resolveValue(Scope.kt:257)
So I have added factory for RemoteDataSource.
factory {
RemoteDataSource()
}
and finally it look like as below:
val jaiminRepositoryModule = module {
factory {
RemoteDataSource()
}
single {
JaiminRepository(get(),get())
}
}
But still am getting error. What might be the issue? Do I need to do something with EnrollApiInterface also? Please guide. Thanks in Advance.
You have to define all dependencies in the module(or another module), otherwise your repository can't be created. Make sure you also provide the EnrollApiInterface:
val jaiminRepositoryModule = module {
factory<EnrollApiInterface> {
EnrollApiInterfaceImpl()
}
factory {
RemoteDataSource()
}
single {
JaiminRepository(get(),get())
}
}
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.** { *; }
I'm finding this exception related with Moshi sometimes when opening the app:
Caused by java.lang.ArrayIndexOutOfBoundsException: length=33; index=33
at java.util.ArrayList.add(ArrayList.java:468)
at com.squareup.moshi.Moshi$Builder.add(Moshi.java:231)
We initialise a repository in the BaseApplication which, sometimes, results in the mentioned crash when initialising Moshi. I'm finding this error in the app reports but I'm not able to reproduce it. Let's jump to the what we have and see if you might have a clue on it.
This factory is used to create Moshi instances, getting the crash when adding KotlinJsonAdapterFactory:
object MyMoshiConverterFactory {
fun create(setup: (Moshi.Builder.() -> Unit)? = null): Converter.Factory {
val moshi = MoshiUtil.createMoshi()
setup?.let { moshi.it() }
moshi.add(KotlinJsonAdapterFactory()) // Here is the crash!
return MoshiConverterFactory.create(moshi.build())
}
}
Here we have a class where we have all the converters we use. It really has a lot more of converters, but I've removed a few of them for simplicity:
object MoshiUtil {
private val lazyMoshi by lazy {
Moshi.Builder().apply {
add(DateAdapter())
add(DefaultOnDataMismatchAdapter.newFactory(FeedItem::class.java, null))
add(SkipListNullValuesAdapter.createFactory(Element::class.java))
add(SkipListNullValuesAdapter.createFactory(Post::class.java))
add(SkipListNullValuesAdapter.createFactory(MetadataItem::class.java))
add(GeoGeometry::class.java, GeometryAdapter())
}
}
fun createMoshi() = lazyMoshi
}
And finally, in our BaseApplication, we have something like this:
class BaseApplication {
#Override
public void onCreate() {
super.onCreate();
val myService = getMyService(applicationContext)
}
private fun getMyService(appContext: Context): MyService {
val converterFactory = MyMoshiConverterFactory.create()
return Retrofit.Builder().baseUrl(baseUrl).apply {
addConverterFactory(converterFactory)
client(okHttpClientBuilder.build())
}.build().create(MyService::class.java)
}
}
}
So, do you see anything that could be causing it? Do you think it might be a concurrency issue happening at startup when the several places in the app are creating the MoshiUtils object at the same time?. Looking forward to hear from you guys, thanks!
Moshi.Builder is mutable and not thread-safe, so this error you're getting sometimes is a race condition as a result of that. You should call .build() on that base MoshiUtil instance to get an immutable Moshi instance, then make the return value of MoshiUtil.createMoshi be moshi.newBuilder() (creates a Moshi.Builder already configured like the existing Moshi instance), like so:
object MoshiUtil {
private val baseMoshi: Moshi = Moshi.Builder().apply {
// ...
}.build()
fun createMoshi(): Moshi.Builder = baseMoshi.newBuilder()
}
Since every person that calls createMoshi now gets their own instance of Moshi.Builder, there shouldn't be any concurrency problems anymore.
I have a Java application class, I cannot change it to Kotlin. I init Koin like this:
KoinApplication koinApp = KoinApplication.create()
.printLogger()
.modules(
myModule
);
start(koinApp);
My module is created in another file:
#JvmField
val myModule = module {
single { DateUtil(androidContext()) }
factory<ListPresenterContract> { MyListPresenter() }
}
But then when I access this file DateUtil I'm getting this error regarding androidContext():
Caused by: org.koin.android.error.MissingAndroidContextException: Can't resolve Context instance. Please use androidContext() function in your KoinApplication configuration.
at org.koin.android.ext.koin.ModuleExtKt.androidContext(ModuleExt.kt:33)
at koin.MyKoinModulesKt$MyModule$1$1.invoke(MyKoinModules.kt:16)
at koin.MyKoinModulesKt$MyModule$1$1.invoke(Unknown Source:4)
at org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:54)
at org.koin.core.instance.SingleDefinitionInstance.get(SingleDefinitionInstance.kt:40)
at org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70)
at org.koin.core.scope.Scope.resolveInstance(Scope.kt:165)
at org.koin.core.scope.Scope.get(Scope.kt:128)
at view.MyViewerListAdapter$$special$$inlined$inject$1.invoke(Scope.kt:327)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at view.MyViewerListAdapter.getDateUtil(Unknown Source:7)
at view.MyViewerListAdapter.setModelView(MyListAdapter.kt:77)
at view.MyViewerListAdapter.onBindViewHolder(MyViewerListAdapter.kt:45)
at view.MyViewerListAdapter.onBindViewHolder(MyListAdapter.kt:27)
I suspect that it just so happens that my module is initialised before the application class, and gets null for the androidContext. And only when I actually access the file that supposed to have context, it doesn't lazily initialise and I still have the null context. I don't know how to get around that in a Java app class so I removed the context from the module in the meantime.
Based on the latest version 2.0.1 standard
in AppModult.kt
val appContext = module {
single(named("appContext")) { androidContext() }
}
in Application.kt
startKoin {
androidContext(this#App)
androidFileProperties()
modules(listOf(appContext))
}
Create Kotlin klass (JavaKoinApplication.kt)
fun start(myApplication: Application) {
startKoin(listOf(module)) with (myApplication)}
then Call this class in your Java Application Class
JavaKoinApplication.start(this);
I'm getting java.lang.BootstrapMethodError: java.lang.IllegalAccessError: tried to access class kotlin.jvm.internal.DefaultConstructorMarker from class androidx.room.CoroutinesRoom$Companion with the following test, why?
#RunWith(AndroidJUnit4::class)
class DBTest {
#Test
#Throws(Exception::class)
fun basicOperations() = runBlocking {
val context = ApplicationProvider.getApplicationContext<Context>()
val db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java).build()
db.favDao().insertFav(Fav("whatever"))
assertEquals("whatever", db.favDao().getFav("whatever"))
db.favDao().deleteFav(Fav("whatever"))
assertEquals(null, db.favDao().getFav("whatever"))
db.close()
}
}
I pretty much just copied from the docs.
I'm using the latest room-coroutines as there was recent media coverage about it from Google.
As of 3/21/19 a fix was introduced in the snapshot of Robolectric, it should be included in future releases:
https://github.com/robolectric/robolectric/commit/6d246391fdaac92968811bc83e1afb057e6f93a3
The cause was due to an internal annotation on the companion object of CoroutinesRoom class.