Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

packageDmg and install run init KCEF error #2

Closed
LiuPack opened this issue Jan 18, 2024 · 7 comments
Closed

packageDmg and install run init KCEF error #2

LiuPack opened this issue Jan 18, 2024 · 7 comments

Comments

@LiuPack
Copy link

LiuPack commented Jan 18, 2024

InstallationDirectory
at dev.datlag.kcef.KCEFException$installationDirectory.<clinit>(KCEFException.kt)at dev.datlag.kcef.KCEFBuilder.install$kcef(KCEFBuilder.kt:192)at dev.datlag.kcef.KCEF$init$installResult$1.invokeSuspend(KCEF.kt:105)at dev.datlag.kcef.KCEF$init$installResult$1.invoke(KCEF.kt)at dev.datlag.kcef.KCEF$init$installResult$1.invoke(KCEF.kt)at dev.datlag.kcef.common.ExtendCoroutineKt$suspendCatching$2.invokeSuspend(ExtendCoroutine.kt:19)at dev.datlag.kcef.common.ExtendCoroutinekt$suspendCatching$2.invoke(ExtendCoroutine.kt)at dev.datlag.kcef.common.ExtendCoroutineKt$suspendCatching$2.invokelExtendCoroutine.ktat kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264)at dev.datlag.kcef.common.ExtendCoroutinekt.suspendCatching(ExtendCoroutine.kt:16)at dev.datlag.kcef.KCEF.init(KCEF.kt:104)
at dev.datlag.kcef.KCEF.init(KCEF.kt:45)at ComposableSingletons$MainKt$lambda-1$1$1$1$1.invokeSuspend(main.kt:43)at kotlin.coroutines.ivm.internal.BaseContinuationlmpl.resumeWith(Continuationlmpl.kt:33)at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)at kotlinx.coroutines.scheduling.Tasklmpl.run(Tasks.kt:103)at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793at kotlinx.coroutines,scheduling,CoroutineScheduler$Worker,runWorkerlCoroutineScheduler.kt:697)at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

build release dmg ,install and run KCEF.init error

this is my KCEF Init

Window(
        title = "玩 Android",
        icon = painterResource("android_studio.png"),
        state = rememberWindowState(width = 350.dp, height = 700.dp),
        onCloseRequest = ::exitApplication,
    ) {
        window.minimumSize = Dimension(350, 700)
        var restartRequired by remember { mutableStateOf(false) }
        var downloading by remember { mutableStateOf(0f) }
        var initialized by remember { mutableStateOf(false) }
        var failedMsg by remember { mutableStateOf("") }
        LaunchedEffect(Unit) {
            withContext(Dispatchers.IO) {
                KCEF.init(builder = {
                    progress {
                        onDownloading {
                            downloading = max(it, 0f)
                        }
                        onInitialized {
                            initialized = true
                        }
                    }
                }, onError = {
                    failedMsg = it?.stackTraceToString().orEmpty()
                    it?.printStackTrace()
                }, onRestartRequired = {
                    restartRequired = true
                })
            }
        }
        if (restartRequired) {
            Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center, content = {
                Text(text = failedMsg)
            })
        } else {
            if (initialized) {
                App()
            } else {
                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center,
                    content = {
                        Text(text = "Downloading $downloading%")
                    })
            }
        }
        DisposableEffect(Unit) {
            onDispose {
                KCEF.disposeBlocking()
            }
        }
    }

this is my build.gradle

compose.desktop {
    application {
        buildTypes.release.proguard {
            configurationFiles.from("compose-desktop.pro")
        }
        mainClass = "MainKt"
        nativeDistributions {
            targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
            packageName = "玩 Android"
            packageVersion = "1.0.0"
            macOS {
                dockName = "玩 Android"
                setDockNameSameAsPackageName = true
                bundleID = "org.liupack.wanandroid"
                iconFile.set(project.file("launcher/icon.icns"))
            }
            linux {
                iconFile.set(project.file("launcher/icon.png"))
            }
            windows {
                iconFile.set(project.file("launcher/icon.ico"))
            }
        }
    }
}

afterEvaluate {
    tasks.withType<JavaExec> {
        jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
        jvmArgs(
            "--add-opens", "java.desktop/java.awt.peer=ALL-UNNAMED"
        )

        if (System.getProperty("os.name").contains("Mac")) {
            jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
        }
    }
}
@DatL4g
Copy link
Owner

DatL4g commented Jan 18, 2024

Installation Directory

You should provide a proper installation directory. This can depend on the platform the application is running on.

I built a tooling library that can help you.
The most basic (core) module is enough, so all you need is

dependencies {
  implementation("dev.datlag.tooling:tooling:1.1.0") // can be used in commonMain
}

Then you can initialize KCEF like this:

