1、前言
学习kmp(Kotlin MultiPlatform简称)过程中报了错误,这个报错在直接运行desktop的main方法才会出现,用gradle运行却不会报错,新建的kmp项目也不会出现,我学习的写了一些代码的项目才会出现。
运行main方法主要是需要运行main方法才能debug,gradle不能debug
环境
kmp版本:1.7.0
gradle版本:8.13
kotlin版本:2.1.0
操作系統:win11
ide:IntelliJ IDEA 2024.3.4.1
2、报错
Exception in thread "main" java.lang.ExceptionInInitializerErrorat androidx.compose.ui.scene.skia.WindowSkiaLayerComponent.<init>(WindowSkiaLayerComponent.desktop.kt:53)at androidx.compose.ui.scene.ComposeContainer.createSkiaLayerComponent(ComposeContainer.desktop.kt:344)at androidx.compose.ui.scene.ComposeContainer.access$createSkiaLayerComponent(ComposeContainer.desktop.kt:84)at androidx.compose.ui.scene.ComposeContainer$mediator$2.invoke(ComposeContainer.desktop.kt:141)at androidx.compose.ui.scene.ComposeContainer$mediator$2.invoke(ComposeContainer.desktop.kt:141)at androidx.compose.ui.scene.ComposeSceneMediator$skiaLayerComponent$2.invoke(ComposeSceneMediator.desktop.kt:143)at androidx.compose.ui.scene.ComposeSceneMediator$skiaLayerComponent$2.invoke(ComposeSceneMediator.desktop.kt:143)at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:83)at androidx.compose.ui.scene.ComposeSceneMediator.getSkiaLayerComponent(ComposeSceneMediator.desktop.kt:143)at androidx.compose.ui.scene.ComposeSceneMediator.<init>(ComposeSceneMediator.desktop.kt:144)at androidx.compose.ui.scene.ComposeSceneMediator.<init>(ComposeSceneMediator.desktop.kt:113)at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:130)at androidx.compose.ui.scene.ComposeContainer.<init>(ComposeContainer.desktop.kt:84)at androidx.compose.ui.awt.ComposeWindowPanel.<init>(ComposeWindowPanel.desktop.kt:52)at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:66)at androidx.compose.ui.awt.ComposeWindow.<init>(ComposeWindow.desktop.kt:64)at androidx.compose.ui.window.Window_desktopKt$Window$3$1.invoke(Window.desktop.kt:183)at androidx.compose.ui.window.Window_desktopKt$Window$3$1.invoke(Window.desktop.kt:181)at androidx.compose.ui.window.Window_desktopKt$Window$13$1.invoke(Window.desktop.kt:605)at androidx.compose.ui.window.Window_desktopKt$Window$13$1.invoke(Window.desktop.kt:604)at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2$1.invoke(AwtWindow.desktop.kt:70)at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$2$1.invoke(AwtWindow.desktop.kt:69)at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:82)at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1364)at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:992)at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1013)at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1150)at androidx.compose.runtime.CompositionImpl.composeInitial(Composition.kt:649)at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:635)at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:221)at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:101)at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:728)at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:750)at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find skiko-windows-x64.dll.sha256, proper native dependency missing.at org.jetbrains.skiko.Library.findAndLoad(Library.kt:103)at org.jetbrains.skiko.Library.load(Library.kt:56)at org.jetbrains.skiko.SkiaLayer.<clinit>(SkiaLayer.awt.kt:36)... 45 more
3、修复
3.1、生成skiko-windows-x64.dll
去到desktopMain的main.kt,fun main()方法左侧的绿色运行按钮,点击Run main [desktop],运行一次生成文件。
生成路径是C:\Users\用户名.skiko\一串和摘要差不多的文件夹名
例:
C:\Users\hui\.skiko\ec6bc0f7306786ecca7e44964c7c5c0e40049680f07b151b50515efdfa5bea73
有两个文件skiko-windows-x64.dll和icudtl.dat。icudtl.dat就是报错的需要的sha256文件
3.2、将文件放入程序读取目录
点击右上角的齿轮形状的设置按钮,点击Project Structure,
1、在project tab下,看下当前sdk的是什么
2、在下面的SDKs的tab,查看当前的sdk目录
确认目录后,将skiko-windows-x64.dll和icudtl.dat放入sdk的bin目录下,完成修复
例:
我这边确认目录后,将两个文件放入C:\Users\hui.jdks\jbr-21.0.6\bin,接着就可以
4、排查过程
ide点击控制台的报错行at org.jetbrains.skiko.Library.findAndLoad(Library.kt:103)
接着打个断点,debug运行。
从下面截图看到,94行是关键,判断PathInJvm的文件存在不存在,是windows系统的话,判断jvmFiles目录下是否包含icudtl.dat文件是否存在,让他条件成立接着进入95行即可,所以将skiko-windows-x64.dll和icudtl.dat文件放入当前运行jdk的bin目录下即可。