javagradleintellij-ideajavafx

Dependency of a JavaFX module to another Java Gradle module fails in IntelliJ


I am running IntelliJ IDEA Community Edition 2024.1.4 and want to create a simple project with multiple inter-dependent modules using Gradle and Java 21.

The root directory contains a settings.gradle:

rootProject.name = 'demo'
include 'the-library'
include 'core'
include 'ui'

and in the root I have 3 modules: "the-library", "core" and "ui".

First, I want to use code from the-library in the core module, so in the core's build gradle it says

dependencies {
    implementation project(':the-library')
    ...
}

Works like a charm, I can use the-library's code in the core module.

Now to the issue: I also created a ui module using JavaFX (went through IntellJ's "New Module" wizard and created a JavaFX module). In its build.gradle I added the dependency to the core:

dependencies {
  implementation('com.github.almasb:fxgl:17.3') {
    exclude(group: 'org.openjfx')
    exclude(group: 'org.jetbrains.kotlin')
  }

  implementation project(':core')
  testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
  testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}

But a Gradle sync reveals an error:

FAILURE: Build failed with an exception.

* Where:
Build file 'D:\dev\demo\ui\build.gradle' line: 43

* What went wrong:
A problem occurred evaluating root project 'ui'.
> Project with path ':core' could not be found in root project 'ui'.

The problem seems to be related to the nature of the JavaFX-based module, because otherwise 'core' would not be able to have a successful dependency to 'the-library' as mentioned before.

Anyone can help me please?


Solution

  • Having no second settings.gradle was definitely an issue, thanks for pointing that out, Simon!

    I finally have resolved my issue by using a workaround:

    Instead of creating a JavaFX module from the wizard, create a simple Java module and import all JavaFX later (just import the javafxplugin in the ui module's Gradle)

    plugins {
        id 'java'
        id 'org.openjfx.javafxplugin' version '0.1.0'
    }
    

    Add the desired module dependencies in the ui's gradle just as described above

    dependencies {
        implementation project(':core')
        testImplementation platform('org.junit:junit-bom:5.10.0')
        testImplementation 'org.junit.jupiter:junit-jupiter'
    ...
    }
    

    Wrap the UI's entry point in another class, otherwise IntelliJ will complain with

    "JavaFX runtime components are missing, and are required to run this application":

    This works:

    public class HelloWorld
    {
        public static class TheUI extends Application
        {
            @Override
            public void start(Stage primaryStage) {
                primaryStage.setTitle("Hello World!");
                Button btn = new Button();
                ...
                primaryStage.setScene(new Scene(root, 300, 250));
                primaryStage.show();
            }
        }
        public static void main(String[] args) {
            Application.launch(TheUI.class); // main entry point
        }
    }
    

    Et voilĂ , you can write a UI application accessing other modules' functionality.