Recently I've been trying to integrate jetpack compose into an existing project. But I've been facing some project configuration problems.
I have the following compose file:
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@Composable
fun ComposeTestScreen() {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(text = "Hello")
}
}
And the following activity:
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
class ComposeTestActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTestScreen()
}
}
}
If I keep the file ComposeTestScreen.kt
this way, I get the following compile-time failure:
e: org.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during IR lowering
File being compiled: /Users/pvieira/AndroidStudioProjects/fury_isp-sf-android/testapp/src/main/java/com/mercadolibre/android/instore/selling/framework/testapp/features/compose/ComposeTestScreen.kt
The root cause java.lang.RuntimeException was thrown at: org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:49)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException(CodegenUtil.kt:241)
at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException$default(CodegenUtil.kt:236)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invokeSequential(performByIrFile.kt:68)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invoke(performByIrFile.kt:55)
at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invoke(performByIrFile.kt:41)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:29)
at org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase.invoke(CompilerPhase.kt:96)
at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:43)
at org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory.invokeCodegen(JvmIrCodegenFactory.kt:312)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.runCodegen(KotlinToJVMBytecodeCompiler.kt:348)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:123)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:47)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:167)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:53)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:101)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:47)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:485)
at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:131)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.doCompile(IncrementalCompilerRunner.kt:424)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:360)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileNonIncrementally(IncrementalCompilerRunner.kt:242)
at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:98)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execIncrementalCompiler(CompileServiceImpl.kt:625)
at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execIncrementalCompiler(CompileServiceImpl.kt:101)
at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1746)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.RuntimeException: Exception while generating code for:
FUN name:ComposeTestScreen visibility:public modality:FINAL <> () returnType:kotlin.Unit
annotations:
Composable
BLOCK_BODY
CALL 'public final fun Box$default (modifier: androidx.compose.ui.Modifier?, contentAlignment: androidx.compose.ui.Alignment?, propagateMinConstraints: kotlin.Boolean, content: @[Composable] @[ExtensionFunctionType] kotlin.Function1<androidx.compose.foundation.layout.BoxScope, kotlin.Unit>, $mask0: kotlin.Int, $handler: kotlin.Any?): kotlin.Unit [inline] declared in androidx.compose.foundation.layout.BoxKt' type=kotlin.Unit origin=DEFAULT_DISPATCH_CALL
modifier: CALL 'public final fun fillMaxSize$default (fraction: kotlin.Float, $mask0: kotlin.Int, $handler: kotlin.Any?): androidx.compose.ui.Modifier declared in androidx.compose.foundation.layout.SizeKt' type=androidx.compose.ui.Modifier origin=DEFAULT_DISPATCH_CALL
$receiver: GET_FIELD 'FIELD FIELD_FOR_OBJECT_INSTANCE name:Companion type:androidx.compose.ui.Modifier.Companion visibility:public [final,static]' type=androidx.compose.ui.Modifier.Companion origin=null
fraction: COMPOSITE type=kotlin.Float origin=DEFAULT_VALUE
CONST Float type=kotlin.Float value=0.0
$mask0: CONST Int type=kotlin.Int value=1
...
If I keep the file the ComposeTestScreen.kt
other way, as shown below:
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
@Composable
fun ComposeTestScreen() {
Text(text = "Hello")
}
I get the following runtime crash:
E FATAL EXCEPTION: main
java.lang.NoSuchMethodError: No static method setContent$default(Landroidx/activity/ComponentActivity;Landroidx/compose/runtime/CompositionContext;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V in class Landroidx/activity/compose/ComponentActivityKt; or its super classes (declaration of 'androidx.activity.compose.ComponentActivityKt' appears in /data/app/~~TAzH_ZscbUGYQ5oNBBrxqA==/com.mercadolibre.android.isp_sf.testapp-FvFRqtbuvFAOdVrOuaQ2Mg==/base.apk)
at com.mercadolibre.android.instore.selling.framework.testapp.features.compose.ComposeTestActivity.onCreate(ComposeTestActivity.kt:11)
at android.app.Activity.performCreate(Activity.java:8305)
at android.app.Activity.performCreate(Activity.java:8284)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1417)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3626)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3782)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
I've been looking for some solutions to this problem, how to add these fields in gradle. As mentioned here. But it didn't solve me.
This is my project testapp gradle file:
plugins {
id 'mercadolibre.gradle.config.app'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
buildFeatures {
viewBinding true
compose true
}
composeOptions {
kotlinCompilerExtensionVersion "1.4.3"
}
defaultConfig {
applicationId "$libraryGroupId" + ".testapp"
versionCode "$testAppVersionCode".toInteger()
versionName "$testAppVersionName"
}
buildTypes {
debug {
minifyEnabled false
aaptOptions {
cruncherEnabled false
}
}
release {
initWith(buildTypes.debug)
// We need this in true to test after executing ProGuard to check our ProGuard custom rules.
minifyEnabled true
shrinkResources true
}
mds {
// This build type "mds" can NOT be renamed because the keyword is used from our Mobile Distribution System.
debuggable true
signingConfig signingConfigs.debug
minifyEnabled true
shrinkResources true
if (project.hasProperty('mdsAppIdSuffix')) {
applicationIdSuffix "${project.mdsAppIdSuffix}"
}
if (project.hasProperty('mdsVersionNameSuffix')) {
versionNameSuffix "${project.mdsVersionNameSuffix}"
}
}
}
lint {
// TODO: Delete this once play services is updated. Now we need it because play services brings support library 26
disable 'GradleCompatible'
}
packagingOptions {
exclude 'META-INF/ASL2.0'
exclude 'META-INF/LICENSE'
exclude("META-INF/*.kotlin_module")
}
dexOptions.preDexLibraries = true
}
dependencies {
def modules = [
'analytics', 'core', 'congrats', 'congrats_splash', 'destinations',
'di', 'utils', 'facade', 'print_buyer_ticket', 'navigation', 'network',
'notification', 'payment'
]
modules.each { module ->
implementation project(":$module")
}
implementation libs.meli.baseTestApp
implementation libs.meli.countryUtils
implementation libs.meli.commonsLogging
implementation libs.meli.commonsCore
implementation libs.meli.commonsDataDispatcher
implementation libs.meli.configurationManager
// Both authentication libraries are used for the AuthenticationConfigurator
implementation libs.meli.authentication
implementation libs.meli.authenticationTestUi
implementation libs.meli.ui
def composeBom = platform(libs.misc.composeBom)
implementation composeBom
implementation 'androidx.compose.material:material'
implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.compose.ui:ui-tooling'
implementation 'androidx.activity:activity-compose:1.7.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1'
implementation (libs.misc.kotlinStdlib)
// Mercado Pago Front End Configurators
implementation libs.meli.configurationMp.authentication
implementation libs.meli.configurationMp.font
implementation libs.meli.configurationMp.matt
implementation libs.meli.configurationMp.traceability
implementation libs.meli.configurationMp.ui
implementation libs.meli.configurationMp.webkit
}
I also tried to do this gradle configuration without using the compose BOM, in the traditional way by importing the compose libraries, but the same error occurs to me.