duqhiqiku
duqhiqiku

Reputation: 51

Why can't JavaFX be packaged with the .jar file?

I had the following error where the json.org dependency was not being included in the final .jar file.

Exception in thread "Thread-2" java.lang.NoClassDefFoundError: org/json/JSONTokener
        at gui.Main.lambda$awake$0(Main.java:91)
        at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.ClassNotFoundException: org.json.JSONTokener
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 2 more

I then learnt that you can add the json.org jar file as an "Extracted Directory" which solved my problem. After doing this I thought I would try to do the same for JavaFX. Upon trying to add it as an "Extracted Directory" I noticed it was already listed there (as shown in the image below).

enter image description here

However, if I try to run the jar file using java -jar [filename].jar, I get Error: JavaFX runtime components are missing, and are required to run this application. I can run it using java -jar --module-path /usr/local/javafx-sdk-11.0.2/lib --add-modules javafx.controls,javafx.fxml [filename].jar but this shouldn't be necessary in theory. I was wondering if anyone knows why this does not work? Thanks.

Note: Packaging JavaFX would be really useful as it means I can just send the .jar file and it will work out of the box without the user needing to setup extra dependencies.

Upvotes: 1

Views: 379

Answers (1)

Cường Lư Quốc
Cường Lư Quốc

Reputation: 338

I remember I have the same issue when packing the JavaFX project. And the solution is building the fat jar (including all dependencies) If you use the maven, you can search 2 keyword: maven-assembly-plugin and maven-dependency-plugin

maven-assembly-plugin will help you build the fat jar file

maven-dependency-plugin will help you copy external jar file (not manage by maven repository)

 <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <mainClass>package.mainclass</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

Upvotes: 1

Related Questions