Could someone give a complete example of calling ObservableValue.subscribe()
from a Gradle project?
Doing the following results in error: cannot find symbol
on subscribe()
:
SimpleObjectProperty<Object> prop = new SimpleObjectProperty<Object>(null);
prop.subscribe(new Consumer<Object>() { public void accept(Object t) {} });
The subscribe()
function was added in JavaFX 21, and I suspect Gradle is using an older version that does not have it, but I cannot figure out how to get Gradle to pick up the new version (if that even is the real problem). I am at my whits end on this.
My build.gradle.kt
:
repositories {
mavenCentral()
}
plugins {
java
application
id("org.openjfx.javafxplugin") version "0.1.0"
}
javafx {
version = "24"
modules("javafx.base")
}
application {
mainClass = "Main"
}
My src/java/main/Main.java
:
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) { launch(args); }
@Override public void start(Stage stage) {
ObservableValue<Object> prop = new SimpleObjectProperty<Object>(null);
prop.subscribe(new Consumer<Object>() { public void accept(Object t) {} });
}
}
The compilation result:
$ ./gradlew build
> Task :compileJava FAILED
/home/user/question/src/main/java/Main.java:11: error: cannot find symbol
prop.subscribe(new Consumer<Object>() { public void accept(Object t) {} });
^
symbol: method subscribe(<anonymous Consumer<Object>>)
location: variable prop of type ObservableValue<Object>
1 error
[Incubating] Problems report is available at: file:///home/user/question/build/reports/problems/problems-report.html
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler output below.
/home/user/question/src/main/java/Main.java:11: error: cannot find symbol
prop.subscribe(new Consumer<Object>() { public void accept(Object t) {} });
^
symbol: method subscribe(<anonymous Consumer<Object>>)
location: variable prop of type ObservableValue<Object>
1 error
* Try:
> Check your code and dependencies to fix the compilation error(s)
> Run with --scan to get full insights.
BUILD FAILED in 924ms
1 actionable task: 1 executed
The code from @Slaw works, but only if I don't use Gradle Wrapper/gradlew
.
So the question becomes: Could someone give a complete example of calling ObservableValue.subscribe() from a Gradle project that uses Gradle wrapper?
Results without gradlew
(using code from @Slaw):
$ tree -a
.
├── build.gradle.kts
├── settings.gradle.kts
└── src
└── main
└── java
└── com
└── example
└── Main.java
6 directories, 3 files
$ gradle -version
------------------------------------------------------------
Gradle 8.10.2
------------------------------------------------------------
Build time: 2024-09-23 21:28:39 UTC
Revision: 415adb9e06a516c44b391edff552fd42139443f7
Kotlin: 1.9.24
Groovy: 3.0.22
Ant: Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM: 21.0.5 (Oracle Corporation 21.0.5+1-nixos)
Daemon JVM: /nix/store/f042x32jfm94d3cgaga8d6xl8vy6sg46-openjdk-21.0.5+11/lib/openjdk (no JDK specified, using current Java home)
OS: Linux 6.6.69 amd64
$ gradle run
> Task :run
Property value = null
Property value = Hello, World!
Property value = Hi, mom!
BUILD SUCCESSFUL in 529ms
2 actionable tasks: 2 executed
Results with gradlew
(using code from @Slaw):
$ tree -a
.
├── build.gradle.kts
├── settings.gradle.kts
└── src
└── main
└── java
└── com
└── example
└── Main.java
6 directories, 3 files
$ gradle wrapper
BUILD SUCCESSFUL in 449ms
1 actionable task: 1 executed
$ ./gradlew -version
------------------------------------------------------------
Gradle 8.10.2
------------------------------------------------------------
Build time: 2024-09-23 21:28:39 UTC
Revision: 415adb9e06a516c44b391edff552fd42139443f7
Kotlin: 1.9.24
Groovy: 3.0.22
Ant: Apache Ant(TM) version 1.10.14 compiled on August 16 2023
Launcher JVM: 21.0.5 (Oracle Corporation 21.0.5+1-nixos)
Daemon JVM: /nix/store/vc52hvhclai81s6yyg7mng0g0mfvnqim-openjdk-21.0.5+11/lib/openjdk (no JDK specified, using current Java home)
OS: Linux 6.6.69 amd64
$ ./gradlew run
> Task :compileJava FAILED
/home/user/question/src/main/java/com/example/Main.java:16: error: cannot find symbol
property.subscribe(value -> System.out.println("Property value = " + value));
^
symbol: method subscribe((value)->S[...]alue))
location: variable property of type SimpleObjectProperty<Object>
1 error
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Compilation failed; see the compiler error output for details.
* Try:
> Run with --info option to get more log output.
> Run with --scan to get full insights.
BUILD FAILED in 446ms
1 actionable task: 1 executed
I have now solved this issue. It was a problem with my Java installation. After discovering that Gradle was behaving differently than Gradle Wrapper, I was able to figure out that they were using different was using a different JAVA_HOME
and different Java installations. In one of my NixOS overlays, I had the following settings:
p.jdk.override {
enableJavaFX = true;
openjfx_jdk = p.openjfx.override { withWebKit = true; };
};
Changing p.openjfx.override
to p.openjfx23.override
fixes the issue.
It still puzzles me that Gradle Wrapper used the JavaFX in my Java installation and not the one specified in build.gradle.kts
, but at least for my system the issue is now resolved.
Based on the error, I would assume the problem is you're not using JavaFX 21+. But your build script clearly shows you using JavaFX 24, so I'm not sure why an older version would be being used. Perhaps one of the following things is causing problems?
The plugins
block is, I believe, supposed to be the first bit of code, other than imports, in the build script file. Though I'm not sure if this is required.
Your Main
class is in the unnamed package.
Your Main
class extends javafx.application.Application
. That latter class comes from the javafx.graphics
module, but you're only depending on the javafx.base
module.
Though I'm not sure why any of those (potential) problems would specifically cause issues with subscribe
. Regardless, here is a minimal example.
<project-directory>
│ build.gradle.kts
│ settings.gradle.kts
│
└───src
└───main
└───java
└───com
└───example
Main.java
settings.gradle.kts
rootProject.name = "subscribe-example"
build.gradle.kts
plugins {
id("org.openjfx.javafxplugin") version "0.1.0"
application
}
repositories {
mavenCentral()
}
javafx {
modules("javafx.base")
version = "24.0.1"
}
application {
mainClass = "com.example.Main"
}
com/example/Main.java
package com.example;
import javafx.beans.property.SimpleObjectProperty;
public class Main {
/*
* The types in the 'javafx.base' module do not require the JavaFX platform
* to be running in order to use them. So, you can simply perform the test
* in the main method without having to extend 'javafx.application.Application'
* or depending on 'javafx.graphics' at all.
*/
public static void main(String[] args) {
var property = new SimpleObjectProperty<>();
property.subscribe(value -> System.out.println("Property value = " + value));
property.set("Hello, World!");
property.set("Hi, mom!");
}
}
PS <project-directory>> gradle run
> Task :run
Property value = null
Property value = Hello, World!
Property value = Hi, mom!
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
And with the wrapper (which still works):
PS <project-directory>> gradle wrapper
BUILD SUCCESSFUL in 1s
1 actionable task: 1 up-to-date
PS <project-directory>> ./gradlew --version
------------------------------------------------------------
Gradle 8.14
------------------------------------------------------------
Build time: 2025-04-25 09:29:08 UTC
Revision: 34c560e3be961658a6fbcd7170ec2443a228b109
Kotlin: 2.0.21
Groovy: 3.0.24
Ant: Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM: 24.0.1 (Eclipse Adoptium 24.0.1+9)
Daemon JVM: C:\Program Files\Eclipse Adoptium\jdk-24.0.1.9-hotspot (no JDK specified, using current Java home)
OS: Windows 10 10.0 amd64
PS <project-directory>> ./gradlew run
> Task :run
Property value = null
Property value = Hello, World!
Property value = Hi, mom!
BUILD SUCCESSFUL in 1s
2 actionable tasks: 1 executed, 1 up-to-date