2

When I run the gradle "run" task, i cannot finish compiling java, as I get many errors of the form:"error: package javafx.XXXXX does not exist" for all of the javaFX imports. My test project can do imports just fine, although it isn't using gradle to compile.

I am trying to get a client's program "BilliardViewer" running on a Ubuntu VM. It has been through the hands of many programmers, some of which likely may not have had that much experience doing coding. I'm not sure whether this is a gradle issue, and eclipse issue, a library issue, or a coding issue. I know that the JavaFX library is properly installed, since I can run a separate HelloWorld jfx program. The only difference in the build paths between the two is that the BilliardViewer program has some external dependencies, since it uses C++ as well as Java. The program currently runs on his Mac, with I believe MacOS Mojave.

My HelloWorld Program, which works.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
...

@Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Hello World!");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                System.out.println("Hello World!");
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

Some code from the BilliardViewer Program, which does not work (Colors.java)

import java.util.Optional;

import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
...

public ColorPicker(final int x, final int y) {
        stage.setX(x);
        stage.setY(y);

        stage.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
            if (!isNowFocused) {
                stage.hide();
            }
        });

        stage.setScene(new Scene(grid));
        stage.setTitle("SO COLORFUL");
        grid.setPadding(new Insets(10));

        for (int row = 0; row < ROWS; row++) {
            for (int col = 0; col < COLS; col++) {
                final Color currentColor = color[row][col];

                final Rectangle rect = new Rectangle(RECT_SIZE, RECT_SIZE, currentColor);

                rect.setOnMouseClicked(event -> {
                    selectedColor = Optional.of(currentColor);
                    stage.close();
                });

                Tooltip.install(rect, new Tooltip(Colors.colorMap.get(currentColor).get()));

                grid.add(rect, col, row);
            }
        }
    }

I expected the build to at least be able to compile java, since the exact same code compiles just fine on the client's Mac laptop.

EDIT: build.gradle

apply plugin: 'cpp'
apply plugin: TestingModelBasePlugin
//apply plugin: 'findbugs'

mainClassName = 'billiards.viewer.Main'

repositories {
    jcenter()
}

dependencies {
    // When getting the version number for a dependency, don't go to Maven Central and
    // simply search for the package you want. You will often find many versions of the
    // package, most of which are unofficial or out-of-date. Instead, go to the website
    // of the package, and they will usually give you the correct Maven information there.
    compile 'org.eclipse.collections:eclipse-collections-api:9.2.0'  // All the interfaces
    compile 'org.eclipse.collections:eclipse-collections:9.2.0'  // The actual classes
    compile 'com.google.guava:guava:25.1-jre'
    compile 'org.apache.commons:commons-math3:3.6.1'
    compile 'org.apache.commons:commons-lang3:3.7'  // can remove this now I think?
    compile 'org.apache.commons:commons-io:1.3.2'
    compile 'io.javaslang:javaslang:2.0.5'
    compile 'org.xerial:sqlite-jdbc:3.23.1'
    compile 'net.java.dev.jna:jna:4.5.1'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
}

test {
    useJUnitPlatform()
}

compileJava {
    options.compilerArgs << '-Xlint' << '-Werror'
}

jar {
    baseName = 'billiard-viewer'
    manifest.attributes 'Main-Class': 'billiards.viewer.Main'
}

sourceSets {
    main {
        java {
            srcDir 'src/java'
        }

        //resources {
            //srcDir 'css'
        //}
    }
}

applicationDefaultJvmArgs = ['-server', '-Djna.library.path=./build/libs/backend/shared', '-Xss10000m']

sourceCompatibility = 1.8
targetCompatibility = 1.8

model {

    components {

        backend(NativeLibrarySpec) {

            binaries.all {

                cppCompiler.define "NDEBUG"
                cppCompiler.args '-O3', '-march=native', '-flto', '-ftrapv'
                linker.args '-lgmp', '-lmpfr', '-lmpfi', '-lsqlite3', '-ltbb'

                if (toolChain in Clang) {
                    cppCompiler.args '-Weverything', '-Werror',
                                     '-Wno-padded', '-Wno-comma',
                                     '-Wno-exit-time-destructors', '-Wno-global-constructors',
                                     '-Wno-c++98-compat', '-Wno-c++98-compat-pedantic',
                                     '-std=c++14'
                }

                if (toolChain in Gcc) {
                    cppCompiler.args '-Wall', '-Wextra', '-Wpedantic', '-Werror',
                                     '-Wno-c++11-compat', '-Wno-c++14-compat',
                                     '-std=c++14'
                }

                checkedBy $.tasks.testBackend
            }
        }

        test(NativeExecutableSpec) {

            sources.cpp {
                lib library: 'backend', linkage: 'static'
            }

            binaries.all {

                cppCompiler.define "NDEBUG"
                cppCompiler.args '-O3', '-march=native', '-flto', '-ftrapv'
                linker.args '-lgmp', '-lmpfr', '-lmpfi', '-lboost_unit_test_framework'

                if (toolChain in Clang) {
                    cppCompiler.args '-Weverything', '-Werror',
                                     '-Wno-padded', '-Wno-comma',
                                     '-Wno-disabled-macro-expansion', '-Wno-global-constructors',
                                     '-Wno-c++98-compat', '-Wno-c++98-compat-pedantic',
                                     '-std=c++14'
                }

                if (toolChain in Gcc) {
                    cppCompiler.args '-Wall', '-Wextra', '-Wpedantic', '-Werror',
                                     '-Wno-c++11-compat', '-Wno-c++14-compat',
                                     '-std=c++14'
                }
            }
        }
    }
}

