Is it possible to include the JavaFX modules in a Jpackage app? - java

My question is kind of a two parter:
CAN I even include the JavaFX modules in a JPackaged app such that a user doesn't have to go and install a specific version of JavaFX libraries before installing my app?
If #1 is possible, how do I do that and/or what am I doing wrong when I attempt it?
My application was originally Java 8, and I upgraded it to Java 17. Currently:
Windows 10
Java 17.0.6 LTS
JavaFX 19.0.2.1
My app is non-modular and being built with maven and packaged into a monolithic jar with all dependencies (except JavaFX modules) using the Maven Assembly Plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.github.iguanastin.app.MyAppKt</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
I'm currently using jpackage to package my app into an installable EXE for Windows:
& jpackage.exe
--input ./input
--dest ./output
-n MyApp
--app-version 1.0.0
--java-options "--module-path 'C:\Program Files\Java\javafx-sdk-21\lib' --add-modules javafx.controls --add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED"
--main-jar ./myapp-jar-with-dependencies.jar
Which works fine, as long as the user has manually installed JavaFX in: C:\Program Files\Java\javafx-sdk-21.
As I understand it this isn't the way it SHOULD be packaged, because the --module-path and --add-modules should be passed to Jpackage and not as JVM arguments with the --java-options argument. However, when I try to package it like so:
& jpackage.exe
--input ./input
--dest ./output
-n MyApp
--app-version 1.0.0
--module-path 'C:\Program Files\Java\javafx-sdk-21\lib'
--add-modules javafx.controls
--java-options '--add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED'
--main-jar ./myapp-jar-with-dependencies.jar
It creates an EXE with no errors and installs normally, but when I try to run it I get 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-ea/com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(Unknown Source) at javafx.graphics#21-ea/com.sun.javafx.tk.quantum.QuantumToolkit.init(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.tk.Toolkit.getToolkit(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.startToolkit(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
at javafx.graphics#21-ea/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(Unknown Source)
... 1 more
Exception in thread "main" java.lang.RuntimeException: No toolkit found
at javafx.graphics#21-ea/com.sun.javafx.tk.Toolkit.getToolkit(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.PlatformImpl.startup(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.startToolkit(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
at javafx.graphics#21-ea/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Failed to launch JVM
Which appears to be caused by missing/unlinked JavaFX dlls according to this post. I also found this Github issue which suggests using the JavaFX jmods instead of the SDK, but the result is the same. I forget where, but another post I found suggested adding the sdk /bin folder to the app folder, which also gives the same error at runtime.
After spending hours trying out different combinations of the above solutions with jmods, sdk, etc. I'm still not getting anywhere on this problem.

I'm answering my own question because I found the solution. Yes, you can include JavaFX in a jpackage launcher, and my problem was that I had accidentally downloaded the JavaFX jmods for aarch64 linux instead of windows.

Related

javafx .jar project can't run outside of the directory [duplicate]

