質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.83%

  • JavaFX

    372questions

    JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

JavaFXのtutorialを使ったjdk-10でのpacage化でつまずいています。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 153
退会済みユーザー

退会済みユーザー

 前提・実現したいこと

javafx.version=10.0.1
javafx.runtime.version=10.0.1+10
javafx.runtime.build=10
でJavaFxのtutorialで下記のページの内容を追って行っています。
https://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm

ファイルの配置は以下の通り
src\fxmlexample
│  module-info.java
└─fxmlexample
FXMLExample.java
FXMLExampleController.java

javac後
mods\fxmlexample
│  module-info.class
└─fxmlexample
background.jpg
FXMLExample.class
FXMLExampleController.class
fxml_example.fxml
Login.css

この状態で
java --module-path mods -m fxmlexample/fxmlexample.FXMLExample
とすると、問題なくアプリが意図通り表示されます。

次に、
jlink --module-path "C:\Program Files\Java\jdk-10\jmods;mods" --add-modules fxmlexample --output output_fxmlexample --launcher fxmlexample=fxmlexample/fxmlexample.FXMLExample

として、output_fxmlexampleにパッケージを出力します。

cd output_fxmlexample\bin
で,作られたfxmlexample.batを起動するとエラーがでます。

 発生している問題・エラーメッセージ

Exception in Application start method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:473)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:372)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:973)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:198)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javafx.fxml.LoadException:
/fxmlexample/fxmlexample/fxml_example.fxml:13

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:105)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:930)

 該当のソースコード

jkd-10.0.1

FXMLExample.java

package fxmlexample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class FXMLExample extends Application {

    public static void main(String[] args) {
        Application.launch(FXMLExample.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

        stage.setTitle("FXML Welcome");
        stage.setScene(new Scene(root, 300, 275));
        stage.show();
    }
}

FXMLExampleController.java

package fxmlexample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.text.Text;

public class FXMLExampleController {
    @FXML private Text actiontarget;

    @FXML protected void handleSubmitButtonAction(ActionEvent event) {
        actiontarget.setText("Sign in button pressed");
    }

}

module-info.java

module fxmlexample{
    exports fxmlexample;
    requires javafx.graphics;
    requires javafx.controls;
    requires javafx.fxml;
}

fxml_example.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>


<GridPane fx:controller="FXMLExampleController" 
                    xmlns:fx="http://javafx.com/fxml" 
                    alignment="center" hgap="10" vgap="10" 
                    styleClass="root">

    <padding>
        <Insets top="25" right="25" bottom="25" left="25"/>
    </padding>

    <Text id="welcome-text" text="Welcome" 
                GridPane.columnIndex="0" GridPane.rowIndex="0" 
                GridPane.columnSpan="2"/>

    <Label text="User Name:" 
                GridPane.columnIndex="0" GridPane.rowIndex="1"/>

    <TextField  GridPane.columnIndex="1" GridPane.rowIndex="1"/>

    <Label text="Password:" 
                GridPane.columnIndex="0" GridPane.rowIndex="2"/>

    <PasswordField fx:id="passwordField" 
                GridPane.columnIndex="1" GridPane.rowIndex="2"/>

    <HBox spacing="10" alignment="bottom_right" 
                GridPane.columnIndex="1" GridPane.rowIndex="4">
                <Button text="Sign In" onAction="#handleSubmitButtonAction"/>
    </HBox>

    <Text fx:id="actiontarget" 
                GridPane.columnIndex="1" GridPane.rowIndex="6"/>

    <stylesheets>
      <URL value="@Login.css" />
    </stylesheets>

</GridPane>

Login.css

root { 
    display: block;
}
.root {
-fx-background-image: url("background.jpg");
}
.label {
    -fx-font-size: 12px;
    -fx-font-weight: bold;
    -fx-text-fill: #333333;
    -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
}

#welcome-text {
   -fx-font-size: 32px;
   -fx-font-family: "Arial Black";
   -fx-fill: #818181;
   -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 );
}
#actiontarget {
  -fx-fill: FIREBRICK;
  -fx-font-weight: bold;
  -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );  
}

