Home » Java » Desktop Java » JavaFX on JDK 11

About Mohammad Rimaz

Mohammad Rimaz
Hossein currently is Software Engineering Student at K.N. Toosi University of Technology and a junior developer. He is a passionate Java programmer, especially interested in GUI programming with JavaFX. His interest includes Big Data, Data Visualization, and Recommender Systems

JavaFX on JDK 11

There was a mixture of feelings about the decoupling of JavaFX from JDK after its 11th release. Many of us felt that now this is the time to say goodbye to JavaFX and switch to another GUI technology, While some others were happy about this circumstance. They believed that decoupling JavaFX from the hands of the Oracle and pursuing its development as an open-source community-driven project is a fantastic opportunity for JavaFX to get even greater. I belong to the latter group. Although I might be worried about the way that JavaFX is going to evolve, I firmly believe with the features that Java Modularity and JPMS brought to us, having a separate JavaFX module is actually fascinating. You can just include that module into your project, create a custom runtime image using the “jlink” tool and BOOM! You just have a fancy modularized project that you can easily ship and run elsewhere.

javafx

You might ask yourself, “How?”. This is basically what I am going to illustrate in this article for you. I am going to show you how you can create a modularized project with Maven.

Environment:

I am using the JDK 11 on Early Access. You can download it from this link: http://jdk.java.net/11/

$ java --version
java 11-ea 2018-09-25
Java(TM) SE Runtime Environment 18.9 (build 11-ea+24)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11-ea+24, mixed mode)

And Apache Maven

$ mvn --version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T23:03:14+04:30)
Maven home: C:\Program Files\Maven\apache-maven-3.5.4
Java version: 11-ea, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-11
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Creating a Project:

My project has 2 modules. One module is logic and the other one is gui that JavaFX related code belongs to it.

Here is the project structure:

javafx11-demo
│   pom.xml
│
├───gui
│   │   pom.xml
│   │
│   └───src
│       └───main
│           └───java
│               │   module-info.java
│               │
│               └───com
│                   └───mhrimaz
│                       └───gui
│                               GUIMain.java
│
└───logic
    │   pom.xml
    │
    └───src
        └───main
            └───java
                │   module-info.java
                │
                └───com
                    └───mhrimaz
                        └───logic
                                CoolLogic.java

Configuring the “pom.xml”s:

This is the content of root pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.mhrimaz</groupId>
    <artifactId>javafx11-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
 
 
    <modules>
        <module>logic</module>
        <module>gui</module>
    </modules>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.ow2.asm</groupId>
                        <artifactId>asm</artifactId>
                        <version>6.2</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
 
    </build>
</project>

Basically, I’m configuring the maven compiler plugin and configuring it for Java 11. Notice that I defined two modules: logic and gui.

For the logic module, pom.xml is as the following:

<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <parent>
        <groupId>com.mhrimaz</groupId>
        <artifactId>javafx11-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
 
    <artifactId>logic</artifactId>
    <version>1.0-SNAPSHOT</version>
    
</project>

Finally, for the gui module we define its pom.xml as the following:

<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <parent>
        <groupId>com.mhrimaz</groupId>
        <artifactId>javafx11-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
 
    <artifactId>gui</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <dependencies>
        <dependency>
            <groupId>com.mhrimaz</groupId>
            <artifactId>logic</artifactId>
            <version>${project.version}</version>
        </dependency>
	<dependency>
	    <groupId>org.openjfx</groupId>
	    <artifactId>javafx-controls</artifactId>
	    <version>11-ea+19</version>
	</dependency>
    </dependencies>
	
 
</project>

Notice that here we have two dependencies, One is the dependency on our logic module, because every gui needs a logic, and the other one is the dependency on javafx-controls module.

Configuring the “module-info.java”s:

If you are not familiar with java modularity concepts I suggest you read my other article about JPMS and modularity.

We should export our “com.mhrimaz.logic” package in order to make it accessible outside our module.

module logic{
    exports com.mhrimaz.logic;
}

For the gui module, we should do several things, First of all, we should require the logic module. Another thing is that we should require javafx.controls module. And finally, we should open the “com.mhrimaz.gui” package for runtime deep-reflection access for the sake of JavaFX. We will end up to the following configuration:

module gui{
    requires logic;
    requires javafx.controls;
    opens com.mhrimaz.gui to javafx.graphics;
}

Last Steps:

In order to compile and build the modules enter this command:

mvn clean install

This will compile and build the modules for you. You will have this hierarchy at the end:

