You can checkout my whole project on github. I currently don't use any dependency managers in my projects and I would like to keep it that way. I am using a library that I made in java and I am using javaFX for GUI. As the title states I want to make my app a standalone app so someone can run it without having java installed.
I make my jar file like this in VSCode:
And after this I can run my application with .jar file with this command:
java --module-path %JAVAFX% --add-modules=javafx.controls,javafx.fxml -jar match_three_solver.jar
So I try to run this command jdeps -s --module-path %JAVAFX% match_three_solver.jar
to check which packages I have to include in my jlink command and it returns me this error:
Exception in thread "main" java.lang.module.FindException: Error reading module: match_three_solver.jar
at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:351)
at java.base/jdk.internal.module.ModulePath.scan(ModulePath.java:238)
at java.base/jdk.internal.module.ModulePath.scanNextEntry(ModulePath.java:191)
at java.base/jdk.internal.module.ModulePath.findAll(ModulePath.java:167)
at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:521)
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)
Caused by: java.lang.module.InvalidModuleDescriptorException: Main.class found in top-level directory (unnamed package not allowed in module)
at java.base/jdk.internal.module.ModulePath.toPackageName(ModulePath.java:720)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
at java.base/java.util.zip.ZipFile$EntrySpliterator.tryAdvance(ZipFile.java:573)
at java.base/java.util.Spliterator.forEachRemaining(Spliterator.java:332)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at java.base/jdk.internal.module.ModulePath.jarPackages(ModulePath.java:621)
at java.base/jdk.internal.module.ModulePath.lambda$readJar$6(ModulePath.java:653)
at java.base/jdk.internal.module.ModuleInfo.doRead(ModuleInfo.java:311)
at java.base/jdk.internal.module.ModuleInfo.read(ModuleInfo.java:129)
at java.base/jdk.internal.module.ModulePath.readJar(ModulePath.java:652)
at java.base/jdk.internal.module.ModulePath.readModule(ModulePath.java:332)
... 8 more
If I understand this correctly (I don't know really what I am doing cuz I'm doing this for the first time)... I have a non-modular .jar
file so I can't use jdeps
. If I want to use jdeps
command I have to have module-info.java
in my project. My issue is that wherever I create module-info.java
file... the compiler starts screaming errors and it also doesn't recognize javafx
modules:
So if you have any idea how to fix this (if I have to completely restructure the current folder to make it work) please let me know. Also what is the point that I can't use jdeps
without my .jar
file being a modular.
Also I tired to just make my standalone app with this command
jlink --module-path ../jmods;lib/javaFX/lib
--add-modules javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media,javafx.web
--output jreFX2
and run it like this (in its standalone environment) jreFX2\bin\java -jar match_three_solver.jar
... And it gives me this error:
Graphics Device initialization failed for : d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at javafx.graphics@21.0.2/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:283)
at javafx.graphics@21.0.2/com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:253)
at javafx.graphics@21.0.2/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:263)
at javafx.graphics@21.0.2/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:290)
at javafx.graphics@21.0.2/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:162)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:651)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1135)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at javafx.graphics@21.0.2/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:95)
at javafx.graphics@21.0.2/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.base/java.lang.Thread.run(Thread.java:1583)
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:118)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1135)
Caused by: java.lang.RuntimeException: No toolkit found
at javafx.graphics@21.0.2/com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:275)
at javafx.graphics@21.0.2/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:290)
at javafx.graphics@21.0.2/com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:162)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:651)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:409)
at javafx.graphics@21.0.2/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
... 2 more
Any help would be greatly appreciated. Thanks in advance.
The following steps outline the process of creating a custom JRE:
https://adoptium.net/temurin/releases/?os=windows&arch=x64&package=jdk
get OpenJDK21U-jdk_x64_windows_hotspot_21.0.6_7.zip
unzip OpenJDK21U-jdk_x64_windows_hotspot_21.0.6_7.zip
move jdk-21.0.6+7
to C:\TOOLS
final path is C:\TOOLS\jdk-21.0.6+7
JAVA_HOME
SET C:\TOOLS\jdk-21.0.6+7
PATH
ADD C:\TOOLS\jdk-21.0.6+7\bin
https://gluonhq.com/products/javafx/
get openjfx-21.0.6_windows-x64_bin-jmods.zip
unzip openjfx-21.0.6_windows-x64_bin-jmods.zip
move javafx-jmods-21.0.6
into C:\TOOLS
final path is C:\TOOLS\javafx-jmods-21.0.6
JAVA_JMODS
SET C:\TOOLS\jdk-21.0.6+7\jmods
JAVAFX_JMODS
SET C:\TOOLS\javafx-jmods-21.0.6
open cmd.exe
run command:
jlink --module-path %JAVA_JMODS%;%JAVAFX_JMODS% ^
--add-modules javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.swing,java.desktop,java.base ^
--output jreFX2
match_three_solver_app
├── jreFX2
├── match_three_solver.jar
└── runMe.bat
Create app directory : match_three_solver_app
create runMe.bat
into app directory : match_three_solver_app
start /B "" jreFX2\bin\javaw -jar match_three_solver.jar
exit
match_three_solver_app
├── jreFX2
├── match_three_solver.jar
└── runMe.bat
Now you can compress the match_three_solver_app
directory into a zip archive.
match_three_solver_app.zip
Others only need to get match_three_solver_app.zip
, unzip it, and click runMe.bat
in the directory to run match_three_solver.
Here the directory size of custom JRE: jreFX2
is 106.3 MB