21

I installed OpenJDK-11 as described here. I ran sudo apt install openjfx

My java version:

$ java -version
openjdk version "11.0.3" 2019-04-16
OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu1)
OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu1, mixed mode, sharing)

But still I get ava.lang.NoClassDefFoundError: javafx/application/Application which indicates that the jre cannot find the FX classes.

4 Answers 4

13

You are getting this error because your runtime PATH to javafx is probably incorrect or missing.

Please, follow these steps:

Check the path of JavaFX. (example: /usr/share/openjfx/lib/)

Then run command:

java --module-path $FX-PATH --add-modules javafx.controls -jar sample.jar

where $FX-PATH should be set or replaced with mentioned JavaFX path.

If you need to add more modules, you can specify them in --add-modules parameter.
(--add-modules javafx.controls,javafx.fxml)

1
  • 3
    You might need to add more FX modules to command to be able to run w/out errors, e.g. --add-modules javafx.controls,javafx.fxml,javafx.graphics. You can see list of available modules as far as I can tell from structure of legal folder of downloaded javafx-sdk. Jan 14, 2020 at 2:56
3

Java FX is no longer packaged with the Java runtime. You must download and package the Jar with JavaFX runtime, see https://openjfx.io/openjfx-docs/ in order to learn how best to get this up and running.

2

I recommend you to go with https://openjfx.io/openjfx-docs/ .i am using Eclipse IDE but it works for all IDE

Then you can refer to this global variable when setting the VM options as:

In IDE Right-click on project->Run As -> Run Configuration ->Arguments->VM Arguments

For Windows,

--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml

For Linux,

--module-path /path to javafx/lib --add-modules javafx.controls,javafx.fxml
0

You might be encountering this problem because you're trying to run JavaFX from Kotlin via command line. As Kotlin uses its own URLClassLoader that isn't populated by the underlying JVM's system classloader as parent, JavaFX classes will not be found when JavaFX is present in the underlying JVM (for example because the JVM is Azul Zulu 18 with JavaFX included) implicitly but not explicitly on the classpath.

The workaround is to create your own URLClassLoader with the same URLs as Kotlin's ClassLoader, using the JVM's system classloader as parent, and then use that via Reflection.

Here's an example of how to do that with an additional main() method.

import java.net.URLClassLoader
import javafx.application.Application
import javafx.event.*
import javafx.scene.*
import javafx.scene.control.*
import javafx.scene.layout.*
import javafx.stage.*

class Hello : Application() {
    override fun start(primaryStage: Stage) {
        primaryStage.setTitle("Hello")
        val label = Label()
        label.setText("Hello, world!")
        val root = StackPane()
        root.getChildren().add(label)
        primaryStage.setScene(Scene(root))
        primaryStage.show()
    }
    companion object {
        @JvmStatic
        fun main(vararg args: String) {
            launch(Hello::class.java, *args)
        }
    }
}

fun main(vararg args: String) {
    class Foo
    URLClassLoader((Foo::class.java.getClassLoader() as URLClassLoader).getURLs(), ClassLoader.getSystemClassLoader())
        .loadClass("Hello")
        .getMethod("main", Array<String>::class.java)
        .invoke(null, args)
}

I've tested this with Kotlin 1.7.10 and Azul Zulu 18.0.2.fx on Kubuntu 22.04.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.