How can we bundle and create an executable of your...
# tornadofx
g
How can we bundle and create an executable of your tornadofx application? It looks like there is a project called fxlauncher (https://github.com/edvin/fxlauncher), but I’m searching more for a gradle task or a bash command to do that
r
do you mean thigs like shadow-plugin (
id 'com.github.johnrengelman.shadow' version '4.0.4'
)
g
Yes, could be. After a lot of work I was able to use shadow plugin with the kotlin multiplatform plugin, is this the common approach to create executables for tornadofx? But how can we create .dmg, .exe or .deb, for example?
a
I linked this a little earlier I haven't used it personally, but I'm hoping someone can come back with some results! https://docs.oracle.com/javase/9/tools/jlink.htm#JSWOR-GUID-CECAC52B-CFEE-46CB-8166-F17A8E9280E9
g
Thanks @amanda.hinchman-dominguez, this could be an interesting approach. I’ll be checking it 😃
s
@GarouDan if you do succeed please let me know , I'd love to discuss how you did it ! For me I used fxlauncher with steps outlined in the readme but if you find something more simple and smaller using jlink that'd be cool
a
You cannot use jlink with JDK 8. For JDK 8, you can use Java Packager - https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javapackager.html
@GarouDan @Stephane M There are gradle wrappers on top of Java Packager. check out https://github.com/FibreFoX/javafx-gradle-plugin
👍 1
The makes it super easy to create a Packager, by executing a Gradle task.
a
Oh no sorry guys!!
g
Thanks @abhinay, I’ll be checking this too. @Stephane M, I was trying to use fxlancher yesterday and it looks like it doesn’t work with gradle
5.4
, so I was trying to move with this solution but it didn’t work. I was able to create a fatJar with shadow, but when I run it with
java -jar ...
it opens the java application but no window appears (starting from IntelliJ it works).
Copy code
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
	kotlin("multiplatform")

	id("com.github.johnrengelman.shadow")
	id("java")
//	id("no.tornado.fxlauncher") version "1.0.20"
}

repositories {
	mavenCentral()
}

kotlin {
	jvm() {
	}

	sourceSets {
		val jvmMain by getting {
			kotlin.srcDir("src/main/kotlin")
			resources.srcDir("src/main/resources")

			dependencies {
				implementation(kotlin("stdlib-jdk8"))

				implementation("no.tornado:tornadofx:1.7.18")
			}
		}

		val jvmTest by getting {
			kotlin.srcDir("src/test/kotlin")
			resources.srcDir("src/test/resources")

			dependencies {
				implementation(kotlin("test"))
				implementation(kotlin("test-junit"))
			}
		}
	}
}

tasks {
	withType<KotlinCompile>().configureEach {
		kotlinOptions {
			jvmTarget = "1.8" // JavaVersion.VERSION_1_8
		}
	}
}

tasks.withType<ShadowJar> {
	manifest {
        attributes.put("Main-Class", "com.example.ExampleKt")
	}

	// Assuming just one target.
	val target = kotlin.targets.iterator().next()
	from(target.compilations["main"].output)
	val runtimeClasspath = target.compilations["main"].compileDependencyFiles as Configuration
	configurations = mutableListOf(runtimeClasspath)
}


//fxlauncher {
//	applicationVendor = "My Company"
//	// Base URL where you will host the application artifacts
//	applicationUrl = "<http://fxldemo.tornado.no/>"
//	applicationMainClass = "no.tornado.FxlDemo"
//	acceptDowngrade = false
//	// Optional scp target for application artifacts hosted at the above url
//	deployTarget = "<mailto:w48839@fxldemo.tornado.no|w48839@fxldemo.tornado.no>:fxldemo"
//}
If you have any clues how to make this work, please kindly let me know.
s
we used gradle 4.x and this has been working for us, maybe investigate that?
g
Hum, I’m afraid I’ll not be able to downgrade too much as this, since this project is using several other modules. Either way, thanks for sharing a gradle compatible version, at least for this module I’ll try later 😃
@abhinay, jfx-gradle-plugin looks promissing, I was able to create a jar but I don’t how to use the dependencies from the
kotlin
block, of a multiplatform plugin. Do you know something about this? For example, with fxlauncher I was able to do something like:
Copy code
// Assuming just one target.
    val target = kotlin.targets.iterator().next()
    from(target.compilations["main"].output)
    val runtimeClasspath = target.compilations["main"].compileDependencyFiles as Configuration
    configurations = mutableListOf(runtimeClasspath)
a
@GarouDan Do you want to package kotlin dependencies with the jar?
g
@abhinay, yes, and probably dependencies from other modules that I’m importing with something like
implementation(project(":sleeping_accommodation: "))
a
Why don't you use the shadowJar plugin?
g
I tried, but when executing
java -jar ...
the application started but the application window didn’t appear. If I start from IntelliJ the application window appears normally.
a
Is there an exception in the terminal when you fire the java command?
g
No, no exception =/
Indeed it is very strange
a
What platform are you running on?
Can you upload the jar here?
g
macOs Mojave 10.14.4 (18E226)
Yes, I’ll be able to do that a little later but I’ll be uploading here, thanks 😃
👍 1
It looks like I’ve found a little time now and I was able to generate the jar file:
I would prefer to create the
.dmg
,
.exe
,
.deb
files, but if is not possible it would be ok to be using a fat jar
@amanda.hinchman-dominguez, since you’re using jdk11, how are you distributing your code? Are you using fxlauncher and a recent version of gradle?
a
I personally haven't used fxlauncher... but I've heard it only assumes the user is using jdk8, so I'm not entirely sure if that throws it out the window for us
And I haven't fully migrated over yet but I'll let you know what I find out
I think for windows, you have to sign your files using .iss and .wsf to create an executable. I'm unsure about iOS and Linux.
g
Hum, thanks for the tips 😃
I have been able to create and execute the fatJar now with shadow. The problem was that I was point the ExampleKt class when I should point App as my main class. So now the challenge is to create the executables 😉
javafx-gradle-plugin
I think could help, but I don’t know how to include the dependencies of the kotlin multiplatform there.
fxlauncher
could be a good option but to me doesn’t work with my gradle version
a
Hi @GarouDan! Just try to go through the readme section of
javafx-gradle-plugin
and you should be able to start running and create native bundles in no time.
Copy code
apply plugin: 'javafx-gradle-plugin'

jfx {
    // minimal requirement for jfxJar-task
    mainClass = 'full.qualified.nameOf.TheMainClass'
    
    // minimal requirement for jfxNative-task
    vendor = 'YourName'
}
This is all you need to get started.
g
@abhinay, thanks, unfortunately I have already tried. The jar generated with the
jfxJar
doesn’t contain any dependencies, only the manifest. I think this is because the dependencies are beeing configured in the
kotin {...}
block, since I’m using the
kotlin("multiplatform")
plugin. With the shadowJar I was able to input the correct dependencies with:
Copy code
// Assuming just one target.
    val target = kotlin.targets.iterator().next()
    from(target.compilations["main"].output)
    val runtimeClasspath = target.compilations["main"].compileDependencyFiles as Configuration
    configurations = mutableListOf(runtimeClasspath)
but I couldn’t find a way to do this with
javafx-gradle-plugin
yet. If you have any clues, please kindly let me know.
a
Is your project hosted somewhere?