Reputation: 1
I'm trying to run a simple TestFX application on RHEL 9.4. It works fine in 'normal' mode, but for CI I need to also run in headless mode. I'm using Java 1.8.0_431 and Monocle 1.8.0_20.
Running from a CLI, I use the following:
mvn clean install -Dtestfx.headless=true -Dtestfx.robot=glass -Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw -Dprism.txt=t2K -Dheadless.geometry=16000x12000-32 -Djavafx.platform=linux -Djava.awt.headless=true -X
This gives the following fault:
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.178 sec <<< FAILURE!
com.example.TestFXExampleTest Time elapsed: 0.177 sec <<< ERROR!
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NoClassDefFoundError: com/sun/glass/ui/Robot
at org.testfx.util.WaitForAsyncUtils.waitFor(WaitForAsyncUtils.java:301)
at org.testfx.api.FxToolkit.registerPrimaryStage(FxToolkit.java:113)...
If I run from IntelliJ, I'm passing "-Dheadless=true" which executes the following:
@BeforeClass
public static void setUpHeadlessMode() throws Exception {
if (Boolean.getBoolean("headless")) {
// System.setProperty("javafx.platform", "monocle");
System.setProperty("testfx.robot", "glass");
System.setProperty("testfx.headless", "true");
System.setProperty("glass.platform", "Monocle");
System.setProperty("monocle.platform", "Headless");
System.setProperty("prism.order", "sw");
System.setProperty("prism.text", "t2k");
System.setProperty("java.awt.headless", "true");
}
registerPrimaryStage();
}
And this gives me:
java.lang.NoSuchMethodException: com.sun.glass.ui.Screen.<init>(long, int, int, int, int, int, int, int, int, int, int, int, float)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at com.sun.glass.ui.monocle.MonocleApplication$2.run(MonocleApplication.java:234) ...
Both of these errors seem to suggest that there is a missing library, although not the same one. I've seen numerous discussions about TestFX, but most are either for later java versions, or are for Windows, or are not about headless mode.
The fact that the test app builds and runs in headed mode suggests the POM is probably ok, although I can provide (a redacted) version of that if this might be useful. The relevant bits are:
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11</version>
</dependency>
On Windows, the headless components are provided by the native 'glass.dll' and (providing you magically get the right version) this works fine. I'm assuming there should be a similar '.so' for Linux, but so far have not located one. (And I'm not 100% sure this is actually the correct diagnosis or fix anyway.)
I'm expecting headless to work as it does in Windows. So far I've tried numerous combinations of Monocle version, mvn switches, and VMArgs.
The machine is heavily locked-down, so I can't do things like easily install new software or grab thing directly from Github. But previous attempts on a similar machine have also failed to run headless mode tests.
Upvotes: 0
Views: 35
Reputation: 159341
JavaFX 11 does not work with Java 8.
Also, you can't mix and match versions of JavaFX software (e.g. try to use JavaFX monocle 1.8 with JavaFX 11).
Use a modern Java and JavaFX version (e.g. 21 LTS or 23). Getting started instructions.
I don't use TestFX, but there are probably documents or example projects that can be used with your chosen continuous integration system. Note that the document says it "has only legacy support," so the code and documentation are not likely fully maintained.
JavaFX monocle is poorly documented, so you might find it hard to get information on it. As far as I understand, it is a customized version of JavaFX for headless systems, and you need to use classified dependencies instead of unclassified JavaFX dependencies. Monocle is not built for all JavaFX versions (I don't know if it is even fully maintained). The classified dependencies for JavaFX 21 monocle can be found in Maven Central. I won't answer here how to use it as I don't use it.
In fact, JavaFX 11 is fine with Java 8.
While you may have been able to get the combo to perform the functions you needed, the JavaFX 11 release has a minimum Java version of 11, so the combination was never supported. There is no official documentation on similar deployments.
It's only the glass windowing which isn't working.
The Glass Windowing Tookit is a key component of the JavaFX architecture. If it is not working, then parts of the installation are broken.
I'll change the JavaFX version as another 'clutching at straws' exercise, though. Changing java version, might be viable just for testing.
If your app is deployed on Java 8, using a non-Java 8 version of Java/JavaFX for tests would not be advisable. My earlier advice was to upgrade the Java and JavaFX versions, not one or the other.
production will not even be using the Oracle VM.
Most Java 8 versions don't include JavaFX. Oracle was the major vendor including JavaFX in some Java 8 distributions. However, there may be some ways to add JavaFX 8 support to other Java distributions if you can find the right procedures to do so. I'd recommend only JavaFX 8 distributions certified to work with the Java 8 version provided by your Java runtime vendor (so that would not include any versions hosted in Maven central).
And as you say, Monocle support and documentation are a 'bit sketchy'.
Yeah, I have no idea how you would find a version of JavaFX 8 for whatever Java 8 distribution you are using that also supports Monocle.
The TestFX framework documentation states "TestFX 4 requires Java version of 8 (1.8), or higher, and has only legacy support.". So likely your best bet is to refer to the TestFX documentation for Java 8 installations. That is if it still exists - I haven't read their documentation - otherwise, you could try contacting or hiring the original TestFX developers if you could find them to get assistance on getting it set up for your environment.
While I'm happy using and developing on the Java platform, the intricacies of versions and their interactions is something I've not had to cope with so far.
Many things in Java ecosystem are backwards compatible, at least as regards to core JDK features (third party libraries tend to be less well maintained as per backward compatibility).
However, JavaFX includes both native and Java code, making compatibility more complicated than pure Java code. Additionally, JavaFX was split from the JDK runtime for Java 11 and adopted the Java module system, which allows it to evolve separately from the Java system in later versions but not in earlier versions.
To address some of those issues, modern JavaFX versions have a getting started guide which references sample code which should work when used with a compatible Java runtime.
On the JavaFX download page, Gluon provides a matrix of which JavaFX versions are compatible with which Java runtimes.
For long-term stable combinations of JavaFX and runtime versions, you can adopt the Long Term Service (LTS) release of each (which receives official support, both free and with a paid option, for numerous consecutive years).
Upvotes: 1