edvin / tornadofx

Lightweight JavaFX Framework for Kotlin
Apache License 2.0
3.68k stars 272 forks source link

Resource must not be null exceptions occurs when generated jar file is run.When I run the project , it totally fine.I use fxml for resources. #1273

Open Leo-Thura opened 4 years ago

Leo-Thura commented 4 years ago

tornadofx.DefaultErrorHandler uncaughtException SEVERE: Uncaught error java.lang.IllegalStateException: component.javaClass.getResource(resource) must not be null

SchweinchenFuntik commented 4 years ago

describe in more detail namely:

Leo-Thura commented 4 years ago

java.lang.IllegalStateException: component.javaClass.getResource(resource) must not be null at tornadofx.ResourceLookup.url(Component.kt:1304) at tornadofx.FX$Companion$fxmlLocator$1.invoke(FX.kt:114) at tornadofx.FX$Companion$fxmlLocator$1.invoke(FX.kt:88) at tornadofx.UIComponent.loadFXML(Component.kt:1119) at tornadofx.UIComponent$fxml$1.(Component.kt:1113) at tornadofx.UIComponent.fxml(Component.kt:1112) at tornadofx.UIComponent.fxml$default(Component.kt:1112) at view.MainView.(MainView.kt:21) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at java.base/java.lang.Class.newInstance(Class.java:584) at tornadofx.FXKt.find(FX.kt:434) at tornadofx.FXKt.find$default(FX.kt:423) at tornadofx.App.start(App.kt:83) at main.MyApp.start(MyApp.kt:54) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) at java.base/java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277) at java.base/java.lang.Thread.run(Thread.java:834)

I use gradle build system

`class AppLauncher {

companion object {

    @JvmStatic
    fun main(args : Array<String>) {

        MyApp().main(arrayOf())
    }

}

}`

I also use this app launcher class to launch the MyApp application.

The output is shown when I run the generated jar file.But the project perfectly worked.

`plugins { id 'application' id 'org.jetbrains.kotlin.jvm' version '1.3.72' id 'org.openjfx.javafxplugin' version '0.0.9' }

group 'org.example' version '1.0-SNAPSHOT'

repositories { mavenCentral() jcenter() }

javafx { version = "11.0.2" modules = ['javafx.controls', 'javafx.graphics'] }

jar {

manifest {
    attributes('Main-Class': 'main.MyApp')
}

}

dependencies {

implementation "org.jetbrains.kotlin:kotlin-stdlib"
implementation 'no.tornado:tornadofx:1.7.20'
implementation "org.openjfx:javafx:11.0.2"
implementation "org.openjfx:javafx-base:11.0.2"
implementation "org.openjfx:javafx-controls:11.0.2"

implementation 'no.tornado:tornadofx-controlsfx:0.1'

implementation 'org.jetbrains.exposed:exposed-core:0.24.1'
implementation 'org.jetbrains.exposed:exposed-dao:0.24.1'
implementation 'org.jetbrains.exposed:exposed-jdbc:0.24.1'
implementation 'org.jetbrains.exposed:exposed-jodatime:0.24.1'
implementation 'mysql:mysql-connector-java:5.1.48'
implementation 'org.slf4j:slf4j-simple:1.7.21'
implementation 'org.apache.poi:poi:4.1.2'

}

compileKotlin { kotlinOptions.jvmTarget = "1.8" }

compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }` This is my build.gradle file

In main view class , I access the fxml file like this.The fxml file is located under resources directory

`class MainView : View("MainView") {

override val root : BorderPane by fxml("/MainView.fxml")

}`

But jar file worked when I don't use fxml

class MainView : View("MainView") { override val root = borderpane { } }

SchweinchenFuntik commented 4 years ago

MyApp().main(arrayOf())

incorrect launch https://edvin.gitbooks.io/tornadofx-guide/content/part1/3_Components.html

// 
fun main(args: Array<String>) {
  launch<MyApp>(args) // start app JavaFX (TornadoFX)
}
SchweinchenFuntik commented 4 years ago

very similar to https://github.com/edvin/tornadofx/issues/1268

what version of TornadoFX and JavaFX do you have?

https://github.com/edvin/tornadofx/issues/1268#issuecomment-681109682

Leo-Thura commented 4 years ago

Tornadofx : 1.7.20 and Javafx : 11.0.2

SchweinchenFuntik commented 4 years ago

answer above, you need "TornadoFX 2.0-SNAPSHOT" https://github.com/edvin/tornadofx/issues/1268#issuecomment-681426394

Leo-Thura commented 4 years ago

I tried Snapshot version . I still get the same error when I run the generated jar file.

SchweinchenFuntik commented 4 years ago

Have you changed the application launch?

SchweinchenFuntik commented 4 years ago

also make sure you are using the correct version

Leo-Thura commented 4 years ago

Yes . I changed the application launch.

Leo-Thura commented 4 years ago

I'm currently using JDK 11 . Do I need to change to higher JDK?

Leo-Thura commented 4 years ago

` class TestView : View("My View") {

override val root : Parent = FXMLLoader.load(javaClass.getResource("/TestView.fxml"))

}`

When I load fxml using FXMLLOADER , I get new error :-)

tornadofx.DefaultErrorHandler uncaughtException SEVERE: Uncaught error java.lang.NullPointerException: Location is required. at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3230) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3194) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3163) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3136) at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3113) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3106) at main.TestView.(TestView.kt:9) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at java.base/java.lang.Class.newInstance(Class.java:584) at tornadofx.FXKt.find(FX.kt:434) at tornadofx.FXKt.find$default(FX.kt:423) at tornadofx.App.start(App.kt:83) at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) at java.base/java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277) at java.base/java.lang.Thread.run(Thread.java:834)

SchweinchenFuntik commented 4 years ago

I'll try to throw off an example project tomorrow

Leo-Thura commented 4 years ago

Finally I found a solution . May not be a good solution . But it works for me.

` class TestView : View("My View") {

private val url = File("src/main/resources/TestView.fxml").toURI().toURL()
override val root: Parent =  FXMLLoader(url).also { loader -> loader.setController(this) }.load()

@FXML
lateinit var lbl_test : Label

init {

    lbl_test.text = "This is testing string"
}

}`

SchweinchenFuntik commented 4 years ago

here is an example project TornadoFX simple.zip