1: ã¯ãããĢ
æŦčŗæã§ã¯ Java ãã¤ãŗãšããŧãĢãããĻããĒãį°åĸã§ãEclipse ã§éįēããčĒäŊããã°ãŠã ã .exe ããĄã¤ãĢã¨ããĻåŽčĄã§ãããããĢããæšæŗãį´šäģããĻããžãã
1-1: åččŗæ
åččŗæã¨ããĻį´šäģããĻããč¨äēãčĒãã§ããã ããŽãä¸įĒæŠããã¨æããžããããå°ãä¸å¯§ãĢãã¨ãããã¨ã§ãžã¨ãį´ãããĻããã ããžããã
1-2: åŽæŊį°åĸ
- Windows 11 Pro
- Eclipse 2023-12
- e(fx)clipse 3.8.0
- Oracle OpenJDK 21
- JavaFX 21
- Launch4j 3.50
2: äŊæĨæšæŗ
2-1: ãĩãŗããĢ Eclipse ããã¸ã§ã¯ããĢã¤ããĻ
ãĩãŗããĢ㎠Eclipse ããã¸ã§ã¯ãåã¯ãHelloFXSampleãã§ãã
ããããããHelloFXSample.exeãã¨ããĻåŽčĄã§ãããããĢããĻãããžãã
åäŊã¯ãããŋãŗãã¯ãĒãã¯ãããã "Hello JavaFX World!" ã襨į¤ēããã ããŽåį´ãĒããŽã§ãã
package application;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController {
@FXML private Button button;
@FXML private Label label;
@FXML void onButtonClicked() {
label.setText("Hello JavaFX World!");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
<children>
<Button fx:id="button" layoutX="25.0" layoutY="55.0" mnemonicParsing="false" onAction="#onButtonClicked" text="Button" />
<Label fx:id="label" layoutX="25.0" layoutY="100.0" text="Label" />
</children>
</AnchorPane>
2-2: Eclipse ããã¸ã§ã¯ããŽã¨ã¯ãšããŧã
exe ããĄã¤ãĢåãããããã¸ã§ã¯ããåŗã¯ãĒãã¯ããã¨ã¯ãšããŧãã鏿ããžãã
ãåŽčĄå¯čŊJARããĄã¤ãĢãã鏿ããæŦĄã¸é˛ãŋãžãã
åŋ čĻãĒč¨åŽãčĄããJARããĄã¤ãĢãįæããžãã
| é įŽ | 鏿 |
|---|---|
| čĩˇåæ§æ | Main (ããããããĻãŗãĒãšããĢãã) |
| ã¨ã¯ãšããŧãå | JAR ããĄã¤ãĢãŽäŋåå |
| ãŠã¤ããŠãĒãŧåĻį | įæãããJARãŽéŖãŽãĩãããŠãĢããŧãĢåŋ é ãŠã¤ããŠãĒãŧããŗããŧ |
ã¨ã¯ãšããŧãããã¨ãäŋåå
ãĢ JAR ããĄã¤ãĢã¨å¤é¨ãŠã¤ããŠãĒå
ĨããŽããŠãĢããäŊæãããžãã
2-3: ãĸããĒåŽčĄį¨ãŽæå°æ§æ JRE ãäŊæãã
Java ãŽåŽčĄãĢ㯠JRE (Java Runtime Environment) ãåŋ čĻã§ããéįēį°åĸ㎠JRE ãããŽãžãžãŗããŧããĻãåäŊããžãããé å¸į¨ãĒãŽã§ããĒããšãæå°éãŽãĩã¤ãēãĢãããã¨ãããã¨ã§ãæå°æ§æãŽ JRE ãäŊæããžãã
2-3-1: jdeps ãĢãããĸã¸ãĨãŧãĢãŽäžåéĸäŋãŽįĸēčĒ
jdeps ãŗããŗããäŊŋãããĸã¸ãĨãŧãĢãŽäžåéĸäŋãįĸēčĒããžããjdeps ãŗããŗã㯠JDK ãĢåĢãžããĻãããããããšãéãŖãĻããã°åŠį¨ã§ããžãã
> jdeps --module-path [JavaFX SDK ㎠lib ããŖãŦã¯ããĒ] -s [JAR ããĄã¤ãĢ]
--module-path ãĒããˇã§ãŗãŽ [JavaFX SDK ㎠lib ããŖãŦã¯ããĒ] ãĢã¯ãã¤ãŗãšããŧãĢããĻããã¯ã㎠JavaFX SDK ㎠lib ããŖãŦã¯ããĒãŽããšãæåŽããžãã褿°ããšãæåŽããå ´å㯠; ã§åēåãã°č¯ãããã§ãã
ããĄããŽį°åĸã§ã¯ãSDK ã "C:\pleiades\javafx-sdk-21.0.2" ãĢæ ŧį´ããĻãããŽã§ãæŦĄãŽãããĢæåŽããžããã
> jdeps --module-path "C:\pleiades\javafx-sdk-21.0.2\lib" -s HelloFXSample.jar
HelloFXSample -> java.base
HelloFXSample -> javafx.base
HelloFXSample -> javafx.controls
HelloFXSample -> javafx.fxml
HelloFXSample -> javafx.graphics
æå°æ§æ JRE åãããĢãããŖãĻãjdeps ãŗããŗãã§åæãããé
įŽããæŦĄã§äŊŋã jlink ãŗããŗã㎠--add-modules ãĢæåŽããžãã
- java.base īŧä¸čĻīŧ
- javafx.base
- javafx.controls
- javafx.fxml
- javafx.graphics īŧåččŗæãĢããã¨ãä¸čĻã¨ãŽãã¨īŧ
čĒäŊãĸã¸ãĨãŧãĢãåĢãå ´å
čĒäŊãĸã¸ãĨãŧãĢãåĢãå ´åã¯ãæŦĄãŽãããĒã¨ãŠãŧãåēããããããžããã
> jdeps --module-path C:\pleiades\javafx-sdk-21.0.2\lib -s HelloFXSample.jar
Exception in thread "main" java.lang.module.FindException: Module ImportedSample2 not found, required by JarImportSample2
at java.base/java.lang.module.Resolver.findFail(Resolver.java:892)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:192)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:420)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:254)
at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:607)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:561)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:537)
at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:50)
čĒäŊãĸã¸ãĨãŧãĢãããã¨ããJAR ããĄã¤ãĢãŽã¨ã¯ãšããŧãæãJAR ããĄã¤ãĢãŽéŖãĢįæãããĻãã īŊīŊ_lib ããŠãĢããĢãäžåãã JAR ããĄã¤ãĢããŗããŧãããĻããžãã
ããã§ã īŊīŊ_lib ããĄã¤ãĢã --module-path ãĢ ; ã§åēåãŖãĻæåŽããžãã
ãŗããŗãåŽčĄį°åĸ (PowerShellãĒãŠ) ãĢããŖãĻ㯠; ããŗããŗããŽåēåãã¨ããĻčĒčãããĻããžãããããããĢã¯ãŠãŧãããžãã
> jdeps --module-path "C:\pleiades\javafx-sdk-21.0.2\lib;HelloFXSample" -s HelloFXSample.jar
HelloFXSample -> ImportedSample2 (čĒäŊãĸã¸ãĨãŧãĢ)
HelloFXSample -> java.base (įĄčĻããĻOK)
HelloFXSample -> javafx.base
HelloFXSample -> javafx.controls
HelloFXSample -> javafx.fxml
HelloFXSample -> javafx.graphics (įĄčĻããĻOK)
ããã§ã¯ ImportedSample2 ãĸã¸ãĨãŧãĢãĢãäžåããĻãããã¨ãåãããžãã
- ImportedSample2 īŧåŋ čĻīŧ
- java.base īŧä¸čĻīŧ
- javafx.base
- javafx.controls
- javafx.fxml
- javafx.graphics īŧåččŗæãĢããã¨ãä¸čĻã¨ãŽãã¨īŧ
2-3-2: jlink ãŗããŗããĢãã JRE ãŽäŊæ
jlink ãŗããŗããäŊŋããé å¸ãĸããĒãąãŧãˇã§ãŗå°į¨ãŽ JRE ãäŊæããžãã
> jlink --module-path [JavaFX ㎠jmods ããŖãŦã¯ããĒ] --add-modules java.base,javafx.base,javafx.controls,javafx.fxml --output jre-min
--module-path ãĒããˇã§ãŗãŽ [JavaFX ㎠jmods ããŖãŦã¯ããĒ] ãĢ㯠JavaFX SDK é
å¸ãĩã¤ãã§ããĻãŗããŧãã§ãã jmods ããĄã¤ãĢãŽããŖãŦã¯ããĒãæåŽããžãã
--add-modules ãĒããˇã§ãŗãĢ㯠jdeps ãŗããŗãã§čĻã¤ããŖãäžåéĸäŋãŽãŠã¤ããŠãĒããĢãŗãåēåãã§æåŽããžãã
> jlink --module-path "C:\pleiades\javafx-jmods-21.0.2" --add-modules java.base,javafx.base,javafx.controls,javafx.fxml --output jre-min
ããžãčĄãã° jre-min ããŖãŦã¯ããĒãįæãããĻããžãã
čĒäŊãĸã¸ãĨãŧãĢãåĢãå ´å
čĒäŊãĸã¸ãĨãŧãĢãåĢãå ´åã¯ãæŦĄãŽãããĒã¨ãŠãŧãįēįãããããããžããã
> jlink --module-path c:\pleiades\javafx-jmod
s-21.0.2\ --add-modules java.base,javafx.base,javafx.controls,javafx.fxml,ImportedSample2 --ou
tput jre-min
ã¨ãŠãŧ: Module ImportedSample2 not found
java.lang.module.FindException: Module ImportedSample2 not found
at java.base/java.lang.module.Resolver.findFail(Resolver.java:892)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:129)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:420)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:254)
at jdk.jlink/jdk.tools.jlink.internal.Jlink$JlinkConfiguration.resolve(Jlink.java:217)
at jdk.jlink/jdk.tools.jlink.internal.JlinkTask.createImageProvider(JlinkTask.java:523)
at jdk.jlink/jdk.tools.jlink.internal.JlinkTask.createImage(JlinkTask.java:411)
at jdk.jlink/jdk.tools.jlink.internal.JlinkTask.run(JlinkTask.java:286)
at jdk.jlink/jdk.tools.jlink.internal.Main.run(Main.java:56)
at jdk.jlink/jdk.tools.jlink.internal.Main.main(Main.java:34)
ããĄãã jdeps ãŗããŗããŽã¨ãã¨åæ§ãĢ --module-path ãĢ īŊīŊ_lib ããŠãĢããæåŽããžãããããããĻã --add-modules ãĒããˇã§ãŗãĢčĒäŊãĸã¸ãĨãŧãĢãčŋŊč¨ãããã¨ãåŋããĒããããĢããžãããã
> jlink --module-path "c:\pleiades\javafx-jmods-21.0.2\;HelloFXSample_lib/ImportedSample2.jar" --add-modules java.base,javafx.base,javafx.controls,javafx.fxml,ImportedSample2 --output jre-min
įļããŽæé ã¯ãåãæäŊã§äŊæã§ããã¯ãã§ãã
2-4: JARããĄã¤ãĢãåäŊįĸēčĒãã
PowerShell ãžã㯠cmd.exe ã§ JAR ããĄã¤ãĢãäŋåããããŖãŦã¯ããĒã§äŊæĨããžãã
æŦĄãŽãããĒãŗããŗãã§ãJAR ããĄã¤ãĢããããã°ãŠã ãåŽčĄã§ãããã¨ãįĸēčĒããžãã
> .\jre-min\bin\java.exe -jar [JAR ããĄã¤ãĢ]
> .\jre-min\bin\java.exe -jar HelloFXSample.jar
2-5: EXE ããĄã¤ãĢãĢ夿ãã
夿ãĢ㯠Launch4j ãäŊŋį¨ããžããæŦĄãŽãĩã¤ãããããĻãŗããŧãããã¤ãŗãšããŧãĢããĻãã ããã
http://launch4j.sourceforge.net/
Basicãŋãã§ã¯æŦĄãŽãããĒč¨åŽãčĄããžãã
| č¨åŽé įŽ | č¨åŽå 厚 |
|---|---|
| Output file | åēåãã exe ããĄã¤ãĢåãč¨åŽããžããJRE ããį¸å¯žããšã§æåŽã§ãããã jre-min ããŠãĢããŽæ¨ĒãĢæåŽããžãã |
| Jar | 夿ããJARããĄã¤ãĢãæåŽããžã |
JREãŋãã§ã¯æŦĄãŽãããĒč¨åŽãčĄããžãã
| č¨åŽé įŽ | č¨åŽå 厚 |
|---|---|
| JRE paths | exe ããĄã¤ãĢãåēæēãĢ jre-min ããŖãŦã¯ããĒãį¸å¯žããšã§æåŽããžã |
| Min JRE version | åŋ é é įŽã§ãã21.0.2 ãŽãããĢ Java ãŽããŧã¸ã§ãŗãæåŽããžã |
æåžãĢãįģéĸä¸é¨ãŽæ¯čģããŧ㯠(Build Wrapper) ã§č¨åŽããĄã¤ãĢãäŋåããåŽčĄããžããåŽčĄæãŽãã°ãĢ "Successfully created" ãããã°æåããĻããã¯ãã§ãã
įģéĸä¸é¨ãŽåįããŧ㯠(Test Wrapper) ã§åŽčĄããĻåäŊãįĸēčĒããžãã
äŊæĨããŖãŦã¯ããĒãĢãããjre-min ããŖãŦã¯ããĒ㨠exe ããĄã¤ãĢãé
å¸ãããã¨ã§ããŠãã§ãåŽčĄã§ããžãã
ããĄããŽį°åĸã§ã¯ãlib ããŖãŦã¯ããĒã jar ããĄã¤ãĢã¯åŋ
čĻãããžããã§ããã
3: ããžãīŧčĒäŊãĸã¸ãĨãŧãĢãåĢãããã¸ã§ã¯ãīŧ
JavaFX ããã¸ã§ã¯ããäŊæããã¨ããčĒäŊããã°ãŠã ãã¤ãŗããŧããããã¨ããĻãããžãåããĒããã¨ããããããããžããã
ãããĻãåå ãŽä¸ã¤ãĢãJava 9 ããå°å
Ĩããããĸã¸ãĨãŧãĢãˇãšãã ããããããããžããã
Java 9 ããã¯ãããąãŧã¸ãĒãīŧãããŠãĢããããąãŧã¸īŧã¯éæ¨åĨ¨ã¨ãĒãŖãĻããããããąãŧã¸ãĒã㎠JAR ããĄã¤ãĢãã¤ãŗããŧãããã¨ããžãåããĒããĒããžãã
ããããčĒŦæããå¤ąæãčĩˇãããĒããããĢã¯ãäŊããããŽãããąãŧã¸ãĢæåąãããmodule_info.java ãéŠåãĢæåŽããĻãã ããã
3-1: åįžæé (鿍åĨ¨ãŽãããŠãĢããããąãŧã¸ã§äŊãŖãĻããžã)
ãžããEXE ããĄã¤ãĢåãããã¨ãã Eclipse ããã¸ã§ã¯ãã¯ãæŦĄãŽãããĒ ImportedSample ããã¸ã§ã¯ãã§äŊæããã JAR ããĄã¤ãĢãã¤ãŗããŧãããĻããã¨ããžãã
3-1-1: ã¤ãŗããŧãããã ImportedSample ããã¸ã§ã¯ããŽäŊæ
åäŊã¨ããĻã¯ãmain ãĄãŊãããåŽčĄããã¨ãsayHello ãĄãŊãããŽæģãå¤ "Hello.sayHello" ã襨į¤ēããã ãã§ãã
Eclipse ããã¸ã§ã¯ããŽįļæ
īŧãããŠãĢããããąãŧã¸ãŽįļæ
īŧ
public class Hello {
public static void main(String[] args) {
System.out.println(sayHello());
}
public static String sayHello() {
return "Hello.sayHello";
}
}
ImportedSample ããã¸ã§ã¯ãããäģ㎠Java ããã¸ã§ã¯ãã¨ããĻäŊŋãããããĢ JAR ããĄã¤ãĢåããžãã
JAR ããĄã¤ãĢåãŽæé ã¯ãJavaFX ããã¸ã§ã¯ããŽã¨ãã¨åæ§ã§ãããã¨ã¯ãšããŧãæãŽåĻįãĢãĻãįæããã JAR ãĢåŋ
é ãŠã¤ããŠãĒããããąãŧã¸ãã鏿ããĻãããžãã
æŦĄãŽãããĒãŗããŗãã§ãįæãã JAR ããĄã¤ãĢåäŊãŽåäŊįĸēčĒãčĄããžãã
> java -jar ImportedSample.jar
Hello.sayHello (åēåįĩæ)
3-1-2: ããã¸ã§ã¯ããŽäŊæã¨ JAR ããĄã¤ãĢãŽã¤ãŗããŧã
JAR ããĄã¤ãĢãã¤ãŗããŧããã JavaFX ããã¸ã§ã¯ããäŊæããžãã
äģå㯠JarImportSample ã¨ããååã§äŊæããžããã
JarImportSample ãŽããŠãĢããĢãå
ãģãŠäŊæãã JAR ããĄã¤ãĢããŗããŧããĻãããžããīŧåŗãčĻãã¨ããĒãŧãĢ JAR ããĄã¤ãĢãčŋŊå ãããĻããīŧ
ããã¸ã§ã¯ãåãåŗã¯ãĒã㯠> [ããĢããģããš] > [ããĢããģããšãŽæ§æ] ã鏿ããžãã
æŦĄãŽãããĢããã°ãŠã ãæ¸ãæããJAR ã§ã¤ãŗããŧããã Hello ã¯ãŠãšãåŠį¨ãããã¨ããĻãŋãžãã
package application;
import Hello;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController {
@FXML private Button button;
@FXML private Label label;
@FXML void onButtonClicked() {
label.setText(Hello.sayHello());
}
}
æŽåŋĩãĒãããHello ã¯ãŠãšãčĻã¤ãããĒãã¨č¨ãããĻããžããžãã
3-2: åå
ããĄãã§č§ŖčĒŦãããĻããžããīŧããŋãžãããããžãįč§ŖããĻããžããīŧ
3-3: č§Ŗæąēæšæŗ
3-3-1: ã¤ãŗããŧãããã ImportedSample2 ããã¸ã§ã¯ããŽåäŊæ
ImportedSample ããã¸ã§ã¯ããŽäŊãæšãééãŖãĻããžããŽã§ãImportedSample2 ã¨ããĻäŊãį´ããžãã
æŗ¨æįšã¨ããĻã¯ãæŦĄãŽã¨ããã§ãã
- ã¯ãŠãšã¯ãĒãĢããããŽãããąãŧã¸ãŽä¸ãĢã¤ãããã¨
- äģå㯠application2 ãããąãŧã¸ãĢæåąãããĻããžã (ããã¨åĨå)
- ã¤ãžããHello.java 㯠application2 ããŠãĢããŽä¸ãĢäŊæãããĻããžã
- module-info.java ãäŊæãã
- Eclipse ãĒãããã¸ã§ã¯ãäŊææãŽãĒããˇã§ãŗã§æåŽã§ããžã
- ãĸã¸ãĨãŧãĢåã¯ããããąãŧã¸åã¨åããĢããžãã
Hello.java ãŽå
é ãĢ㯠package application2; ãŽčŋŊå ãåŋ
čĻã§ãã
package application2;
public class Hello {
public static void main(String[] args) {
System.out.println(sayHello());
}
public static String sayHello() {
return "Hello.sayHello2";
}
}
module-info.java ãĢã¯ãapplication ãããąãŧã¸ãŽå Ŧéč¨åŽãæåŽããžãã
module ImportedSample2 {
exports application2;
}
å ãģãŠã¨åæ§ãŽæé ã§ JAR ããĄã¤ãĢãįæãį´ããåäŊã§åäŊįĸēčĒããžãã
> java -jar ImportedSample2.jar
Hello.sayHello2 (åēåįĩæ)
3-3-2: ããã¸ã§ã¯ããŽäŊæã¨ JAR ããĄã¤ãĢãŽã¤ãŗããŧã
ããžãåããããJAR ããĄã¤ãĢã JavaFX ããã¸ã§ã¯ãã§čĒãŋčžŧãŋį´ããĻãŋãžãããã
ããã§ã¯æ°ããäŊãį´ããĻ JarImportSample2 ã¨ããĻããžãã
æŦĄãŽãããĢããã°ãŠã ãæ¸ãæããJAR ã§ã¤ãŗããŧããã Hello ã¯ãŠãšãåŠį¨ããžãã
package application;
import application2.Hello; // application2 ãããąãŧã¸ãĢæåąãį´ãããã
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController {
@FXML private Button button;
@FXML private Label label;
@FXML void onButtonClicked() {
label.setText(Hello.sayHello());
}
}
ããŽæįšã§ã¯ãapplication2/Hello ãåå¨ããĒãã¨č¨ãããĻããžããžãã
module-info.java ãŽä¸čēĢãæŦĄãŽãããĢæ¸ãæããImportedSample2 ãĸã¸ãĨãŧãĢãčĒãŋčžŧããããĢæåŽããžãã
module JarImportSample2 {
requires javafx.controls;
requires javafx.fxml;
requires ImportedSample2;
opens application to javafx.graphics, javafx.fxml;
}
ããã¨ãåããããĢãĒãŖãĻããã¯ãã§ãã



















Comments
Let's comment your feelings that are more than good