How can I modify the default configuration file generated by Gradle (command-line) to build a desktop app using Compose

Hi, tried to build a simple “Hello World” (desktop) app with the following procedure:

https://www.jetbrains.com/help/idea/compiling-applications.html#compilation_output_folders

but had no success using the IDE to build jar files.

On the other hand, using the following procedure (using Gradle on the command-line)

https://docs.gradle.org/current/samples/sample_building_kotlin_applications.html

I managed to build a command-line app.

So I was wondering if there is a way I can modify the default configuration file generated by Gradle (command-line) to build a desktop app using Compose.

Does somebody have any experience with that? Is there some doc or a tutorial on how to do that?

Alternatively, is there a script for building a basic desktop “hello world” app template/project from the command-line.

I don’t have much experience with Compose, so correct me if I’m wrong, but even if you configure your desktop app using IntelliJ, underneath it creates Gradle project anyway. Just invoke gradle build for your desktop project.

I’m trying to avoid creating projects with an IDE.

If I can create blanks projects from the command-line with a script or a template, it makes it easier to automate the development process. It is more reproducible and less error-prone.

That’s what do with other languages : Go, JavaScript (npm), Crystal, Rust, etc.

Yes, I agree.

In that case Compose provides both empty app templates and many example apps. I guess they are all using Gradle, because Gradle is the main/only build system supported by Compose.

1 Like

Super!

Thanks.

Do you know what the following error point to ? when tryng:

java -jar app.jar
Error: Unable to initialize main class MainKt
Caused by: java.lang.NoClassDefFoundError: androidx/compose/runtime/Composer

Most probably you built a jar file with your own code only, without its dependencies and now you try to execute it as a standalone application. As I told you in another thread, you would have to create a so called “fat jar” if you want to execute it like this.

2 Likes

If you build a command-line app using:

gradle init
gradlew build

it will automatically generate a tar file and a zip file ready for distribution.

Without requiring that you take any additional steps.

What surprised me is that when you create a desktop app using the IDE (IntelliJ) there doesn’t seem to be an option to do the same, i.e. build the app for distribution.

It surprises me, because that’s the point eventually: Build an app to distribute it, so the whole procedure should be as simple and straightforward as possible.

With Go, for instance, it is as simple as:

go mod init MyApp
go get ... //dependencies
go build

I assume you mean Compose Desktop, because there is no such thing as “just desktop application” in Java/Kotlin.

Yes, there is such option and it is described in the documentation very extensively: compose-jb/README.md at master · JetBrains/compose-jb · GitHub . I see there is even an option to produce a fat jar you asked for:

./gradlew packageUberJarForCurrentOS

Note that Compose Desktop internally uses native libraries for its UI, these apps are not pure-Java, so they are not multi-platform, they are less standard and building them is more complicated, at least internally.

2 Likes

Thank you!

Hi, do you know where the jar files containing the imports used in this snippet are located?

I assume they must be somewhere in the IntelliJ app?

mport androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application


@Composable
@Preview
fun App() {
    var text by remember { mutableStateOf("Hello, World!") }

    MaterialTheme {
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        App()
    }
}

Dependencies are downloaded from the internet by Gradle and usually stored somewhere inside ~/.gradle/caches/ directory.

Ctrl+click on a class name and you will see its contents. Then you can see the gradle artifact name in the window title, you can also right click on the class body/tab to find its full path. Or just use ctrl+shift+c to copy it.

Thank you for all your help.
I think I have all I needed to get started now.
I really appreciate.