I have an executable-jar that I can run with java -jar app.jar but the SDK is 326MB. This is a lot.
jlink can create a JRE, but I can't use jlink as I have a non-modular application.
Can you please tell me how to create a JRE?
jlink can be used to create a 'JRE'/runtime image for non-modular applications just fine. It just can't automatically derive the modules that should go in the runtime image in that case. They have to be specified manually instead.
For instance, if I have a simple app.jar:
$ java -jar app.jar
Hello World!
Then create a runtime image with jlink, with only the java.base module:
jlink --output runtime --add-modules java.base --strip-debug --no-header-files --no-man-pages
Then I can run the jar with the java executable in the runtime image:
$ ./runtime/bin/java -jar app.jar
Hello World!
And the runtime image is just ~35 MB (though this can vary per platform).
jdeps can be used to get an idea of which modules should be used to create the runtime image:
$ jdeps --print-module-deps add.jar
java.base
This will print a comma-separated list of modules that can be passed directly as an argument to the --add-modules option of jlink.
You can try to this as source:
https://javaalmanac.io/
where you can find links to download only JRE instead of JDK.
Related
I'm getting the message "Missing JavaFX application class com.ponderwhy.pikeinventory.PikeInventory" after deploying with jPackage.
Using AdoptOpenJDK 16, JavaFx-16, WiX 3.11 on Windows 10. My application runs fine when I use the following JVM options file.
# -classpath aka -cp
-cp D:/WS_Utility/PikeInventory/bin;D:/WS_Utility/Basic/bin;D:/WS_Utility/ancillary/bin;C:/Java/javafx-sdk-16/lib;C:/Java/controlsfx-jfx-13/controlsfx-11.0.2.jar
# -modulepath aka -p
-p C:/Java/javafx-sdk-16/lib;D:/WS_Utility/basic/bin;D:/WS_Utility/Ancillary/bin;D:/WS_Utility/PikeInventory/bin;C:/Java/controlsfx-jfx-13/controlsfx-11.0.2.jar
--add-modules=ALL-MODULE-PATH
--add-exports javafx.base/com.sun.javafx.collections=ALL-UNNAMED
--add-exports javafx.base/com.sun.javafx.runtime=ALL-UNNAMED
--add-exports javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.css=ALL-UNNAMED
com.ponderwhy.pikeinventory.PikeInventory
When I use jPackage to build an.exe file using the following jPackage commands:
--type exe
--app-version 1.0.1
--description "Pike Inventory"
--name PikeInventory
--vendor PonderWhy
--verbose
--java-options -splash:$APPDIR//RockF7.jpg
--input D:/Dev/TrainInv/jPackage
--icon D:/Dev/TrainInv/jPackage/LocoFront.ico
--main-jar PikeInventory.jar
--main-class com.ponderwhy.pikeinventory.PikeInventory
--module-path C:/Java/javafx-jmods-16;C:/Java/controlsfx-jfx-13;C:/Java/JDK-16/jmods;D:/Dev/TrainInv/jPackage
--add-modules javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media,javafx.swing,javafx.web
--win-console
--win-dir-chooser
--win-menu
--win-menu-group PikeInventory
--win-shortcut
# --win-upgrade-uuid PkInv
I have the 2 environment variables set that I find some references to.
PATH_TO_FX=C:\Java\javafx-sdk-16\lib
PATH_TO_FX_MODS=C:\Java\javafx-jmods-16
All three of my projects, Basic, Ancillary and PikeInventory have module-info.class.
The jPackage builds, deploys and installs without error. My splash comes up then the missing class message.
I am at a loss at what to try next to resolve my problem.
Any help would be greatly appreciated.
Peter
I have found a way to create a personalised JRE on Windows that I can use on Windows.
I found a similar question on this web site where the answer
was "you just have to use the Linux jmods directory to make a Linux personalised JRE."
So, using AdoptOpenJDK (build 15+36), I tried to do that with the following commands:
jlink --module-path \jmodsWindows\ --add-modules java.desktop --output OUTWindows\java
jlink --module-path \jmodsLinux\ --add-modules java.desktop --output OUTLinux\java
jlink --module-path \jmodsMac\ --add-modules java.desktop --output OUTMac\java
But the personalised JREs that all three above commands created are the Windows one.
Is there something wrong with my commands? Is there a change in JDK 15 that affects how the jlink tool creates custom runtime images?
#deduper I tried with :
jlink --module-path C:\Users\hydrolien\Formiko\jmodsLinux --add-modules java.desktop --output OUTLinux\java
And that's working !
That was just a problem of absolute or relative path.
thanks a lot for your help !
Following instructions at https://openjfx.io/openjfx-docs/#install-javafx, I compiled the sample HelloFX.java via:
javac --module-path $PATH_TO_FX --add-modules=javafx.controls /Users/me/Documents/java/HelloFX.java
But now if I attempt to run that...
java --module-path $PATH_TO_FX --add-modules=javafx.controls /Users/me/Documents/java/HelloFX
... I get error:
Error: Could not find or load main class .Users.me.Documents.java.HelloFX
Caused by: java.lang.ClassNotFoundException: /Users/me/Documents/java/HelloFX
Yet the file reported as not found is there:
ls -l /Users/me/Documents/java/HelloFX.class
-rwxr--r-- 1 me staff 1336 Oct 30 16:01 /Users/murray/Documents/java/HelloFX.class
(I had already changed permissions to add u+x in case that was the issue, but apparently that was not the trouble.
What's wrong?
(Yes, $PATH_TO_FX does point to javafx-sdk-11/lib.)
This question was already answered in the openjfx-dev mailing list:
The "java" command expects a fully-qualified class name, not a file path as
its argument
For completion:
The javac command deals with filenames, which means you can compile a java file from any location:
javac [ options ] [ sourcefiles ]
However the java command deals with classes:
java [options] mainclass [args...]
where mainclass specifies the name of the class to be launched, not the filename or location.
Providing you have Java 11 installed (and JAVA_HOME is set at it), the JavaFX 11 SDK downloaded, and just following the getting started guide:
Download the HelloFX class to any location, i.e /Users/<user>/Downloads.
Open a terminal and cd to that location:
cd /Users/<user>/Downloads
Set the JavaFX path:
export PATH_TO_FX=/path/to/javafx-sdk-11/lib
Compile the class:
javac --module-path $PATH_TO_FX --add-modules=javafx.controls HelloFX.java
Check that HelloFX.class is created at the same folder level.
Run the class:
java --module-path $PATH_TO_FX --add-modules=javafx.controls HelloFX
It should run just fine.
Now, if you try to run the above command from a different location it won't work, because the HelloFX class is not available in the classpath.
So if you want to run this class from a different location you'll need to specify this classpath:
javac --module-path $PATH_TO_FX --add-modules=javafx.controls \
/Users/<user>/Downloads/HelloFX.java
java --module-path $PATH_TO_FX --add-modules=javafx.controls \
--class-path /Users/<user>/Downloads HelloFX
Not quite sure how to use jdeps to inspect module if current module has multi-version dependencies.
jdeps keep asking me provide --multi-version 9 but other dependent modules is not multi-version.
How to properly use jdeps for such cases?
command:
jdeps -cp .\..\..\..\modules --module-path .\..\..\..\modules -s ws-gen.jar
Error: jaxb-api.jar is a multi-release jar file but --multi-release option is not set
command:
jdeps --multi-release 9 --module-path . -filter:package -s jaxb-api.jar
Error: bcprov-jdk15on-1.60.jar is not a multi-release jar file but --multi-release option is set
jdeps - earlier access from JDK11
command:
jdeps -version
11
This seems a bug in jdeps which is tracked by https://bugs.openjdk.java.net/browse/JDK-8210502.
This same bug in jdeps with Oracle-JDK: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8207162.
I am creating a sample application with 3 modules user, dept and account. In my user module, I have a main class and compile my modules with the following command:
javac -d target --module-source-path src $(find -name "*.java")
After compiling, execute following command for run:
java -p target -m com.user/com.user.info.Launcher
The output after running java modules are successful. But when trying to create runtime image using jlink the image created successfully but module executable script is not there. For create an image, I am using the following command:
jlink --module-path $JAVA_HOME/jmods:target --add-modules com.user --output my-app
In, runtime image, I have bin directory, but this directory contains only java and keynote script. I am expecting user main class script as well, for executing my application.
My Java version as below:
java version "9-ea"
Java(TM) SE Runtime Environment (build 9-ea+165)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+165, mixed mode)
How can I resolve this problem?
jlink creates a runtime VM image in which it includes only the modules that are needed.
Since you specified --add-modules com.user the image will include the com.user module, and all of the modules it (directly or indirectly) depends on.
You can run your application by using the java binary in the bin folder of the generated image, and using the command:
java com.user.info.Launcher
You can also have jlink generate a launcher script using the --launcher <command>=<module>/<main> option. In your case you could do something like:
jlink --module-path $JAVA_HOME/jmods:target --add-modules com.user --output my-app --launcher launch=com.user/com.user.info.Launcher
And after that, you can just use launch from the bin directory to run the application.