Shadab Ansari
Shadab Ansari

Reputation: 7070

Tornadofx application not launching

I'm new to JavaFX and TornadoFX but know Kotlin. I am working on new desktop application and was trying TornadoFX. I installed TornadoFX plugin in IntelliJ and create a new TornadoFX project (gradle based). With the template code, when I run the app I get the following error :

Jan 28, 2020 4:06:22 PM tornadofx.DefaultErrorHandler uncaughtException
SEVERE: Uncaught error
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:875)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$147(LauncherImpl.java:157)
    at com.sun.javafx.application.LauncherImpl$$Lambda$49/458209687.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodError: javafx.stage.Window.getProperties()Ljavafx/collections/ObservableMap;
    at tornadofx.FXKt.setAboutToBeShown(FX.kt:663)
    at tornadofx.App.start(App.kt:84)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
    at com.sun.javafx.application.LauncherImpl$$Lambda$52/707342127.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
    at com.sun.javafx.application.PlatformImpl$$Lambda$46/1637506559.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/1602612637.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/2117255219.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

MyApp Class: class MyApp: App(MainView::class, Styles::class)

Styles Class:

class Styles : Stylesheet() {
    companion object {
        val heading by cssclass()
    }

    init {
        label and heading {
            padding = box(10.px)
            fontSize = 20.px
            fontWeight = FontWeight.BOLD
        }
    }
} 

MainView Class:

class MainView : View("Hello TornadoFX") {
    override val root = hbox {
        label(title) {
            addClass(Styles.heading)
        }
    }
}

I'm using java 1.8, kotlin 1.3 and tornadofx 1.7.17 I also tried by creating a new "Application" configuration to run the app.

Any help is appreciated.

Upvotes: 1

Views: 1291

Answers (1)

maroc
maroc

Reputation: 466

The gradle configuration produced by the TornadoFX plugin is obsolete and has a number of problems. Not only because of the older versions selected for kotlin and tornadofx, but also the buildscript method has been deprecated for kotlin applications that use gradle. Additionaly, the gradle version is quite old and must be updated to work with newer Java versions.

To get a running build starting with the demo app created by the TornadoFX wizard and Java 8 do the following:

  1. Make sure you have a Java 8 JDK that includes JavaFX. Most open JDKs such as Adopt OpenJDK do not. The oracle JDK 8 should include Java FX. For open JDKs, I suggest Zulu or Liberica (they have a build for raspery pi). When you download, make sure to select the JDK with Java FX included. For Zulu, you have to select "JDK FX", for Liberica you have to select "Full JDK".
  2. Edit gradle/wrapper/gradle-wrapper.properties and change the gradle-4.4-bin.zip in the URL to gradle-6.3-bin.zip Version 6.3 will work with JDK up to version 14.
  3. If on Mac or Linux, you have to convert the gradlew script to use unix line endings. The one produced by the TornadoFX plugin uses windows new lines "\r\n" which the "sh" interpreter can't handle. On linux, you can use dos2unix command or sed if you don't have dos2unix installed:sed -i 's/\x0D$//' gradlew
  4. Edit build.gradle using the code below. This is the simplest config to build and run the demo app
  5. Execute the gradlew script to build and run
    Mac/Linux: ./gradlew run
    Windows: gradlew.bat run
  6. It's a good idea to update the wrapper
    Mac/Linux: ./gradlew wrapper
    Windows: gradlew.bat wrapper

JDK 8 build.gradle

    plugins {
        // Apply the Kotlin JVM plugin to add support for Kotlin.
        id 'org.jetbrains.kotlin.jvm' version '1.3.70'

        // Apply the application plugin to add support for building a CLI application.
        id 'application'
    }

    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }

    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            url "https://oss.sonatype.org/content/repositories/snapshots/"
        }
    }

    dependencies {
        // Align versions of all Kotlin components
        implementation platform('org.jetbrains.kotlin:kotlin-bom')

        // Use the Kotlin JDK 8 standard library.
        implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'

        // Use the tornadofx
        implementation "no.tornado:tornadofx:1.7.20"
    }

    mainClassName = "com.example.demo.app.MyApp"   

JDK 9+

For JDK 9+, start at step 2 above plus modify the build.gradle to download JavaFX since it was separated from the JDK starting with 9.

Add to the plugins section:

    // Apply the javafx plugin
    id 'org.openjfx.javafxplugin' version '0.0.8'

And then add a javafx section:

javafx {
    version = "13"
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

Finally, change tornadofx version to the 2.0 snapshot

    // Use the tornadofx
    implementation "no.tornado:tornadofx:2.0.0-SNAPSHOT"

At this point the demo app should run. There are some gotchas with running a JDK 9+ version with TornadoFX but you should be able to find those answers in other questions.

Upvotes: 4

Related Questions