I'm getting this error
Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Ap
plication
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 13 more
When trying to run my class file, this is the source
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.concurrent.Executor;
public class TestApplication extends Application{
#Override
public void start(Stage stage) throws Exception {
new TestApplication();
}
public TestApplication() {
try{
final Parent root = FXMLLoader.load(Executor.class.getResource("test.fxml"));
final Stage stage = new Stage(){{
setScene(new Scene(root, 300, 250));
setTitle("Test");
setResizable(false);
show();
}};
}catch(Exception e){
e.printStackTrace();
}
}
}
The fxml file contains a simple gui.
I've worked on this very same issue for the past few hours. Even though I haven't seen it written explicitly, it appears that you MUST use one of the JavaFX packaging tools, which is either an Ant task or the javafxpackager executable. (See http://docs.oracle.com/javafx/2/deployment/packaging.htm, section 5.3.1). The NetBeans IDE uses Ant to package the code. (I'm using IntelliJ)
When you use one of those packaging methods, in addition to all of your application's code and resources, it also adds the following to your output JAR file:
/com/javafx/main/Main$1.class
/com/javafx/main/Main$2.class
/com/javafx/main/Main.class
/com/javafx/main/NoJavaFXFallback.class
With these in place, you can run the app from the command line:
java -jar outjar.jar
and all works fine. If I remove the extra com.javafx.main files, the app does not run.
To double-check this, I looked at all four JAR files in the JavaFX samples (BrickBreaker, Ensemble, FXML-LoginDemo, and SwingInterop). They all have the "extra" files, too.
For my small test app, I used this command line to build an "executable" JAR file:
javafxpackager -createjar -appclass sample.Main -outfile outjar -v -nocss2bin -srcdir C:\workspaces\garoup1\out\production\javafx1
Hope this helps!
I had the same problem and below steps helped me to solve it,
Adding the vm arguments while running the application,
--module-path /home/user/Java-libraries/openjfx-11.0.2_linux-x64_bin-sdk/javafx-sdk-11.0.2/lib/ --add-modules javafx.controls,javafx.fxml
Note:
The --module-path will contain the jars of Java fx
I used open-jdk 13
Configure this in your eclipse (If you are using so) or you can just compile and run like,
Compile
javac --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml *.java
Run
java --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml MyMainClass
I believe that my example will help someone. I had not succeeded with building REALLY executable jar file, that can be run by click from any place/directory with Java 8. Moving to Java 11 and few other twicks did the business.
Move to Java 11. Specify SDK, other staff in IDE, add this to pom.xml
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
Add JavaFX dependencies
<!--JavaFX-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>15.0.1</version>
<type>pom</type>
</dependency>
<!--JavaFX-controls-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>15.0.1</version>
</dependency>
Build application
Create wrapper class for your Main class, which extends Application
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
Add the following to pom.xml
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<finalName>final-jar-file-name</finalName>
<archive>
<manifest>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run this maven command
mvn clean -Dmaven.clean.failOnError=false compile assembly:single -DskipTests=true
The jar file with specified name will appear in target directory. It will be executable independent from where you are running it.
Using java 8 shouldn't give this problem but it did for me
I created my jar initially from Eclipse Export -> Runnable Jar and it was fine. When I moved to Maven it failed with the above.
Comparing the two jars showed that nothing fx related was packaged with the jar (as I'd expect) but that the Eclipse generated manifest had Class-Path: . in it. Getting maven to package the jar with the following worked for me (with Java 8)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pg.fxapplication.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
I know it may not be the "proper" way of launching an javafx application but i have struggled with this problem for some time and came up with a workaround that does not require to use any external packaging applications, force you to use ant or maven plugin (which conflicts with the shade plugin) etc...
The solution uses Utils4j to load jfxrt dynamically at runtime. You cannot load it in a class extending javafx.application.Application, do it in a separate class and name it for example: Launcher
import org.fuin.utils4j.Utils4J
public class Launcher {
public static void main(String[] args) {
Utils4J.addToClasspath("file:///"+System.getProperty("java.home")+ File.separator+"lib"+File.separator+"jfxrt.jar");
// CODE TO RUN YOUR CLASS THAT EXTENDS javafx.application.Application goes here.
}
}
you can include Utils4j with your project (if using maven):
<dependency>
<groupId>org.fuin</groupId>
<artifactId>utils4j</artifactId>
<version>0.7.0</version>
</dependency>
I use maven and I just run this mvn install:install-file -Dfile="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar" -DgroupId=com.oracle.javafx -DartifactId=javafx -Dversion=2.2 -Dpackaging=jar in terminal(Maybe a little difference in Windows.). Then maven will install jfxrt.jar then you can simply reference it as
<dependency>
<groupId>com.oracle.javafx</groupId>
<artifactId>javafx</artifactId>
<version>2.2</version>
</dependency>
If you are using netbeans like me and you have two versions of JDK installed, then you should change the classpath to the appropriate java installation in the config file. This is also a bug in Netbeans:
There are two ways to do it:
Either start NetBeans with --jdkhome by executing this:
"C:\Program Files\NetBeans Dev 201402160001\bin\netbeans.exe" --jdkhome "C:\Program Files\Java\jdk1.7.0_51"
Or set the "netbeans_jdkhome" property in /etc/netbeans.conf e.g.
# Default location of JDK, can be overridden by using --jdkhome <dir>:
netbeans_jdkhome="C:\Program Files\Java\jdk1.7.0_51"
IntelliJ and maybe other IDE's do not refactor your Run/Debug configuration. You must manually change your package name preceding the name of your Main class. For instance, change 'sample.Main' to 'com.company.package.ui.Main' so it will launch correctly next time you try to run it. The IDE might have already marked the Run/Debug button with a red cross because it couldn't find the main class. It also gives a warning when you open the Run/Debug configuration.
I already answered it on "Ask ubntu".
I recommend you to go with https://openjfx.io/openjfx-docs/ .i am using Eclipse IDE but it works for all IDE
Then you can refer to this global variable when setting the VM options as:
In IDE Right-click on project->Run As -> Run Configuration ->Arguments->VM Arguments
For Windows,
--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml
For Linux,
--module-path /path to javafx/lib --add-modules javafx.controls,javafx.fxml
I'm developing on Linux a simple WebApp i got the same error, but is really easy to fix it (assuming you are developing on the command line as myself).
cat compile.sh
#!/bin/bash
/usr/lib/jvm/jdk1.7.0_25/bin/javac WebViewSample.java -cp /usr/lib/jvm/jdk1.7.0_25
/jre/lib/jfxrt.jar
$ cat run.sh
#!/bin/sh
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_25/bin/
CLASSPATH=/usr/lib/jvm/jre1.7.0_25/lib/jfxrt.jar:.
$JAVA_HOME/java -cp $CLASSPATH WebViewSample $* 2>&1 /dev/null | awk -F\| '{ print $2"|"$3 ; exit $1 }'
exit $?
I had a problem of not finding the Pair class from javafx.
It seems that vanilla eclipse (without the e(fx)clipse extension) doesn't search the javaFX runtime jar included with java.
I just added to my eclipse project build path this external jar (or if you are in a debug configuration, add the external jar in the JRE tab of the debug configuration):
$JAVA_HOME/jre/lib/ext/jfxrt.jar
(replace JAVA_HOME with your jdk folder)
For me it was in /installs/jdk1.8.0_211/jre/lib/ext/jfxrt.jar
in eclipse environment: add jfxrt.jar to Bundle-ClassPath in MANIFEST.MF file.
Bundle-ClassPath: .,
jfxrt.jar

Could not find or load main class when running JAR on Ubuntu [duplicate]

I'm getting this error
Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Ap
plication
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 13 more
When trying to run my class file, this is the source
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.concurrent.Executor;
public class TestApplication extends Application{
#Override
public void start(Stage stage) throws Exception {
new TestApplication();
}
public TestApplication() {
try{
final Parent root = FXMLLoader.load(Executor.class.getResource("test.fxml"));
final Stage stage = new Stage(){{
setScene(new Scene(root, 300, 250));
setTitle("Test");
setResizable(false);
show();
}};
}catch(Exception e){
e.printStackTrace();
}
}
}
The fxml file contains a simple gui.
I've worked on this very same issue for the past few hours. Even though I haven't seen it written explicitly, it appears that you MUST use one of the JavaFX packaging tools, which is either an Ant task or the javafxpackager executable. (See http://docs.oracle.com/javafx/2/deployment/packaging.htm, section 5.3.1). The NetBeans IDE uses Ant to package the code. (I'm using IntelliJ)
When you use one of those packaging methods, in addition to all of your application's code and resources, it also adds the following to your output JAR file:
/com/javafx/main/Main$1.class
/com/javafx/main/Main$2.class
/com/javafx/main/Main.class
/com/javafx/main/NoJavaFXFallback.class
With these in place, you can run the app from the command line:
java -jar outjar.jar
and all works fine. If I remove the extra com.javafx.main files, the app does not run.
To double-check this, I looked at all four JAR files in the JavaFX samples (BrickBreaker, Ensemble, FXML-LoginDemo, and SwingInterop). They all have the "extra" files, too.
For my small test app, I used this command line to build an "executable" JAR file:
javafxpackager -createjar -appclass sample.Main -outfile outjar -v -nocss2bin -srcdir C:\workspaces\garoup1\out\production\javafx1
Hope this helps!
I had the same problem and below steps helped me to solve it,
Adding the vm arguments while running the application,
--module-path /home/user/Java-libraries/openjfx-11.0.2_linux-x64_bin-sdk/javafx-sdk-11.0.2/lib/ --add-modules javafx.controls,javafx.fxml
Note:
The --module-path will contain the jars of Java fx
I used open-jdk 13
Configure this in your eclipse (If you are using so) or you can just compile and run like,
Compile
javac --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml *.java
Run
java --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml MyMainClass
I believe that my example will help someone. I had not succeeded with building REALLY executable jar file, that can be run by click from any place/directory with Java 8. Moving to Java 11 and few other twicks did the business.
Move to Java 11. Specify SDK, other staff in IDE, add this to pom.xml
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
Add JavaFX dependencies
<!--JavaFX-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>15.0.1</version>
<type>pom</type>
</dependency>
<!--JavaFX-controls-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>15.0.1</version>
</dependency>
Build application
Create wrapper class for your Main class, which extends Application
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
Add the following to pom.xml
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<finalName>final-jar-file-name</finalName>
<archive>
<manifest>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run this maven command
mvn clean -Dmaven.clean.failOnError=false compile assembly:single -DskipTests=true
The jar file with specified name will appear in target directory. It will be executable independent from where you are running it.
Using java 8 shouldn't give this problem but it did for me
I created my jar initially from Eclipse Export -> Runnable Jar and it was fine. When I moved to Maven it failed with the above.
Comparing the two jars showed that nothing fx related was packaged with the jar (as I'd expect) but that the Eclipse generated manifest had Class-Path: . in it. Getting maven to package the jar with the following worked for me (with Java 8)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pg.fxapplication.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
I know it may not be the "proper" way of launching an javafx application but i have struggled with this problem for some time and came up with a workaround that does not require to use any external packaging applications, force you to use ant or maven plugin (which conflicts with the shade plugin) etc...
The solution uses Utils4j to load jfxrt dynamically at runtime. You cannot load it in a class extending javafx.application.Application, do it in a separate class and name it for example: Launcher
import org.fuin.utils4j.Utils4J
public class Launcher {
public static void main(String[] args) {
Utils4J.addToClasspath("file:///"+System.getProperty("java.home")+ File.separator+"lib"+File.separator+"jfxrt.jar");
// CODE TO RUN YOUR CLASS THAT EXTENDS javafx.application.Application goes here.
}
}
you can include Utils4j with your project (if using maven):
<dependency>
<groupId>org.fuin</groupId>
<artifactId>utils4j</artifactId>
<version>0.7.0</version>
</dependency>
I use maven and I just run this mvn install:install-file -Dfile="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar" -DgroupId=com.oracle.javafx -DartifactId=javafx -Dversion=2.2 -Dpackaging=jar in terminal(Maybe a little difference in Windows.). Then maven will install jfxrt.jar then you can simply reference it as
<dependency>
<groupId>com.oracle.javafx</groupId>
<artifactId>javafx</artifactId>
<version>2.2</version>
</dependency>
If you are using netbeans like me and you have two versions of JDK installed, then you should change the classpath to the appropriate java installation in the config file. This is also a bug in Netbeans:
There are two ways to do it:
Either start NetBeans with --jdkhome by executing this:
"C:\Program Files\NetBeans Dev 201402160001\bin\netbeans.exe" --jdkhome "C:\Program Files\Java\jdk1.7.0_51"
Or set the "netbeans_jdkhome" property in /etc/netbeans.conf e.g.
# Default location of JDK, can be overridden by using --jdkhome <dir>:
netbeans_jdkhome="C:\Program Files\Java\jdk1.7.0_51"
IntelliJ and maybe other IDE's do not refactor your Run/Debug configuration. You must manually change your package name preceding the name of your Main class. For instance, change 'sample.Main' to 'com.company.package.ui.Main' so it will launch correctly next time you try to run it. The IDE might have already marked the Run/Debug button with a red cross because it couldn't find the main class. It also gives a warning when you open the Run/Debug configuration.
I already answered it on "Ask ubntu".
I recommend you to go with https://openjfx.io/openjfx-docs/ .i am using Eclipse IDE but it works for all IDE
Then you can refer to this global variable when setting the VM options as:
In IDE Right-click on project->Run As -> Run Configuration ->Arguments->VM Arguments
For Windows,
--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml
For Linux,
--module-path /path to javafx/lib --add-modules javafx.controls,javafx.fxml
I'm developing on Linux a simple WebApp i got the same error, but is really easy to fix it (assuming you are developing on the command line as myself).
cat compile.sh
#!/bin/bash
/usr/lib/jvm/jdk1.7.0_25/bin/javac WebViewSample.java -cp /usr/lib/jvm/jdk1.7.0_25
/jre/lib/jfxrt.jar
$ cat run.sh
#!/bin/sh
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_25/bin/
CLASSPATH=/usr/lib/jvm/jre1.7.0_25/lib/jfxrt.jar:.
$JAVA_HOME/java -cp $CLASSPATH WebViewSample $* 2>&1 /dev/null | awk -F\| '{ print $2"|"$3 ; exit $1 }'
exit $?
I had a problem of not finding the Pair class from javafx.
It seems that vanilla eclipse (without the e(fx)clipse extension) doesn't search the javaFX runtime jar included with java.
I just added to my eclipse project build path this external jar (or if you are in a debug configuration, add the external jar in the JRE tab of the debug configuration):
$JAVA_HOME/jre/lib/ext/jfxrt.jar
(replace JAVA_HOME with your jdk folder)
For me it was in /installs/jdk1.8.0_211/jre/lib/ext/jfxrt.jar
in eclipse environment: add jfxrt.jar to Bundle-ClassPath in MANIFEST.MF file.
Bundle-ClassPath: .,
jfxrt.jar

Running app jar file on spark-submit in a google dataproc cluster instance

I'm running a .jar file that contains all dependencies that I need packaged in it. One of this dependencies is com.google.common.util.concurrent.RateLimiter and already checked it's class file is in this .jar file.
Unfortunately when I hit the command spark-submit on the master node of my google's dataproc-cluster instance I'm getting this error:
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
at com.google.common.util.concurrent.RateLimiter$SleepingStopwatch$1.<init>(RateLimiter.java:417)
at com.google.common.util.concurrent.RateLimiter$SleepingStopwatch.createFromSystemTimer(RateLimiter.java:416)
at com.google.common.util.concurrent.RateLimiter.create(RateLimiter.java:130)
at LabeledAddressDatasetBuilder.publishLabeledAddressesFromBlockstem(LabeledAddressDatasetBuilder.java:60)
at LabeledAddressDatasetBuilder.main(LabeledAddressDatasetBuilder.java:144)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:672)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:180)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:205)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:120)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
It seems something happened in the sense of overwriting my dependencies. Already decompiled the Stopwatch.class file from this .jar and checked that method is there. That just happened when I ran on that google dataproc instance.
I did grep on the process executing the spark-submit and I got the flag -cp like this:
/usr/lib/jvm/java-8-openjdk-amd64/bin/java -cp /usr/lib/spark/conf/:/usr/lib/spark/lib/spark-assembly-1.5.0-hadoop2.7.1.jar:/usr/lib/spark/lib/datanucleus-api-jdo-3.2.6.jar:/usr/lib/spark/lib/datanucleus-rdbms-3.2.9.jar:/usr/lib/spark/lib/datanucleus-core-3.2.10.jar:/etc/hadoop/conf/:/etc/hadoop/conf/:/usr/lib/hadoop/lib/native/:/usr/lib/hadoop/lib/*:/usr/lib/hadoop/*:/usr/lib/hadoop-hdfs/lib/*:/usr/lib/hadoop-hdfs/*:/usr/lib/hadoop-mapreduce/lib/*:/usr/lib/hadoop-mapreduce/*:/usr/lib/hadoop-yarn/lib/*:/usr/lib/hadoop-yarn/*
Is there anything I can do to solve this problem?
Thank you.
As you've found, Dataproc includes Hadoop dependencies on the classpath when invoking Spark. This is done primarily so that using Hadoop input formats, file systems, etc is fairly straight-forward. The downside is that you will end up with Hadoop's guava version which is 11.02 (See HADOOP-10101).
How to work around this depends on your build system. If using Maven, the maven-shade plugin can be used to relocate your version of guava under a new package name. An example of this can be seen in the GCS Hadoop Connector's packaging, but the crux of it is the following plugin declaration in your pom.xml build section:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>your.repackaged.deps.com.google.common</shadedPattern>
</relocation>
</relocations>
</execution>
</execution>
</plugin>
Similar relocations can be accomplished with the sbt-assembly plugin for sbt, jarjar for ant, and either jarjar or shadow for gradle.

How to add jars to JMeter's classpath in non-GUI mode

I have created a test plan in the JMeter GUI which uses the "Java Request Sampler".
I added the jarfile which contains the implementation to my sampler to /lib/ext/ of my jmeter installation.
This all works fine when I run it in GUI mode.
However when I switch to non gui mode using
./jmeter -n -t Test\ Plan.jmx
I get:
com.mycompany.JavaSamplerTest java.lang.ClassNotFoundException
2014/01/23 15:25:25 ERROR - jmeter.protocol.java.sampler.JavaSampler: StandardJMeterEngine#5efbfd6e-Java Request Exception initialising: com.mycompany.JavaSamplerTest java.lang.ClassNotFoundException: com.mycompany.JavaSamplerTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at org.apache.jmeter.protocol.java.sampler.JavaSampler.initClass(JavaSampler.java:117)
at org.apache.jmeter.protocol.java.sampler.JavaSampler.testStarted(JavaSampler.java:263)
at org.apache.jmeter.engine.StandardJMeterEngine.notifyTestListenersOfStart(StandardJMeterEngine.java:214)
at org.apache.jmeter.engine.StandardJMeterEngine.run(StandardJMeterEngine.java:336)
at java.lang.Thread.run(Thread.java:744)
I have no clue why this behaves differently when using -n -t. Does anybody have a solution to this?
I work on Linux using openjdk if this is somehow a helpful information.
As per How do I run JMeter in non-gui mode article you can use -J key to provide additional classpath elements location to JMeter like below:
./jmeter -Juser.classpath=/some/folder/your/extension.jar -n -t ${path_to_your_script} -l ${path_to_results}
Put the jar in jmeter/lib folder.
lib/ext is for real plugins.
Below is how I have the plugin set-up for maven pom
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<testPlanLibraries>
<artifact>org.apache.commons:commons-lang3:3.0</artifact>
</testPlanLibraries>
<propertiesSystem>
<user>${username}</user>
</propertiesSystem>
</configuration>
</plugin>
I had the same issue today with jmeter 5.4 on a linux machine.
Thanks to my colleague we identified the root cause.
In jmeter.properties we use the following line to extend the classpath libs.
user.classpath=../lib;../lib/ext
Howerver on a linux machine this line hast to be look like:
user.classpath=../lib:../lib/ext
Thus use : instead of ;
In our case this fits our problem.
Add it as a dependency inside the jmeter plugin:
<dependencies>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.0-801.jdbc4</version>
</dependency>

JavaFX Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application

I'm getting this error
Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Ap
plication
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javafx.application.Application
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 13 more
When trying to run my class file, this is the source
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.util.concurrent.Executor;
public class TestApplication extends Application{
#Override
public void start(Stage stage) throws Exception {
new TestApplication();
}
public TestApplication() {
try{
final Parent root = FXMLLoader.load(Executor.class.getResource("test.fxml"));
final Stage stage = new Stage(){{
setScene(new Scene(root, 300, 250));
setTitle("Test");
setResizable(false);
show();
}};
}catch(Exception e){
e.printStackTrace();
}
}
}
The fxml file contains a simple gui.
I've worked on this very same issue for the past few hours. Even though I haven't seen it written explicitly, it appears that you MUST use one of the JavaFX packaging tools, which is either an Ant task or the javafxpackager executable. (See http://docs.oracle.com/javafx/2/deployment/packaging.htm, section 5.3.1). The NetBeans IDE uses Ant to package the code. (I'm using IntelliJ)
When you use one of those packaging methods, in addition to all of your application's code and resources, it also adds the following to your output JAR file:
/com/javafx/main/Main$1.class
/com/javafx/main/Main$2.class
/com/javafx/main/Main.class
/com/javafx/main/NoJavaFXFallback.class
With these in place, you can run the app from the command line:
java -jar outjar.jar
and all works fine. If I remove the extra com.javafx.main files, the app does not run.
To double-check this, I looked at all four JAR files in the JavaFX samples (BrickBreaker, Ensemble, FXML-LoginDemo, and SwingInterop). They all have the "extra" files, too.
For my small test app, I used this command line to build an "executable" JAR file:
javafxpackager -createjar -appclass sample.Main -outfile outjar -v -nocss2bin -srcdir C:\workspaces\garoup1\out\production\javafx1
Hope this helps!
I had the same problem and below steps helped me to solve it,
Adding the vm arguments while running the application,
--module-path /home/user/Java-libraries/openjfx-11.0.2_linux-x64_bin-sdk/javafx-sdk-11.0.2/lib/ --add-modules javafx.controls,javafx.fxml
Note:
The --module-path will contain the jars of Java fx
I used open-jdk 13
Configure this in your eclipse (If you are using so) or you can just compile and run like,
Compile
javac --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml *.java
Run
java --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml MyMainClass
I believe that my example will help someone. I had not succeeded with building REALLY executable jar file, that can be run by click from any place/directory with Java 8. Moving to Java 11 and few other twicks did the business.
Move to Java 11. Specify SDK, other staff in IDE, add this to pom.xml
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
Add JavaFX dependencies
<!--JavaFX-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx</artifactId>
<version>15.0.1</version>
<type>pom</type>
</dependency>
<!--JavaFX-controls-->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>15.0.1</version>
</dependency>
Build application
Create wrapper class for your Main class, which extends Application
public class Launcher {
public static void main(String[] args) {
Main.main(args);
}
}
Add the following to pom.xml
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<finalName>final-jar-file-name</finalName>
<archive>
<manifest>
<mainClass>path-to-launcher.Launcher</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Run this maven command
mvn clean -Dmaven.clean.failOnError=false compile assembly:single -DskipTests=true
The jar file with specified name will appear in target directory. It will be executable independent from where you are running it.
Using java 8 shouldn't give this problem but it did for me
I created my jar initially from Eclipse Export -> Runnable Jar and it was fine. When I moved to Maven it failed with the above.
Comparing the two jars showed that nothing fx related was packaged with the jar (as I'd expect) but that the Eclipse generated manifest had Class-Path: . in it. Getting maven to package the jar with the following worked for me (with Java 8)
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pg.fxapplication.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
I know it may not be the "proper" way of launching an javafx application but i have struggled with this problem for some time and came up with a workaround that does not require to use any external packaging applications, force you to use ant or maven plugin (which conflicts with the shade plugin) etc...
The solution uses Utils4j to load jfxrt dynamically at runtime. You cannot load it in a class extending javafx.application.Application, do it in a separate class and name it for example: Launcher
import org.fuin.utils4j.Utils4J
public class Launcher {
public static void main(String[] args) {
Utils4J.addToClasspath("file:///"+System.getProperty("java.home")+ File.separator+"lib"+File.separator+"jfxrt.jar");
// CODE TO RUN YOUR CLASS THAT EXTENDS javafx.application.Application goes here.
}
}
you can include Utils4j with your project (if using maven):
<dependency>
<groupId>org.fuin</groupId>
<artifactId>utils4j</artifactId>
<version>0.7.0</version>
</dependency>
I use maven and I just run this mvn install:install-file -Dfile="/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib/jfxrt.jar" -DgroupId=com.oracle.javafx -DartifactId=javafx -Dversion=2.2 -Dpackaging=jar in terminal(Maybe a little difference in Windows.). Then maven will install jfxrt.jar then you can simply reference it as
<dependency>
<groupId>com.oracle.javafx</groupId>
<artifactId>javafx</artifactId>
<version>2.2</version>
</dependency>
If you are using netbeans like me and you have two versions of JDK installed, then you should change the classpath to the appropriate java installation in the config file. This is also a bug in Netbeans:
There are two ways to do it:
Either start NetBeans with --jdkhome by executing this:
"C:\Program Files\NetBeans Dev 201402160001\bin\netbeans.exe" --jdkhome "C:\Program Files\Java\jdk1.7.0_51"
Or set the "netbeans_jdkhome" property in /etc/netbeans.conf e.g.
# Default location of JDK, can be overridden by using --jdkhome <dir>:
netbeans_jdkhome="C:\Program Files\Java\jdk1.7.0_51"
IntelliJ and maybe other IDE's do not refactor your Run/Debug configuration. You must manually change your package name preceding the name of your Main class. For instance, change 'sample.Main' to 'com.company.package.ui.Main' so it will launch correctly next time you try to run it. The IDE might have already marked the Run/Debug button with a red cross because it couldn't find the main class. It also gives a warning when you open the Run/Debug configuration.
I already answered it on "Ask ubntu".
I recommend you to go with https://openjfx.io/openjfx-docs/ .i am using Eclipse IDE but it works for all IDE
Then you can refer to this global variable when setting the VM options as:
In IDE Right-click on project->Run As -> Run Configuration ->Arguments->VM Arguments
For Windows,
--module-path "\path to javafx\lib" --add-modules javafx.controls,javafx.fxml
For Linux,
--module-path /path to javafx/lib --add-modules javafx.controls,javafx.fxml
I'm developing on Linux a simple WebApp i got the same error, but is really easy to fix it (assuming you are developing on the command line as myself).
cat compile.sh
#!/bin/bash
/usr/lib/jvm/jdk1.7.0_25/bin/javac WebViewSample.java -cp /usr/lib/jvm/jdk1.7.0_25
/jre/lib/jfxrt.jar
$ cat run.sh
#!/bin/sh
JAVA_HOME=/usr/lib/jvm/jdk1.7.0_25/bin/
CLASSPATH=/usr/lib/jvm/jre1.7.0_25/lib/jfxrt.jar:.
$JAVA_HOME/java -cp $CLASSPATH WebViewSample $* 2>&1 /dev/null | awk -F\| '{ print $2"|"$3 ; exit $1 }'
exit $?
I had a problem of not finding the Pair class from javafx.
It seems that vanilla eclipse (without the e(fx)clipse extension) doesn't search the javaFX runtime jar included with java.
I just added to my eclipse project build path this external jar (or if you are in a debug configuration, add the external jar in the JRE tab of the debug configuration):
$JAVA_HOME/jre/lib/ext/jfxrt.jar
(replace JAVA_HOME with your jdk folder)
For me it was in /installs/jdk1.8.0_211/jre/lib/ext/jfxrt.jar
in eclipse environment: add jfxrt.jar to Bundle-ClassPath in MANIFEST.MF file.
Bundle-ClassPath: .,
jfxrt.jar

Categories

Resources