javacssjavafxopenjfxopenjdk-11

OpenJFX 11 - javafxpackager Binary CSS


It seems like the JavaFXpackager isn't available in the openjdk/openjfx 11.

I want to create the binary CSS (BSS) using it.
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javafxpackager.html
with the -createbss it was possible in the past.

In the OpenJFX mailing list, they posted something about Filling the Packager gap.
https://mail.openjdk.java.net/pipermail/openjfx-dev/2018-September/022500.html

But this new tool cant create Binary CSS.

My question is: Is there still a way to generate the binary css using OpenJFX 11 or is the whole thing not supported anymore?


Solution

  • While there is a jpackage tool that is possibly being added to Java 14, I'm not aware that it is going to use Css2Bin.

    In OpenJFX (11+), Css2Bin is still a tool used internally to convert the Modena CSS files into BSS. You can find it here.

    If you search the uses of this tool within OpenJFX, you will find it in the build.gradle file that is used to build JavaFX itself.

    I'll paste the task, as it is relevant to see what it does:

    def modulePath = "${project.sourceSets.main.java.outputDir}"
        modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.graphics/build/classes/java/main"
        modulePath += File.pathSeparator + "${rootProject.projectDir}/modules/javafx.base/build/classes/java/main"
        processResources {
          doLast {
            def cssFiles = fileTree(dir: "$moduleDir/com/sun/javafx/scene/control/skin")
            cssFiles.include "**/*.css"
            cssFiles.each { css ->
                logger.info("converting CSS to BSS ${css}");
    
                javaexec {
                    executable = JAVA
                    workingDir = project.projectDir
                    jvmArgs += patchModuleArgs
                    jvmArgs += "--module-path=$modulePath"
                    jvmArgs += "--add-modules=javafx.graphics"
                    main = "com.sun.javafx.css.parser.Css2Bin"
                    args css
                }
            }
          }
        }
    

    As you can notice, basically a java command is called, with the JavaFX jars in the module path, to run the Css2Bin::main public method, which is just part of the javafx.graphics included module.

    So nothing prevents you from doing exactly the same in your build process.

    Assuming you are using Gradle, you can add a task that is executed before the jar task, something like this:

    def java_home = hasProperty('org.gradle.java.home') ? 
          getProperty('org.gradle.java.home') : System.getenv('JAVA_HOME')
    
    task css {
        if (java_home == null) {
            throw new RuntimeException("java_home is not defined.")
        }
        def cssFiles = fileTree(dir: "$project.rootDir/src/main/resources/")
        cssFiles.include "**/*.css"
        cssFiles.each { css ->
            logger.info("converting CSS to BSS ${css}")
            doLast {
                exec {
                    commandLine "${java_home}/bin/java",
                            "--module-path", sourceSets.main.runtimeClasspath.asPath,
                            "--add-modules", "javafx.graphics",
                            "com.sun.javafx.css.parser.Css2Bin", css
                }
            }
        }
    }
    

    Simply run:

    ./gradlew css
    

    and it will convert all the css files in your resources to bss. Then you will probably need to filter out the css ones when doing the jar.

    Same task can be run in a similar way from Maven or command line, of course.