mavendockerjavafxbitbucket-pipelinesopenjdk-8

Building JavaFx application using Bitbucket pipelines


I am trying to build JavaFx project using bitbucket pipelines. For that I am using maven:3-jdk-8 docker image. This Docker image uses OpenJDK 8 instead of Oracle's one (due to the lincensing issue) which does not include the JavaFx part. Note that I have to use Java 8 to build my project! Problem that I am getting is that I am not able to build the application using that docker image alone.

As proposed in an answer to the same question (https://stackoverflow.com/a/40167253/2000338): I tried using this bitbucket-pipelines.yml to try to overcome the situation:

image: maven:3-jdk-8

pipelines:
  default:
    - step:
        script: # Modify the commands below to build your repository.
          - apt-get update
          - apt-get install -y openjfx
          - mvn clean install # -B batch mode makes Maven less verbose

In step 2 it seems that openjfx is installed properly. But in step 3 I am getting following error:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project ***********: Compilation failure: Compilation failure: 
[ERROR] /opt/atlassian/pipelines/agent/build/src/main/java/********/******/****/MainFx.java:[7,26] package javafx.application does not exist

It seams that it is still complaining on the JavaFx libraries missing, but I am not aware of why. On my developer machine (Windows 7, jdk1.8.0_221) I can execute maven build without an issue.


Solution

  • What was missing in previous approach is that the javafx library was not on the classpath. Basically in order to make maven build work I had to add the jfxrt.jar to the classpath. I found that in the maven:3-jdk-8 image after installing javafx the library can be found in: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jfxrt.jar

    Adding this file to a classpath during build run will do the trick.

    One idea (that worked for me) is to include this library in application pom/dependecy part as a system scope.

    In my case I made a maven profile for that:

        <profiles>
        <profile>
            <id>docker_build</id>
            <activation>
                <activeByDefault>false</activeByDefault>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>com.oracle</groupId>
                    <artifactId>javaFX</artifactId>
                    <version>2.2</version>
                    <scope>system</scope>
                    <systemPath>${javafx-location}</systemPath>
                </dependency>
            </dependencies>
        </profile>
    </profiles>
    

    In order to run this maven build you have to issue proper maven command to add this profile. E.g.

    mvn clean install -P docker_build -Djavafx-location=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jfxrt.jar
    

    To simplify this I made a Docker image using following Dockerfile:

    FROM maven:3-jdk-8
    RUN apt-get update && \
        apt-get install -y --no-install-recommends openjfx
    COPY settings.xml /root/.m2/
    

    which uses following maven settings.xml file:

    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
        <localRepository>/usr/share/maven/ref/repository</localRepository>
        <activeProfiles>
            <activeProfile>docker_build</activeProfile>
        </activeProfiles>
        <profiles>
            <profile>
                <id>docker_build</id>
            <properties>
                <javafx-location>/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jfxrt.jar</javafx-location>
            </properties>
            </profile>
        </profiles>
    </settings>
    

    I also published it to the Docker hub if somebody may find it useful: https://hub.docker.com/r/brzigonzales/maven-javafx