I am working on a project that uses Javafx, and my goal is to make a .exe file with Launch4J, because it will be used by other people.
For now, when I export the project in a runnable JAR, if I want to execute it, I have to write as an argument the path of the javafx folder and add the different modules :
java --module-path javafx-sdk-17.0.2\lib --add-modules javafx.controls,javafx.fxml -jar test13.05.jar
Is there a way to put the javafx folder in my projects lib folder, and add the arguments directely into the main function so I can execute the project without having to write the path and add the modules ?
Fat jars are not recommended to distribute JavaFX application for various reasons. Instead use the official jpackage tool to package your application.
solution with a script (linux ubuntu version)
Adding jvm arguments as command in .sh script. every path must be relative in order to run it in other linux pc .Nescesary javafx jar are in libs folder
run_demo.sh
#! /bin/bash
java --module-path libs --add-modules javafx.controls -jar demo-1.0-SNAPSHOT.jar
This aproach can be implemented in other os with their proper scripts
Related
I am new to programming, there is a maven project with java code that does certain testing and it runs regularly through Jenkins pipeline, it runs the tests on an environment (linux machine).
Now what I am struggling and not knowing where to start is how can I test this code manually knowing that it has different Mains (i.e Main1 , Main2 , Main3) and I want to run a certain Main not all, for example only Main1 which tests specific thing.
ps: I have the code in Intellij, but I want to run it outside intellij, I want to run it on the environment I'm testing (linux maachine).
first you have to build the maven project using this command in your project directory:
mvn package
After a successful build, you will see a .jar file has created in target folder same as your package name and version.
finally you have to RUN the project.
To run the project use this command:
java -cp target/jarfileName.jar path_of_the_project_startup
Done.
First, you need to build your maven project. Navigate to the project folder (you must have the project root pom.xml there) open a terminal and to build it type:
mvn clean package
Depending on your project structure, a successful run of this command will result in several target folders at different levels for your modules and possibly .jar files inside them. Navigate into the target folder of the module in which your entry point (main) is and check jar file name. Let's call it jarname.jar for simplicity.
In case you have several entry points in the same jarname.jar, you can run them like this:
java -cp jarname.jar Main1
java -cp jarname.jar Main2
java -cp jarname.jar Main3
If you want to run from terminal and still debug from IntelliJ, run app with:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
and then create a 'Remote JVM Debug' config in IntelliJ on same port (5005), adding some break points and 'Debug'.
As an alternative, you can create Run Config 'Java Scratch' from IntelliJ to run/debug your app.
I'm building an installer on Windows with a few classes in the application jar but with dependencies on logging (logback). This is not a modular application. I'm finding it difficult to get it built properly since the logging dependencies are not being built into the installer. When it runs, cmd.exe tells me that the slf4j classes are not being found.
This is the build command
jpackage --verbose --dest jpk -p ..\.m2\repository\org\slf4j\slf4j-api\1.6.6\slf4j-api-1.6.6.jar;..\.m2\repository\ch\qos\logback\logback-core\1.0.9\logback-core-1.0.9.jar;..\.m2\repository\ch\qos\logback\logback-classic\1.0.9\logback-classic-1.0.9.jar --win-dir-chooser --win-console --input ..\webspeed\target --type msi --main-jar webspeed-1.0-SNAPSHOT.jar --main-class com.technojeeves.webspeed.WebspeedSystray
I'm hoping it's not necessary to have a fat jar as the starting point, since when I tried that after using Maven Shade, I found that jpackage took ages and a massive amount of memory. I couldn't wait any longer and terminated the build.
There are very few examples of jpackage per se, other than simple ones that just echo the Oracle docs. I couldn't find a single one for non-modular with deps.
jpackage runs jlink implicitly for module dependencies but does not seem to include the jars.
For builds with non-module jars you can add each jar under your --input directory parameter as a build step before the jpackage command. Create a staging input directory ..\webspeed\target\jars and copy each of the non-module jars to that staging directory.
After running jpackage and then the installer: check the classpath entries are set by inspecting the yourlaunchername.cfg file. Each launcher cfg should contain an entry which indicates that the classpath is setup with installed copies of each non-module jars.
For example a Windows installer should show:
[Application]
app.classpath=$APPDIR\jars\logback-core-1.0.9.jar
app.classpath=$APPDIR\jars\logback-classic-1.0.9.jar
...
If/as module dependencies don't change much it is usually quicker/easier to pre-prepare a jlink image containing the module images and pass in --runtime-image ${your.jlink}.
I have completed my JavaFX application within gradle build system, and it is working fine in all way. Now I want to export as a .EXE file for standalone software distribution, I tried much more tricks but no gain. If some one can help me out to wrap my project in a software setup, It would be grateful.
Follow these steps to export your JavaFX project into executable Jar
Goto> Project Structure
Goto>>Artifacts
Click "+">> To add new artifact
It will shows a dropdownlist
Select>>Jar>>From module with dependencies
You will see a nested window as shown
Select Main class of your project
Check In the Option " Copy to output directory.." >>Ok
Goto>> Menu-bar>>Build>>Build Artifacts
Select>> your Project.jar>> Build
This will create executable jar file in your project source folder
Locate your jar file in path project\out\artifacts..
Now you can run this jar file simple cmd commad or with batch file
Cmd Command>> Java -jar project.jar
Using batch file>> make .bat file name it "RUN" and write these commands inside
Specify the Java Runtime path and "Javafx Sdk path" along with VM
options & Project Jar
Run your standalone application .. Enjoy ;)
Creating an installer for the desktop platforms (Windows, macOS, Linux) has become easy these days. The tool of choice is jpackage which started to be shipped with JDK 14. It can either be used on the command line on the finished project or you can use a Gradle plugin (https://github.com/beryx/badass-jlink-plugin). If your project is not modularized you could follow this tutorial https://github.com/dlemmermann/JPackageScriptFX which also uses jpackage but together with Maven and some other tools from the JDK. The Maven part could easily be rewritten to Gradle, if needed.
I created a JavaFX project in IntelliJ.
I can run project in IntelliJ. I added below code in Configurations):
--module-path ${PATH_TO_FX} --add-modules=javafx.controls,javafx.fxml
But the output .jar file of project (made with Artifects) doesn't run. I tested these commands, but didn't get any chance:
java --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml -jar Timer.jar
java --module-path %PATH_TO_FX% --add-modules javafx.controls Timer.jar
Last error log of command line:
Error: Could not find or load main class Files\Java\javafx-sdk-11.0.1\lib
Caused by: java.lang.ClassNotFoundException: Files\Java\javafx-sdk-11.0.1\lib
p.s: I could run .jar file of this project when build on JDK-10
EDIT:
I downloaded JavaFX and added it's lib folder to System Environments.
for adding JavaFX to project I did this process:
Project Structure > Libraries > add > Java > JavaFxPath/lib
Then I created Artifect for output jar file in this process:
Project Structure > Artifects > Add > JAR > From Modules with dependencies > main Class : main.Main.
Providing you have a simple (non-modular) JavaFX 11 project (without Maven/Gradle build tools), and you are using IntelliJ, like the HelloFX sample from here,
this is how you can create a jar from IntelliJ that can be run from the console
A full tutorial on how to run the project can be found here, and instructions on how to create a jar are here (see section Non-modular project), but these doesn't cover Artifacts from IntelliJ.
Check that the HelloFX project runs from IntelliJ with these VM options:
--module-path ${PATH_TO_FX} --add-modules javafx.controls,javafx.fxml
where PATH_TO_FX has been set in File -> Settings -> Appearance & Behavior -> Path Variables, pointing to the JavaFX SDK lib.
Semi fat Jar
We can create a Jar that only contains the classes from the project, and third party dependencies, but not JavaFX ones.
Go to File -> Project Structure -> Artifacts -> Add -> JAR -> From modules with dependencies, add your main class, accept.
Then remove the JavaFX jars from the list, and accept.
Build the project, it will create a quite small jar (3 KB in this case).
Now you should be able to run it like:
java --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml -jar out\artifacts\HelloFX_jar\HelloFX.jar
(make sure that %PATH_TO_FX% points to a valid folder and use quotes if it contains spaces.
You can distribute this jar, and run it in other platforms, providing those also have the JavaFX SDK.
Fat Jar
If you want a full fat jar that includes JavaFX dependencies, you can still use Artifacts.
Go to File -> Project Structure -> Artifacts -> Add -> JAR -> From modules with dependencies, add your main class, accept.
Then keep the JavaFX jars from the list, and accept. Build the project.
In theory, you should be able to run it like:
java -jar out\artifacts\HelloFX_jar\HelloFX.jar
But this won't work.
Reason 1: You need a launcher class, as explained here.
So create a launcher class:
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
Reason 2: If you only add your SDK jars to the fat jar, you will be missing the native libraries, as explained here.
So edit the artifact, select the Launcher class as main class, and add the native libraries (Directory Content -> path-to/JavaFX SDK/bin on Windows):
Now build the project (now the jar is about 33 MB, and contains unnecessary native libraries) and run:
java -jar out\artifacts\HelloFX_jar\HelloFX.jar
You can distribute this jar, but only to Windows platforms.
You can create similar jars for other platforms, if you download their JavaFX SDKs, and you can also build cross-platform jars if you add them all together, as explained in the linked answers above.
Anyway, you should consider using jlink instead.
Note
About this error:
Caused by: java.lang.ClassNotFoundException: Files\Java\javafx-sdk-11.0.1\lib
it looks like the library path was set without quotes and it is missing the first part of the path C:\Program Files\.... Just make sure you use quotes:
set PATH_TO_FX="C:\Program Files\Java\javafx-sdk-11.0.1\lib"
I had the similar issue exporting/generating an Jar using JavaFX and IntelliJ Non-modular with Gradle (https://openjfx.io/openjfx-docs/)
The jar I was generating using Gradle jar command does not run and throws error saying it can not find my Main Class. When I opened my jar I was able to locate my main class. So I realized the error has to do with Jar Packaging.
I fixed the problem by adding JavaFX SDK to my Java SDk in IntelliJ as shown below.
After this I use the regular Gradle build Jar command to generate my Jar file (as shown below) and it runs Normally.
The easiest way to do this is to use an OpenJDK build that include JavaFX. Both Bellsoft and Azul produce such builds.
For Azul's Zulu builds of OpenJDK:
https://www.azul.com/downloads/zulu-community/?version=java-11-lts&package=jdk-fx
For Bellsoft Liberica JDK:
https://bell-sw.com/pages/downloads/#/java-11-lts
and choose "Full JDK"
These builds are basically OpenJDK with the OpenJFX JavaFX modules added. Though be careful as some aspects of JavaFX may not be supported on LibericaFX. See https://bell-sw.com/pages/liberica-release-notes-11.0.9.1/
The above answers apply to non-modular JavaFX projects. To get a modular JavaFX project (with modular dependencies) running I used jlink.
Take the JavaFX SDK from https://gluonhq.com/products/javafx/; unzip the files to a directory, and point a shell variable JFX_LIB to the unzipped lib/ directory.
Take the JavaFX jmods (not SDK) file from https://gluonhq.com/products/javafx/; unzip the jmods, they are in a folder similar to javafx-jmods-11.0.2/. Point a shell variable JMOD_PATH to the unzipped directory javafx-jmods-11.0.2/.
Compile, sending your compiled classes to the directory mods/:
javac -d mods --module-source-path src --module-path $JFX_LIB/javafx.graphics.jar:$JFX_LIB/javafx.base.jar:$JFX_LIB/javafx.controls.jar --module com.mymodule
Create a custom JRE with jlink, referring to the module path containing the JavaFX mods and your own compiled mod:
jlink --module-path $JMOD_PATH:mods --add-modules com.mymodule --output customjre
Run:
customjre/bin/java --module com.mymodule/com.mymodule.Main
(I tried for a LONG TIME to get a java -jar running with --module-path and --add-modules. I always got the following error:)
Error: Could not find or load main class com.mymodule.Main
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
I have a jar file that is being created by Spring Boot. Application runs smoothly when run by command java -jar. I want to create an install anywhere launcher with this jar file.
What I have tried is to send the Spring Boot main class (PropertiesLauncher). The issue is that calling it like this won't load the nested jars inside my executable jar and also the loader.path doesn't seems to work.
Is there a way to call the executable jar like java -jar from the install anywhere launcher?
I was thinking that another option was to create an install anywhere launcher for a script file and inside have the java -jar call. So another question will be:
How do I create an install anywhere launcher for a script file?
'execute command' step will do the trick:
Use this command line:
java -jar <path.to.jar.file>
Use EXECUTE_STDOUT, EXECUTE_STDERR and EXECUTE_EXITCODE built-in variables to catch errors and parse the jar's execution result.
Important notes:
You'll have to make sure your jar includes all of the dependencies (or at least set the classpath in the command line);
To include the dependencies within your jar using eclipse you can:
Export your project as a 'runnable jar file' and select the
'Extract/Package required libraries into generated JAR' option/s
Use Maven to build the project with dependencies; the
maven-assembly-plugin is required.
The 'execute command' will work for batch/cmd/shell scripts as well, but you'll have to make sure the scripts are extracted to a local folder such as %TEMP% or /tmp before you can use them.
Goodluck