task testBackend(type: Exec, dependsOn: 'testExecutable') {
    commandLine 'build/exe/test/test'

    // save the results here
    //standardOutput = new FileOutputStream('build/test-results/test.out')
    //errorOutput = new FileOutputStream('build/test-results/test.err')
}

// Make sure the C++ code is up to date when running the Java program
run.dependsOn "backendSharedLibrary"
//run.dependsOn "coverExecutable"

run.doFirst {
    // Having this hardcoded isn't the best, put it works for now
    //environment 'LD_PRELOAD', '/usr/local/Cellar/jemalloc/5.0.1/lib/libjemalloc.so.2'
    //commandLine "./test.fish"
}
  • If it's a Gradle task that's failing the issue is probably with Gradle. Can you show your `build.gradle` (or `build.gradle.kts`) file? – Slaw Jul 17 '19 at 00:42
  • Hi @Slaw thanks for responding. Ive edited my original post to include the `build.gradle` file. The only other files i can see related to gradle are: `gradlew`, `gradlew.bat`, and two files within >gradle>wrapper> directory`gradle-wrapper.jar` and `gradle-wrapper.properties`. – Cameron Ridderikhoff Jul 17 '19 at 19:36
  • Your question, as well as the fact you're using Linux, seems to indicate that JavaFX is not part of the JDK you're using. However, I'm not seeing anywhere in the Gradle configuration where you add the JavaFX library to the dependencies of your project. Note if you're using JavaFX 11+ you might want to check out [Getting Started with JavaFX](https://openjfx.io/openjfx-docs/). I'm also not entirely sure where the `java` (or `application`) plugin is being applied. And don't worry about those other files, they're related to the Gradle Wrapper. – Slaw Jul 17 '19 at 21:08
  • To possibly clarify, JavaFX was part of the OracleJDK until Java 11. Since then it's been a separate library. However, JavaFX was never part of OpenJDK distributions, which I believe is what is used (at least by default) on Linux machines. – Slaw Jul 17 '19 at 21:11
  • Im using JavaFX 8 I believe. I downloaded the jdk from [the Oracle website](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html), and I know for a fact that this release of java has the jfxrt.jar file, as I can see it when I check the build path. I tried downloading Openjdk and Openjfx, but neither install included the jfxrt.jar (which i believe is what contains the libraries). When i had a quick look around, I couldnt find anything on how to add javafx to the gradle configuration for javafx8 – Cameron Ridderikhoff Jul 17 '19 at 22:25
  • Hi @Slaw, I have determined that this issue is definitely a gradle issue. I performed another test, where I created a gradle project with the same code as the other HelloWorld project. It fails with the same issues as the BilliardViewer when i use JavaFX, but it builds without errors when i dont use javafx – Cameron Ridderikhoff Jul 18 '19 at 17:43
  • Do you perchance have more than one JDK installed on your machine? If so, can you check which JDK Gradle is using? – Slaw Jul 18 '19 at 19:49
  • I do happen to have more than one JDK installed, but i dont know how to check which one gradle is using. – Cameron Ridderikhoff Jul 18 '19 at 19:50
  • By default it uses the value of the `JAVA_HOME` environment variable. However, you can check explicitly; [this answer](https://stackoverflow.com/a/53763654/6395627) shows one way. – Slaw Jul 18 '19 at 19:52
  • Thanks @Slaw, by adding a gradle.properties file showing the gradle where to look for the JDK, and that actually fixed it. Thanks so much. – Cameron Ridderikhoff Jul 18 '19 at 21:32

1 Answers1

0

I ended up solving this issue by adding a gradle.properties file to my eclipse project, which showed gradle where to look for the JDK, according to stackoverflow. So to clarify, I had to install a JDK, and point gradle to that JDK.

  • 1
    Just to note, the `gradle.properties` file tends to be part of the project (i.e. present on everyone's computers). If you have an absolute path to a JDK in there it may break if you use a different computer (can get really bad if this is a team project). Consider specifying it in the command line (e.g. through Eclipse configurations) so the setting is specific to your one environment. IntelliJ has a setting where you can have it execute Gradle with the same JDK as the one the project is using; I'm not sure if Eclipse has something similar. – Slaw Jul 18 '19 at 22:08