C:.
│   pom.xml
│
├───gui
│   │   pom.xml
│   │
│   ├───src
│   │   └───main
│   │       └───java
│   │           │   module-info.java
│   │           │
│   │           └───com
│   │               └───mhrimaz
│   │                   └───gui
│   │                           GUIMain.java
│   │
│   └───target
│       │   gui-1.0-SNAPSHOT.jar
│       │
│       ├───classes
│       │   │   module-info.class
│       │   │
│       │   └───com
│       │       └───mhrimaz
│       │           └───gui
│       │                   GUIMain.class
│       │
│       ├───generated-sources
│       │   └───annotations
│       ├───maven-archiver
│       │       pom.properties
│       │
│       └───maven-status
│           └───maven-compiler-plugin
│               └───compile
│                   └───default-compile
│                           createdFiles.lst
│                           inputFiles.lst
│
└───logic
    │   pom.xml
    │
    ├───src
    │   └───main
    │       └───java
    │           │   module-info.java
    │           │
    │           └───com
    │               └───mhrimaz
    │                   └───logic
    │                           CoolLogic.java
    │
    └───target
        │   logic-1.0-SNAPSHOT.jar
        │
        ├───classes
        │   │   module-info.class
        │   │
        │   └───com
        │       └───mhrimaz
        │           └───logic
        │                   CoolLogic.class
        │
        ├───generated-sources
        │   └───annotations
        ├───maven-archiver
        │       pom.properties
        │
        └───maven-status
            └───maven-compiler-plugin
                └───compile
                    └───default-compile
                            createdFiles.lst
                            inputFiles.lst

Now how to run? After a lot of searches and digging up, I didn’t come up with a solution to enter a piece of maven command to run the project, So I will do it in an old-fashioned way.

The basic command is the following:

java --module-path <all-of-your-modules-jar-file> -m <which-module>/<and-which-class-of-it-you-want-to-run>

So we are going to do it by our hand, I KNOW, IT DOESN’T SUPPOSED TO BE IN THIS WAY, but keep your expectations low my friend. If anyone knows a better way of doing this I would be appreciated to let me know it. The command is:

java --module-path gui\target\gui-1.0-SNAPSHOT.jar;logic\target\logic-1.0-SNAPSHOT.jar -m gui/com.mhrimaz.gui.GUIMain

It’s obvious that if you run this you will end up seeing this error:

Error occurred during initialization of boot layer
java.lang.module.FindException: Module javafx.controls not found, required by gui

Basically, It says that during the module resolution, it didn’t found the javafx.controls module. It’s simple, you should add all the JavaFX modules to the module path. The final command is the following:

java --module-path gui\target\gui-1.0-SNAPSHOT.jar;logic\target\logic-1.0-SNAPSHOT.jar;"C:\Users\YOURUSERNAME\.m2\repository\org\openjfx\javafx-base\11-ea+19\javafx-base-11-ea+19-win.jar";"C:\Users\YOURUSERNAME\.m2\repository\org\openjfx\javafx-graphics\11-ea+19\javafx-graphics-11-ea+19-win.jar";"C:\Users\YOURUSERNAME\.m2\repository\org\openjfx\javafx-controls\11-ea+19\javafx-controls-11-ea+19-win.jar" -m gui/com.mhrimaz.gui.GUIMain

This command works perfectly fine on my windows machine. If you want the code you can find it on my GitHub.

If you have any question please do not hesitate to ask, I will try my best to answer them.

Finally, Hello World!

javafx

Published on Java Code Geeks with permission by Mohammad Rimaz, partner at our JCG program. See the original article here: JavaFX on JDK 11

Opinions expressed by Java Code Geeks contributors are their own.

(+1 rating, 1 votes)
You need to be a registered member to rate this.
3 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

3
Leave a Reply

avatar
1 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
Roman CoderCossack5JoeHx Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
JoeHx
Guest

If I remember right, wasn’t JavaFX available but separate (i.e. decoupled) in Java 7, then they packaged together in Java 8? It feels as if they’re going back and forth here.

Cossack5
Guest
Cergey Chaulin

That’s Oracle to you.

Roman Coder
Guest
Roman Coder

“It feels as if they’re going back and forth here.”

They are, politically, but not, technically.

It was hard to get people to code to JavaFX in 7 because it wasn’t “just part of the JDK”.

My hope is that this political hurdle can be overcome by the technical advantages of how things are architectured now, so that the end-user doesn’t notice anything wrong, an app that they run with JavaFX will always just run, and not error out, because JavaFX wasn’t bundled in with Java, that they have on their computer already.