.button {
    -fx-text-fill: white;
    -fx-font-family: "Arial Narrow";
    -fx-font-weight: bold;
    -fx-background-color: linear-gradient(#61a2b1, #2A5058);
    -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 );
}

 試したこと

エラーはおそらく、fxml_example.fxmlでcontrollerが読み込めないというメッセージだろうと思いますが、jlinkの前のコマンドラインでのjava実行では問題なく読み込めていますので、jlinkでmodule化された時の不具合のようにおもいますが。

 補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

気づいた問題
(1) FXML

- <GridPane fx:controller="FXMLExampleController"
+ <GridPane fx:controller="fxmlexample.FXMLExampleController"


こちらはjlinkに関係なく致命的な間違いに思えます。実行できるはずはないと思うのですが・・・記載しておられるソースコードは最新ですか?

(2) module-info.java

     ...
     exports fxmlexample;
+    opens fxmlexample;
     ...


自分はjava9のmoduleの仕様がまだちゃんとわかっておらず、かつIDEを使っているためIDEがいつどのようにしてjlinkを起動しているか(または起動してないか)が把握できてません。IDE(IntelliJ IDEA)からだと、上記の(2)の修正をしない限りは実行できませんでした。


情報共有および時間の節約のため(閲覧者が状況を正確に把握するため)以下をお願いします。

(1)コード用のマークダウン
本サイトでプログラムコードを記載するにはマークダウン記法を使う必要があります。https://teratail.com/help#about-markdownを参照の上「コードを入力の」を参考にして質問を編集していただけるようお願いします。

(2)コンパイル手順の詳細の明記
IDEを使っておられないと思います。javacをどのディレクトリーからどのコマンドラインオプションで実行したかの詳細を明記しないことにはどんなクラスファイルが出来ているか曖昧です。IDEを使わないのでしたらjavacの手順詳細の明記は必須だと思います。(本件はあえてIDEを使っておられないのかも知れませんが...)

(3) ソースは正確ですか?
前述のとおり提示しておられるソースでは実行できるはずがない間違いがあるように思えます。提示しておられるソースが最新のものと一致しているか確認願います。

(4) ファイルの配置の表現について
質問文の生のテキストを拝見すると以下のようになってますが、

ファイルの配置は以下の通り
src\fxmlexample
│  module-info.java
└─fxmlexample
        FXMLExample.java
        FXMLExampleController.java


これは以下のようなディレクトリー構成という意味ですよね?

src(directory)
 + fxmlexample(directory)
    + module-info.java
    + fxmlexample(directory)
       + FXMLExample.java
       + FXMLExampleController.java

05/07 11:00追記
(5) 例外のスタックトレースの省略について
特にfxmlローディング時の例外では例外が何段階にもcatchされている関係で重要な情報(大元の例外発生情報)がトレースの下の方にあります。長いためスタックトレースの上の部分のみ記載されていると思いますが、スタックトレースの途中にある重要な点に絞って記載していただくと状況が伝わり易くなります。
特に重要な行は以下ですが、できるだけそれ以外も省略しない方が望ましいです。

  • 例外のメッセージ(行頭に*を付けておきました)
  • その直後のスタックトレース(行頭に+を付けておきました)
  • アプリケーションに含まれるクラス・メソッドのスタックトレース(行頭に@を付けておきました)

例えば以下ですと一番重要な情報はCaused by: ~.InaccessibleObjectException: Unable to make field private ~.Text ~.FXMLExampleController.actiontarget accessible: module fxmlexample does not "opens fxmlexample" to module javafx.fxmlなのです。

*Exception in Application start method
*java.lang.reflect.InvocationTargetException
+        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
         at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
         ...JRE内のメソッドの例外トレースを一部省略
         at java.base/java.lang.Thread.run(Thread.java:844)
