Skip to content

Commit

Permalink
Use variants to select JavaFX platform Jars in the dependency graph
Browse files Browse the repository at this point in the history
- Metadata Rule (metadata could later be published by JavaFX)
- Transitive dependencies no longer need to be maintained in the plugin
- Empty Jars are no longer on the classpath
- Manual classpath and module path modification limited to minimum
- No hard dependency on 'org.javamodularity:moduleplugin' anymore
  - Users can then choose between Gradle's built in Modul System
    support or the javamodularity plugin
- Dependency declaration done lazily (via withDependencies)
  • Loading branch information
jjohannes committed Aug 28, 2023
1 parent 660ade2 commit 59f1e8f
Show file tree
Hide file tree
Showing 10 changed files with 281 additions and 223 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ repositories {

dependencies {
implementation 'com.google.gradle:osdetector-gradle-plugin:1.7.3'
implementation 'org.javamodularity:moduleplugin:1.8.12'

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
Expand Down
32 changes: 7 additions & 25 deletions src/main/java/org/openjfx/gradle/JavaFXModule.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Gluon
* Copyright (c) 2018, 2023, Gluon
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -31,7 +31,6 @@

import org.gradle.api.GradleException;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
Expand All @@ -43,22 +42,16 @@
public enum JavaFXModule {

BASE,
GRAPHICS(BASE),
CONTROLS(BASE, GRAPHICS),
FXML(BASE, GRAPHICS),
MEDIA(BASE, GRAPHICS),
SWING(BASE, GRAPHICS),
WEB(BASE, CONTROLS, GRAPHICS, MEDIA);
GRAPHICS,
CONTROLS,
FXML,
MEDIA,
SWING,
WEB;

static final String PREFIX_MODULE = "javafx.";
private static final String PREFIX_ARTIFACT = "javafx-";

private List<JavaFXModule> dependentModules;

JavaFXModule(JavaFXModule...dependentModules) {
this.dependentModules = List.of(dependentModules);
}

public static Optional<JavaFXModule> fromModuleName(String moduleName) {
return Stream.of(JavaFXModule.values())
.filter(javaFXModule -> moduleName.equals(javaFXModule.getModuleName()))
Expand Down Expand Up @@ -88,7 +81,6 @@ public static Set<JavaFXModule> getJavaFXModules(List<String> moduleNames) {
return moduleNames.stream()
.map(JavaFXModule::fromModuleName)
.flatMap(Optional::stream)
.flatMap(javaFXModule -> javaFXModule.getMavenDependencies().stream())
.collect(Collectors.toSet());
}

Expand All @@ -101,14 +93,4 @@ public static void validateModules(List<String> moduleNames) {
throw new GradleException("Found one or more invalid JavaFX module names: " + invalidModules);
}
}

public List<JavaFXModule> getDependentModules() {
return dependentModules;
}

public List<JavaFXModule> getMavenDependencies() {
List<JavaFXModule> dependencies = new ArrayList<>(dependentModules);
dependencies.add(0, this);
return dependencies;
}
}
124 changes: 78 additions & 46 deletions src/main/java/org/openjfx/gradle/JavaFXOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,59 @@
*/
package org.openjfx.gradle;

import org.gradle.api.Project;
import com.google.gradle.osdetector.OsDetector;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import org.gradle.api.artifacts.dsl.RepositoryHandler;
import org.gradle.api.artifacts.repositories.FlatDirectoryArtifactRepository;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.nativeplatform.MachineArchitecture;
import org.gradle.nativeplatform.OperatingSystemFamily;

import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.openjfx.gradle.JavaFXModule.PREFIX_MODULE;
abstract public class JavaFXOptions {

public class JavaFXOptions {

private static final String MAVEN_JAVAFX_ARTIFACT_GROUP_ID = "org.openjfx";
static final String MAVEN_JAVAFX_ARTIFACT_GROUP_ID = "org.openjfx";
private static final String JAVAFX_SDK_LIB_FOLDER = "lib";

private final Project project;
private JavaFXPlatform platform;

private String version = "17";
private String sdk;
private String[] configurations = new String[] { "implementation" };
private String[] lastUpdatedConfigurations;
private List<String> modules = new ArrayList<>();
private FlatDirectoryArtifactRepository customSDKArtifactRepository;

public JavaFXOptions(Project project) {
this.project = project;
this.platform = JavaFXPlatform.detect(project);
private final SourceSetContainer sourceSets;
private final Set<String> seenConfigurations = new HashSet<>();

@Inject
abstract protected ObjectFactory getObjects();

@Inject
abstract protected RepositoryHandler getRepositories();

@Inject
abstract protected ConfigurationContainer getConfigurationContainer();

@Inject
abstract protected DependencyHandler getDependencies();

public JavaFXOptions(SourceSetContainer sourceSets, OsDetector osDetector) {
this.sourceSets = sourceSets;
platform = JavaFXPlatform.detect(osDetector);
setClasspathAttributesForAllSourceSets();
}

public JavaFXPlatform getPlatform() {
Expand All @@ -71,7 +95,23 @@ public JavaFXPlatform getPlatform() {
*/
public void setPlatform(String platform) {
this.platform = JavaFXPlatform.fromString(platform);
updateJavaFXDependencies();
setClasspathAttributesForAllSourceSets();
}

private void setClasspathAttributesForAllSourceSets() {
sourceSets.all(sourceSet -> {
setClasspathAttributes(getConfigurationContainer().getByName(sourceSet.getCompileClasspathConfigurationName()));
setClasspathAttributes(getConfigurationContainer().getByName(sourceSet.getRuntimeClasspathConfigurationName()));
});
}

private void setClasspathAttributes(Configuration classpath) {
classpath.getAttributes().attribute(
OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE,
getObjects().named(OperatingSystemFamily.class, platform.getOsFamily()));
classpath.getAttributes().attribute(
MachineArchitecture.ARCHITECTURE_ATTRIBUTE,
getObjects().named(MachineArchitecture.class, platform.getArch()));
}

public String getVersion() {
Expand All @@ -80,7 +120,6 @@ public String getVersion() {

public void setVersion(String version) {
this.version = version;
updateJavaFXDependencies();
}

/**
Expand All @@ -90,7 +129,7 @@ public void setVersion(String version) {
*/
public void setSdk(String sdk) {
this.sdk = sdk;
updateJavaFXDependencies();
updateCustomSDKArtifactRepository();
}

public String getSdk() {
Expand All @@ -113,7 +152,12 @@ public void setConfiguration(String configuration) {
*/
public void setConfigurations(String[] configurations) {
this.configurations = configurations;
updateJavaFXDependencies();
for (String conf : configurations) {
if (!seenConfigurations.contains(conf)) {
declareFXDependencies(conf);
seenConfigurations.add(conf);
}
}
}

public String getConfiguration() {
Expand All @@ -130,64 +174,52 @@ public List<String> getModules() {

public void setModules(List<String> modules) {
this.modules = modules;
updateJavaFXDependencies();
}

public void modules(String...moduleNames) {
setModules(List.of(moduleNames));
}

private void updateJavaFXDependencies() {
clearJavaFXDependencies();

String[] configurations = getConfigurations();
for (String conf : configurations) {
private void declareFXDependencies(String conf) {
// Use 'withDependencies' to declare the dependencies late (i.e., right before dependency resolution starts).
// This allows users to make multiple modifications to the 'configurations' list at arbitrary times during
// build configuration.
getConfigurationContainer().getByName(conf).withDependencies(dependencySet -> {
if (!List.of(configurations).contains(conf)) {
// configuration was removed: do nothing
return;
}
JavaFXModule.getJavaFXModules(this.modules).stream()
.sorted()
.forEach(javaFXModule -> {
if (customSDKArtifactRepository != null) {
project.getDependencies().add(conf, Map.of("name", javaFXModule.getModuleName()));
dependencySet.add(getDependencies().create(Map.of("name", javaFXModule.getModuleName())));
} else {
project.getDependencies().add(conf,
String.format("%s:%s:%s:%s", MAVEN_JAVAFX_ARTIFACT_GROUP_ID, javaFXModule.getArtifactName(),
getVersion(), getPlatform().getClassifier()));
dependencySet.add(getDependencies().create(
MAVEN_JAVAFX_ARTIFACT_GROUP_ID + ":"
+ javaFXModule.getArtifactName() + ":"
+ getVersion()
));
}
});
}
lastUpdatedConfigurations = configurations;
});
}

private void clearJavaFXDependencies() {
private void updateCustomSDKArtifactRepository() {
if (customSDKArtifactRepository != null) {
project.getRepositories().remove(customSDKArtifactRepository);
getRepositories().remove(customSDKArtifactRepository);
customSDKArtifactRepository = null;
}

if (sdk != null && ! sdk.isEmpty()) {
if (sdk != null && !sdk.isEmpty()) {
Map<String, String> dirs = new HashMap<>();
dirs.put("name", "customSDKArtifactRepository");
if (sdk.endsWith(File.separator)) {
dirs.put("dirs", sdk + JAVAFX_SDK_LIB_FOLDER);
} else {
dirs.put("dirs", sdk + File.separator + JAVAFX_SDK_LIB_FOLDER);
}
customSDKArtifactRepository = project.getRepositories().flatDir(dirs);
}

if (lastUpdatedConfigurations == null) {
return;
}

for (String conf : lastUpdatedConfigurations) {
var configuration = project.getConfigurations().findByName(conf);
if (configuration != null) {
if (customSDKArtifactRepository != null) {
configuration.getDependencies()
.removeIf(dependency -> dependency.getName().startsWith(PREFIX_MODULE));
}
configuration.getDependencies()
.removeIf(dependency -> MAVEN_JAVAFX_ARTIFACT_GROUP_ID.equals(dependency.getGroup()));
}
customSDKArtifactRepository = getRepositories().flatDir(dirs);
}
}
}
31 changes: 22 additions & 9 deletions src/main/java/org/openjfx/gradle/JavaFXPlatform.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,47 @@

import com.google.gradle.osdetector.OsDetector;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.nativeplatform.MachineArchitecture;
import org.gradle.nativeplatform.OperatingSystemFamily;

import java.util.Arrays;
import java.util.stream.Collectors;

public enum JavaFXPlatform {

LINUX("linux", "linux-x86_64"),
LINUX_AARCH64("linux-aarch64", "linux-aarch_64"),
WINDOWS("win", "windows-x86_64"),
OSX("mac", "osx-x86_64"),
OSX_AARCH64("mac-aarch64", "osx-aarch_64");
LINUX("linux", "linux-x86_64", OperatingSystemFamily.LINUX, MachineArchitecture.X86_64),
LINUX_AARCH64("linux-aarch64", "linux-aarch_64", OperatingSystemFamily.LINUX, MachineArchitecture.ARM64),
WINDOWS("win", "windows-x86_64", OperatingSystemFamily.WINDOWS, MachineArchitecture.X86_64),
OSX("mac", "osx-x86_64", OperatingSystemFamily.MACOS, MachineArchitecture.X86_64),
OSX_AARCH64("mac-aarch64", "osx-aarch_64", OperatingSystemFamily.MACOS, MachineArchitecture.ARM64);

private final String classifier;
private final String osDetectorClassifier;
private final String osFamily;
private final String arch;

JavaFXPlatform(String classifier, String osDetectorClassifier) {
JavaFXPlatform(String classifier, String osDetectorClassifier, String osFamily, String arch) {
this.classifier = classifier;
this.osDetectorClassifier = osDetectorClassifier;
this.osFamily = osFamily;
this.arch = arch;
}

public String getClassifier() {
return classifier;
}

public static JavaFXPlatform detect(Project project) {
public String getOsFamily() {
return osFamily;
}

public String getArch() {
return arch;
}

public static JavaFXPlatform detect(OsDetector osDetector) {

final String osClassifier = project.getExtensions().getByType(OsDetector.class).getClassifier();
final String osClassifier = osDetector.getClassifier();

for (JavaFXPlatform platform: values()) {
if (platform.osDetectorClassifier.equals(osClassifier)) {
Expand Down
Loading

0 comments on commit 59f1e8f

Please sign in to comment.