/**
* Your provided app name should not contain whitespaces, as some systems do not support it
* So instead of "My application", do something like "My-application"
*
* Your provided app name should not be localized, so it should not change if the user switches his language
* The app name has to be a constant value
*/
val appWriteableRootFolder = Tooling.getApplicationWriteableRootFolder("your-app-name") ?: File("./")
val kcefInstallDir = File(appWriteableRootFolder, "kcef-bundle")

KCEF.init(
	builder = {
		installDir(kcefInstallDir)
		// all other configuration
	},
	// all other configuration
)

Build Script

Looking at your build script indicates that the browser won't work on Mac if you package it.

The afterEvaluate method is only working in development environments. You can completly remove it and configure it like this:

compose {
	desktop {
		application {
			jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.java2d=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/java.awt.peer=ALL-UNNAMED")

			if (System.getProperty("os.name").contains("Mac")) {
				jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
                jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
			}

			// all other configuration
		}
	}
}

Here is a full working example of the build script: https://github.com/DatL4g/Burning-Series/blob/compose/app/desktop/build.gradle.kts

@LiuPack
Copy link
Author

LiuPack commented Jan 19, 2024

安装目录

您应该提供正确的安装目录。这可能取决于运行应用程序的平台。

我构建了一个可以帮助您的工具库。最基本的(核心)模块就足够了,所以你所需要的只是

dependencies {
  implementation("dev.datlag.tooling:tooling:1.1.0") // can be used in commonMain
}

然后你可以像这样初始化 KCEF:

/**
* Your provided app name should not contain whitespaces, as some systems do not support it
* So instead of "My application", do something like "My-application"
*
* Your provided app name should not be localized, so it should not change if the user switches his language
* The app name has to be a constant value
*/
val appWriteableRootFolder = Tooling.getApplicationWriteableRootFolder("your-app-name") ?: File("./")
val kcefInstallDir = File(appWriteableRootFolder, "kcef-bundle")

KCEF.init(
	builder = {
		installDir(kcefInstallDir)
		// all other configuration
	},
	// all other configuration
)

构建脚本

查看您的构建脚本表明,如果您打包浏览器,它将无法在 Mac 上运行。

该方法仅适用于开发环境。您可以完全删除它并按如下方式配置它:afterEvaluate

compose {
	desktop {
		application {
			jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.awt=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/sun.java2d=ALL-UNNAMED")
            jvmArgs("--add-opens", "java.desktop/java.awt.peer=ALL-UNNAMED")

			if (System.getProperty("os.name").contains("Mac")) {
				jvmArgs("--add-opens", "java.desktop/sun.lwawt=ALL-UNNAMED")
                jvmArgs("--add-opens", "java.desktop/sun.lwawt.macosx=ALL-UNNAMED")
			}

			// all other configuration
		}
	}
}

以下是构建脚本的完整工作示例: https://github.com/DatL4g/Burning-Series/blob/compose/app/desktop/build.gradle.kts

nice! it's working !! thanks!!!

@LiuPack LiuPack closed this as completed Jan 19, 2024
@tomastiminskas
Copy link

Hi @LiuPack I'm facing a similar issue. I could implement KCEF on my compose desktop app and make it to work without issue swhen running from IntelliJ Idea. But when creating the MSI file and installing the app on Windows I'm always getting into onRestartRequired callback on the initialization.

I tried using Tooling.getApplicationWriteableRootFolder but having the same issue. Any ideas on how to solve this?

@DatL4g
Copy link
Owner

DatL4g commented Jan 19, 2024

@tomastiminskas It's required to clean the project before packaging ./gradlew clean or at least delete the kcef-bundle directory.
When this is included in the package it does not have all required permissions to read/write and execute.

Otherwise just try to debug where the package will be saved when you use the Tooling method.
I had no issues while testing it in this full working application: https://github.com/DatL4g/Burning-Series/blob/compose/app/desktop/src/jvmMain/kotlin/dev/datlag/burningseries/InitCEF.kt

@tomastiminskas
Copy link

@DatL4g I copied the implementation of the example project and even when running from IntelliJ Idea I'm getting on the onError callback with the following message:

"The provided archive contains a bad (malicious) file".

Thanks in advance for you help

@LiuPack
Copy link
Author

LiuPack commented Jan 20, 2024

@DatL4g I copied the implementation of the example project and even when running from IntelliJ Idea I'm getting on the onError callback with the following message:

"The provided archive contains a bad (malicious) file".

Thanks in advance for you help

Hi @tomastiminskas This is how I currently handle it. You can control the different installation paths of run debug and packageMsi through a variable. The default File("jcef-bundle") is used under run debug, and Tooling.getApplicationWriteableRootFolder is used under packageMsi.
code in https://github.com/LiuPack/wanandroid/blob/master/composeApp/src/jvmMain/kotlin/main.kt

@tomastiminskas
Copy link

Thanks @LiuPack it worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants