Skip to content

Commit 9f43de5

Browse files
Fix ConfigurationCache (#170)
Co-authored-by: Abhinay Agarwal <abhinay.agarwal@gluonhq.com>
1 parent 2053cc7 commit 9f43de5

10 files changed

+248
-55
lines changed

src/main/java/org/openjfx/gradle/JavaFXModule.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Gluon
2+
* Copyright (c) 2018, 2025, Gluon
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
3131

3232
import org.gradle.api.GradleException;
3333

34+
import java.util.Collection;
3435
import java.util.List;
3536
import java.util.Locale;
3637
import java.util.Optional;
@@ -81,16 +82,15 @@ public boolean compareJarFileName(JavaFXPlatform platform, String jarFileName) {
8182
return p.matcher(jarFileName).matches();
8283
}
8384

84-
public static Set<JavaFXModule> getJavaFXModules(List<String> moduleNames) {
85+
public static Set<JavaFXModule> getJavaFXModules(Collection<String> moduleNames) {
8586
validateModules(moduleNames);
86-
8787
return moduleNames.stream()
8888
.map(JavaFXModule::fromModuleName)
8989
.flatMap(Optional::stream)
9090
.collect(Collectors.toSet());
9191
}
9292

93-
public static void validateModules(List<String> moduleNames) {
93+
public static void validateModules(Collection<String> moduleNames) {
9494
var invalidModules = moduleNames.stream()
9595
.filter(module -> JavaFXModule.fromModuleName(module).isEmpty())
9696
.collect(Collectors.toList());

src/main/java/org/openjfx/gradle/JavaFXOptions.java

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Gluon
2+
* Copyright (c) 2018, 2025, Gluon
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -36,13 +36,14 @@
3636
import org.gradle.api.artifacts.dsl.RepositoryHandler;
3737
import org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository;
3838
import org.gradle.api.model.ObjectFactory;
39+
import org.gradle.api.provider.Property;
40+
import org.gradle.api.provider.SetProperty;
3941
import org.gradle.api.tasks.SourceSetContainer;
4042
import org.gradle.nativeplatform.MachineArchitecture;
4143
import org.gradle.nativeplatform.OperatingSystemFamily;
4244

4345
import javax.inject.Inject;
4446
import java.io.File;
45-
import java.util.ArrayList;
4647
import java.util.HashMap;
4748
import java.util.HashSet;
4849
import java.util.List;
@@ -54,13 +55,13 @@ abstract public class JavaFXOptions {
5455

5556
static final String MAVEN_JAVAFX_ARTIFACT_GROUP_ID = "org.openjfx";
5657
private static final String JAVAFX_SDK_LIB_FOLDER = "lib";
58+
private final SetProperty<String> modules;
59+
private final Property<JavaFXPlatform> platform;
5760

58-
private JavaFXPlatform platform;
5961

6062
private String version = "17";
6163
private String sdk;
6264
private String[] configurations = new String[] { "implementation" };
63-
private List<String> modules = new ArrayList<>();
6465
private FlatDirectoryArtifactRepository customSDKArtifactRepository;
6566

6667
private final SourceSetContainer sourceSets;
@@ -80,11 +81,18 @@ abstract public class JavaFXOptions {
8081

8182
public JavaFXOptions(SourceSetContainer sourceSets, OsDetector osDetector) {
8283
this.sourceSets = sourceSets;
83-
platform = JavaFXPlatform.detect(osDetector);
84+
platform = getObjects().property(JavaFXPlatform.class);
85+
getFxPlatform().convention(JavaFXPlatform.detect(osDetector));
8486
setClasspathAttributesForAllSourceSets();
87+
modules = getObjects().setProperty(String.class);
8588
}
8689

90+
8791
public JavaFXPlatform getPlatform() {
92+
return getFxPlatform().get();
93+
}
94+
95+
public Property<JavaFXPlatform> getFxPlatform(){
8896
return platform;
8997
}
9098

@@ -94,7 +102,7 @@ public JavaFXPlatform getPlatform() {
94102
* Supported classifiers are linux, linux-aarch64, win/windows, osx/mac/macos or osx-aarch64/mac-aarch64/macos-aarch64.
95103
*/
96104
public void setPlatform(String platform) {
97-
this.platform = JavaFXPlatform.fromString(platform);
105+
this.getFxPlatform().set(JavaFXPlatform.fromString(platform));
98106
setClasspathAttributesForAllSourceSets();
99107
}
100108

@@ -108,10 +116,10 @@ private void setClasspathAttributesForAllSourceSets() {
108116
private void setClasspathAttributes(Configuration classpath) {
109117
classpath.getAttributes().attribute(
110118
OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE,
111-
getObjects().named(OperatingSystemFamily.class, platform.getOsFamily()));
119+
getObjects().named(OperatingSystemFamily.class, platform.get().getOsFamily()));
112120
classpath.getAttributes().attribute(
113121
MachineArchitecture.ARCHITECTURE_ATTRIBUTE,
114-
getObjects().named(MachineArchitecture.class, platform.getArch()));
122+
getObjects().named(MachineArchitecture.class, platform.get().getArch()));
115123
}
116124

117125
public String getVersion() {
@@ -168,12 +176,17 @@ public String[] getConfigurations() {
168176
return configurations;
169177
}
170178

171-
public List<String> getModules() {
179+
public SetProperty<String> getFxModules() {
172180
return modules;
173181
}
174182

183+
public Set<String> getModules() {
184+
return modules.get();
185+
}
186+
175187
public void setModules(List<String> modules) {
176-
this.modules = modules;
188+
this.modules.set(modules);
189+
177190
}
178191

179192
public void modules(String...moduleNames) {
@@ -190,7 +203,7 @@ private void declareFXDependencies(String conf) {
190203
return;
191204
}
192205

193-
var javaFXModules = JavaFXModule.getJavaFXModules(this.modules);
206+
var javaFXModules = JavaFXModule.getJavaFXModules(getModules());
194207
if (customSDKArtifactRepository == null) {
195208
javaFXModules.stream()
196209
.sorted()

src/main/java/org/openjfx/gradle/JavaFXPlatform.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Gluon
2+
* Copyright (c) 2018, 2025, Gluon
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without

src/main/java/org/openjfx/gradle/JavaFXPlugin.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Gluon
2+
* Copyright (c) 2018, 2025, Gluon
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -31,19 +31,19 @@
3131

3232
import com.google.gradle.osdetector.OsDetector;
3333
import com.google.gradle.osdetector.OsDetectorPlugin;
34-
import org.gradle.api.GradleException;
35-
import org.gradle.api.NonNullApi;
36-
import org.gradle.api.Plugin;
37-
import org.gradle.api.Project;
34+
import org.gradle.api.*;
3835
import org.gradle.api.file.FileCollection;
3936
import org.gradle.api.plugins.ApplicationPlugin;
4037
import org.gradle.api.plugins.JavaBasePlugin;
38+
import org.gradle.api.provider.Property;
39+
import org.gradle.api.provider.SetProperty;
4140
import org.gradle.api.tasks.JavaExec;
4241
import org.gradle.api.tasks.SourceSetContainer;
4342
import org.gradle.util.GradleVersion;
4443
import org.openjfx.gradle.metadatarule.JavaFXComponentMetadataRule;
4544

4645
import java.io.File;
46+
import java.util.ArrayList;
4747
import java.util.Arrays;
4848
import java.util.List;
4949

@@ -54,10 +54,9 @@ public class JavaFXPlugin implements Plugin<Project> {
5454

5555
@Override
5656
public void apply(Project project) {
57-
if (GradleVersion.current().compareTo(GradleVersion.version("6.1")) < 0) {
58-
throw new GradleException("This plugin requires Gradle 6.1+");
57+
if (GradleVersion.current().compareTo(GradleVersion.version("6.4")) < 0) {
58+
throw new GradleException("This plugin requires Gradle 6.4+");
5959
}
60-
6160
// Make sure 'java-base' is applied first, which makes the 'SourceSetContainer' available.
6261
// More concrete Java plugins that build on top of 'java-base' – like 'java-library' or 'application' –
6362
// will be applied by the user.
@@ -83,39 +82,48 @@ public void apply(Project project) {
8382
// and other Java-base plugins like Kotlin JVM)
8483
project.getPlugins().withId("java", p -> javaFXOptions.setConfiguration("implementation"));
8584

86-
// Only do addition configuration of the ':run' task when the 'application' plugin is applied.
87-
// Otherwise, that task does not exist.
88-
project.getPlugins().withId("application", p -> {
89-
project.getTasks().named(ApplicationPlugin.TASK_RUN_NAME, JavaExec.class, execTask -> {
90-
if (GradleVersion.current().compareTo(GradleVersion.version("6.4")) >= 0 && execTask.getMainModule().isPresent()) {
91-
return; // a module, as determined by Gradle core
85+
86+
project.afterEvaluate(new Action<Project>() {
87+
@Override
88+
public void execute(Project project) {
89+
if (!project.getPlugins().hasPlugin("application") ||
90+
(project.getPlugins().hasPlugin("org.javamodularity.moduleplugin")) && project.getExtensions().findByName("modulename") != null) {
91+
return;
9292
}
9393

94-
execTask.doFirst(a -> {
95-
if (execTask.getExtensions().findByName("moduleOptions") != null) {
96-
return; // a module, as determined by modularity plugin
94+
project.getTasks().named("run", JavaExec.class, new Action<JavaExec>() {
95+
@Override
96+
public void execute(JavaExec task) {
97+
if (task.getMainModule().isPresent()) {
98+
return;
99+
}
100+
final var fxPlatform = javaFXOptions.getFxPlatform();
101+
final var fxModules = javaFXOptions.getFxModules();
102+
task.doFirst(a -> {
103+
putJavaFXJarsOnModulePathForClasspathApplication(task, fxPlatform, fxModules);
104+
});
97105
}
98-
99-
putJavaFXJarsOnModulePathForClasspathApplication(execTask, javaFXOptions);
100106
});
101-
});
107+
108+
}
102109
});
110+
103111
}
104112

105113
/**
106114
* Gradle does currently not put anything on the --module-path if the application itself is executed from
107115
* the classpath. Hence, this patches the setup of Gradle's standard ':run' task to move all JavaFX Jars
108116
* from '-classpath' to '-module-path'. This functionality is only relevant for NON-MODULAR apps.
109117
*/
110-
private static void putJavaFXJarsOnModulePathForClasspathApplication(JavaExec execTask, JavaFXOptions javaFXOptions) {
118+
private static void putJavaFXJarsOnModulePathForClasspathApplication(JavaExec execTask, final Property<JavaFXPlatform> platform, final SetProperty<String> stringSetProperty) {
111119
FileCollection classpath = execTask.getClasspath();
112120

113-
execTask.setClasspath(classpath.filter(jar -> !isJavaFXJar(jar, javaFXOptions.getPlatform())));
114-
var modulePath = classpath.filter(jar -> isJavaFXJar(jar, javaFXOptions.getPlatform()));
121+
execTask.setClasspath(classpath.filter(jar -> !isJavaFXJar(jar, platform.get())));
122+
var modulePath = classpath.filter(jar -> isJavaFXJar(jar, platform.get()));
115123

116124
execTask.getJvmArgumentProviders().add(() -> List.of(
117125
"--module-path", modulePath.getAsPath(),
118-
"--add-modules", String.join(",", javaFXOptions.getModules())
126+
"--add-modules", String.join(",", stringSetProperty.get())
119127
));
120128
}
121129

src/test/java/org/openjfx/gradle/JavaFXPluginSmokeTest.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Gluon
2+
* Copyright (c) 2018, 2025, Gluon
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -33,10 +33,12 @@
3333
import org.gradle.testkit.runner.BuildResult;
3434
import org.gradle.testkit.runner.GradleRunner;
3535
import org.gradle.testkit.runner.TaskOutcome;
36+
import org.junit.jupiter.api.Assumptions;
3637
import org.junit.jupiter.api.Test;
3738

3839
import java.io.File;
3940
import java.lang.management.ManagementFactory;
41+
import java.util.ArrayList;
4042
import java.util.Arrays;
4143
import java.util.List;
4244
import java.util.stream.Collectors;
@@ -74,6 +76,7 @@ void smokeTestModular() {
7476

7577
@Test
7678
void smokeTestModularWithModularityPlugin() {
79+
Assumptions.assumeFalse(useConfigurationCache(), "modularity plugin does not support configuration cache");
7780
var result = build(":modular-with-modularity-plugin:run");
7881

7982
assertEquals(TaskOutcome.SUCCESS, result.task(":modular-with-modularity-plugin:run").getOutcome());
@@ -135,7 +138,8 @@ private static List<List<String>> path(BuildResult result, String pathArg) {
135138
return result.getOutput().lines().filter(l -> l.contains(pathArg)).map(l -> {
136139
int pathArgIndex = l.indexOf(pathArg) + pathArg.length();
137140
String pathString = l.substring(pathArgIndex, l.indexOf(" ", pathArgIndex));
138-
if (pathString.isBlank()) {
141+
//recently gradle added an empty classpath instead of omitting it entirely which seems like the same thing?
142+
if (pathString.isBlank() || pathString.equals("\"\"")) {
139143
return List.<String>of();
140144
}
141145
String[] path = pathString.split(System.getProperty("path.separator"));
@@ -149,7 +153,21 @@ private BuildResult build(String task) {
149153
.withGradleVersion(getGradleVersion())
150154
.withPluginClasspath()
151155
.withDebug(ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("-agentlib:jdwp"))
152-
.withArguments("clean", task, "--stacktrace", "--debug")
156+
.withArguments(getGradleRunnerArguments(task))
153157
.build();
154158
}
159+
160+
protected List<String> getGradleRunnerArguments(String taskname) {
161+
//note that the tests are written around --debug, they will fail if you reduce logging
162+
final var args = new ArrayList<String>(List.of("clean", taskname, "--stacktrace", "--debug"));
163+
if (useConfigurationCache()) {
164+
args.add("--configuration-cache");
165+
}
166+
return args;
167+
168+
}
169+
170+
protected boolean useConfigurationCache() {
171+
return false;
172+
}
155173
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2025, Gluon
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* * Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
*
11+
* * Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
*
15+
* * Neither the name of the copyright holder nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
package org.openjfx.gradle;
31+
32+
33+
class JavaFXPluginSmokeTestGradle64 extends JavaFXPluginSmokeTest {
34+
35+
@Override
36+
protected String getGradleVersion() {
37+
return "6.4";
38+
}
39+
40+
}

0 commit comments

Comments
 (0)