*Caused by: javafx.fxml.LoadException:
*/C:/idea2016-3/Jfx10/out/production/Jfx10/fxmlexample/fxml_example.fxml:32

+        at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
         ...JRE内のメソッドの例外トレースを一部省略
@        at fxmlexample/fxmlexample.FXMLExample.start(FXMLExample.java:17)
         ...JRE内のメソッドの例外トレースを一部省略
         ... 1 more
*Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private javafx.scene.text.Text fxmlexample.FXMLExampleController.actiontarget accessible: module fxmlexample does not "opens fxmlexample" to module javafx.fxml
+        at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:337)
         ...JRE内のメソッドの例外トレースを一部省略
         at 
 javafx.fxml/javafx.fxml.FXMLLoader$ControllerAccessor.getControllerFields(FXMLLoader.java:3394)
         ... 17 more
 Exception running application fxmlexample.FXMLExample

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/07 08:39

    早速回答いただきありがとうございます。少し、いじってみます。色々教えて頂きありがとうございました。また、やってみたあとの結果はお知らせします。

    キャンセル

  • 2018/05/07 11:36

    スタックトレースの省略について追記させていただきました(後からの追記で恐縮です)。

    キャンセル

  • 2018/05/07 15:49

    色々ありがとうございました。私の疑問は一つ。コマンドラインで java --module-path mods -m fxmlexample/fxmlexample.FXMLExampleで一旦通っているのに、これをjlinkでjdk-10のpackageに転換したら(と言うことは、成功しているmoduleをpackage化しただけなのに、なぜruntimeのエラーがでるのか?と言う一点でした。

    ご指摘のようなエラーはコマンドラインのjava実行時に出てしかるべきと考えていました。

    fxml_example.fxmlのcontrollerはtutorialでもfxmlexample.FXMLExampleContoroller なので、はじめそうしていたのですが、通らず、試行錯誤で前のfxmlexampl.を外すと、コマンドラインで問題なく動きました。

    今回ひょっとするとと考えたのは、はじめ無名領域(package fxmlexample; を書かずに)でrootディレクトリでプログラムを通してから、別にrootにscrとmodsを作り、通常のpackage宣言を入れてやったのですが、このrootに出来た成果物が災いしているのではないかと考え、すべて削除しました。

    その後javacを行いjavaで走らせると、ご指摘のfxmlexample.FXMLExampleContorollerにしろとの指摘。これを直してjavaで走らせると module-info.javaにopens fxmlexaple; を入れろとの指摘。

    これらを全部直して(KSwordOfHasteさんのご指摘の通り)して、コマンドラインでアプリが動いたのでjlinkに移行し、package内のjavaを使って起動すると、問題なく起動しました。

    コマンドラインのjavaはrootでやっているので、無名領域のFXMLExampleController.classを取り込んだのかも知れません。

    色々お世話様でした。jdk-10から導入された必要最小限のjreを含んだpackageはbatコマンドで起動するので、PCのJAVA_HOMEのJREを必要としないので、結構いいですよ。

    ありがとうございました。

    キャンセル

  • 2018/05/07 16:10 編集

    > このrootに出来た成果物が災いしているのではないかと考え、すべて削除しました。

    なるほど納得です。このようなケースはたまにあるのですが大変混乱しますのでできるだけ慎重にしたいですね。また後からの指摘で申し訳なかったのですが、スタックトレースの省略についても気にしていただければと思います。

    最小限の依存ライブラリーのみを含んで実行という件大変興味を魅かれます。メモリー消費量などどのくらい影響があるか研究したいと思います。
    ---
    PCのJREを必要としないという点重要ですね。native libraryなど含めてパッケージングされるのでしょうからこれもよく確認したいと思います。

    キャンセル

  • 2018/05/07 16:13

    言い忘れましたが本サイトは解決済みQ&Aも情報共有のため見やすくしておくことが望ましいです。ぜひ回答本文の指摘
    (1)コード用のマークダウン
    について対応していただけたらと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaFX

    372questions

    JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。