I figured out a workaround:
1. Detect the OS and architecture and set the classifier based on that
2. Use Grape.grab instead of @Grab to download the platform
implementation explicitly
3. Use the main method of the Application instead of explicitly calling
Application.launch(..) to make the script compile
(javafx.application.Application is not available yet due to Grape.grab().
The working script is as follows:
@Grab('org.openjfx:javafx-controls:21.0.6')
@Grab('org.openjfx:javafx-web:21.0.6')
@Grab('org.openjfx:javafx-media:21.0.6')
@Grab('org.openjfx:javafx-swing:21.0.6')
@Grab('se.alipsa:gade:1.0.0-SNAPSHOT')
import se.alipsa.gade.Gade
String os =System.getProperty("os.name")
String arch =System.getProperty("os.arch")
String classifier ="" if (os =="Linux") {
if (arch =="aarch64") {
classifier="linux-aarch64" }else {
classifier ="linux" }
}else if (os =="Mac OS X") {
if (arch =="aarch64") {
classifier ="mac-aarch64" }else {
classifier ="mac" }
}else if (os =="Windows") {
if (arch =="amd64") {
classifier ="win" }else {
classifier ="win-x86" }
}else {
println"Unknown OS: $os, arch: $arch" System.exit(1)
}
def javafxVersion='21.0.6'
Grape.grab(group:'org.openjfx',module:'javafx-base',version:"$javafxVersion",classifier:"$classifier")
Grape.grab(group:'org.openjfx',module:'javafx-graphics',version:"$javafxVersion",classifier:"$classifier")
Grape.grab(group:'org.openjfx',module:'javafx-controls',version:"$javafxVersion",classifier:"$classifier")
Grape.grab(group:'org.openjfx',module:'javafx-web',version:"$javafxVersion",classifier:"$classifier")
Grape.grab(group:'org.openjfx',module:'javafx-media',version:"$javafxVersion",classifier:"$classifier")
Grape.grab(group:'org.openjfx',module:'javafx-swing',version:"$javafxVersion",classifier:"$classifier")
Gade.main()
I think @Grab should have been able to handle this for me or am i wrong?
Regards,
Per
On 4/8/25 20:31, Per Nyfelt wrote:
Hi,
I have a javafx application published to a nexus server that I want to
launch from a groovy script.
The application has javafx jar defined as compileOnly (provided in
maven lingo) so javafx must be added to the classpath.
When i use a full jdk that includes javafx the applicaton works great
but for some reason @Grab does not play well with javafx (i have no
issues with other dependencies)
The script (called gade.groovy) looks like this:
@Grab('org.openjfx:javafx-controls:21.0.6')
@Grab('org.openjfx:javafx-web:21.0.6')
@Grab('org.openjfx:javafx-media:21.0.6')
@Grab('org.openjfx:javafx-swing:21.0.6')
@Grab('se.alipsa:gade:1.0.0-SNAPSHOT')
import se.alipsa.gade.Gade
import org.openjfx.application.Application
this.class.classLoader.URLs.each { url ->
if (url.toExternalForm().contains("javafx")) {
println "URL: $url"
}
}
Application.launch(Gade.class, [] as String[])
Running it with `groovy gade.groovy` results in
unable to resolve class org.openjfx.application.Application
@ line 21, column 1.
import org.openjfx.application.Application
If i remove the Application import and Applicaton.launch lines the
output is
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-swing/jars/javafx-swing-21.0.6.jar
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-graphics/jars/javafx-graphics-21.0.6.jar
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-base/jars/javafx-base-21.0.6.jar
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-media/jars/javafx-media-21.0.6.jar
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-web/jars/javafx-web-21.0.6.jar
URL:
file:/home/username/.groovy/grapes/org.openjfx/javafx-controls/jars/javafx-controls-21.0.6.jar
When examining the content of e.g. javafx-controls-21.0.6.jar in the
grapes cache reveals an essentially empty file (just the META-INF dir)
which leads me to believe that the transient classifier platform
implementation jars was not fetched properly and added to the
classpath. Does anyone know if there a way to get @Grab to play
nicely with javafx?
Regards,
Per