OpenJFX11 + OpenJDK11 + Maven で JavaFX を動かす
前回のエントリーはOpenJFXとOpenJDKでJavaFXを動かそうというものでした。
でも、OpenJFX SDKにパスを通さなくてはいけないなど、ちょっとめんどうだったのもたしか。
そんなおり、GluonのJoahn VosさんがOpenJFXをMavenでも使えるようにプルリク出してくれました。
この結果、Maven CentralにOpenJFXが登録されました!!
さっそく使ってみましょう。
サンプルコードはこちら。
package net.javainthebox.hello; import javafx.application.Application; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.stage.Stage; public class Hello extends Application { @Override public void start(Stage stage) throws Exception { var label = new Label("Hello, JavaFX + Maven!"); label.setAlignment(Pos.CENTER); var scene = new Scene(label, 200, 50); stage.setScene(scene); stage.show(); } public static void main(String... args) { launch(args); } }
さて、これをコンパイル、実行するための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>net.javainthebox</groupId> <artifactId>hello</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>10</maven.compiler.source> <maven.compiler.target>10</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>11-ea+19</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <release>11</release> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <executions> <execution> <goals> <goal>java</goal> </goals> </execution> </executions> <configuration> <mainClass>net.javainthebox.hello.Hello</mainClass> </configuration> </plugin> </plugins> </build> </project>
このサンプルではjavafx.controlsモジュールを使用しているので、dependencyにはjavafx.controlsを指定しています。Maven Centralではモジュールのピリオドをハイフンで置き換えた名前になっています。
javafx.controlsはjavafx.graphics、javafx.baseに依存しているので、それらも自動的にロードされます。
これ以外にjavafx.fxml、javafx.media、javafx.swing、javafx.webモジュールもちゃんと登録されています。
では、まずはコンパイルしてみましょう。
C:\hello>mvn clean compile [INFO] Scanning for projects... [INFO] [INFO] -----------------------< net.javainthebox:hello >----------------------- [INFO] Building hello 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello --- [INFO] Deleting C:\Users\yuichi\Desktop\hello\target [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory C:\Users\yuichi\Desktop\hello\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ hello --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to C:\Users\yuichi\Desktop\hello\target\classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.103 s [INFO] Finished at: 2018-07-25T21:44:22+09:00 [INFO] ------------------------------------------------------------------------ C:\hello>
あっさり成功しました。もちろん、初回はモジュールのダウンロードがあるはずです。
では、実行してみましょう。
C:\hello>mvn exec:java [INFO] Scanning for projects... [INFO] [INFO] -----------------------< net.javainthebox:hello >----------------------- [INFO] Building hello 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ hello ---
ここまで表示されれば、フレームが表示されているはずです。
OpenJFX SDKを使うよりは、とても簡単にJavaFXのアプリケーションを書けるようになりました。
ところで、JavaFXはネイティブライブラリが必要です。Maven Centralを見てみると、やっぱりプラットフォームごとに分けられてました。下のリンクはjavafx.graphicsのものです。
Central Repository: org/openjfx/javafx-graphics/11-ea+19
pom.xmlを見てみると、プラットフォームによって該当するJARファイルも依存があるように書かれてますね。
現状の問題点
Mavenで実行するとき、exec:javaであれば問題ないのですが、exec:execで別プロセスとして実行させると以下のようなメッセージを出して、実行ができません。
C:\Users\yuichi\Desktop\hello>mvn exec:exec [INFO] Scanning for projects... [INFO] [INFO] -----------------------< net.javainthebox:hello >----------------------- [INFO] Building hello 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- exec-maven-plugin:1.6.0:exec (default-cli) @ hello --- エラー: JavaFXランタイム・コンポーネントが不足しており、このアプリケーションの実行に必要です [ERROR] Command execution failed. org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1) at org.apache.commons.exec.DefaultExecutor.executeInternal (DefaultExecutor.java:404) at org.apache.commons.exec.DefaultExecutor.execute (DefaultExecutor.java:166)
ロードされたクラスを調べてみたのですが、Applicationクラスはロードされているものの、その他のJavaFXに関連するクラスがロードされていません。もうちょっと調べてみようと思ってます。