Skip to content

Commit

Permalink
Use serializable lambdas
Browse files Browse the repository at this point in the history
This is an attempt to fix #338
  • Loading branch information
melix committed Oct 17, 2022
1 parent 4e510e3 commit 556a671
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableBiFunctionOf;
import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableFunctionOf;
import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializablePredicateOf;
import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableSupplierOf;
import static org.graalvm.buildtools.gradle.internal.ConfigurationCacheSupport.serializableTransformerOf;
Expand Down Expand Up @@ -287,12 +288,12 @@ private void configureJavaProject(Project project, Provider<NativeImageService>
GraalVMReachabilityMetadataRepositoryExtension metadataRepositoryExtension = reachabilityExtensionOn(graalExtension);
TaskCollection<CollectReachabilityMetadata> reachabilityMetadataCopyTasks = project.getTasks()
.withType(CollectReachabilityMetadata.class);
reachabilityMetadataCopyTasks.configureEach(task -> {
Provider<GraalVMReachabilityMetadataService> reachabilityMetadataService = graalVMReachabilityMetadataService(
project, metadataRepositoryExtension);
reachabilityMetadataCopyTasks.configureEach(task -> {
Provider<GraalVMReachabilityMetadataService> reachabilityMetadataService = graalVMReachabilityMetadataService(
project, metadataRepositoryExtension);
task.getMetadataService().set(reachabilityMetadataService);
task.usesService(reachabilityMetadataService);
task.getUri().convention(task.getVersion().map(this::getReachabilityMetadataRepositoryUrlForVersion)
task.getUri().convention(task.getVersion().map(serializableTransformerOf(this::getReachabilityMetadataRepositoryUrlForVersion))
.orElse(metadataRepositoryExtension.getUri()));
task.getExcludedModules().convention(metadataRepositoryExtension.getExcludedModules());
task.getModuleToConfigVersion().convention(metadataRepositoryExtension.getModuleToConfigVersion());
Expand Down Expand Up @@ -337,47 +338,55 @@ private void configureAutomaticTaskCreation(Project project,
tasks,
transitiveProjectArtifacts(project, sourceSet.getRuntimeClasspathConfigurationName()),
deriveTaskName(binaryName, "generate", "ResourcesConfigFile"));
options.getConfigurationFileDirectories().from(generateResourcesConfig.map(t ->
options.getConfigurationFileDirectories().from(generateResourcesConfig.map(serializableTransformerOf(t ->
t.getOutputFile().map(f -> f.getAsFile().getParentFile())
));
)));
configureJvmReachabilityConfigurationDirectories(project, graalExtension, options, sourceSet);
configureJvmReachabilityExcludeConfigArgs(project, graalExtension, options, sourceSet);
});
}

private void configureJvmReachabilityConfigurationDirectories(Project project, GraalVMExtension graalExtension,
NativeImageOptions options, SourceSet sourceSet) {
options.getConfigurationFileDirectories().from(graalVMReachabilityQuery(project, graalExtension, sourceSet,
configuration -> true, this::getConfigurationDirectory,
Collectors.toList()));
private void configureJvmReachabilityConfigurationDirectories(Project project,
GraalVMExtension graalExtension,
NativeImageOptions options,
SourceSet sourceSet) {
options.getConfigurationFileDirectories().from(
graalVMReachabilityQuery(project, graalExtension, sourceSet,
serializablePredicateOf(configuration -> true),
serializableBiFunctionOf(this::getConfigurationDirectory))
);
}

private File getConfigurationDirectory(ModuleVersionIdentifier moduleVersion,
DirectoryConfiguration configuration) {
DirectoryConfiguration configuration) {
return configuration.getDirectory().toAbsolutePath().toFile();
}

private <T, A, R> Provider<R> graalVMReachabilityQuery(Project project, GraalVMExtension graalExtension,
SourceSet sourceSet, Predicate<DirectoryConfiguration> filter,
BiFunction<ModuleVersionIdentifier, DirectoryConfiguration, T> mapper, Collector<T, A, R> collector) {
private Provider<List<File>> graalVMReachabilityQuery(Project project,
GraalVMExtension graalExtension,
SourceSet sourceSet,
Predicate<DirectoryConfiguration> filter,
BiFunction<ModuleVersionIdentifier, DirectoryConfiguration, File> mapper) {
GraalVMReachabilityMetadataRepositoryExtension extension = reachabilityExtensionOn(graalExtension);
return extension.getEnabled().flatMap(enabled -> {
return extension.getEnabled().flatMap(serializableTransformerOf(enabled -> {
if (enabled && extension.getUri().isPresent()) {
Configuration classpath = project.getConfigurations().getByName(sourceSet.getRuntimeClasspathConfigurationName());
Set<String> excludedModules = extension.getExcludedModules().getOrElse(Collections.emptySet());
Map<String, String> forcedVersions = extension.getModuleToConfigVersion().getOrElse(Collections.emptyMap());
return graalVMReachabilityMetadataService(project, extension).map(service -> {
return graalVMReachabilityMetadataService(project, extension).map(serializableTransformerOf(service -> {
Set<ResolvedComponentResult> components = classpath.getIncoming().getResolutionResult().getAllComponents();
Stream<T> mapped = components.stream().flatMap(component -> {
Stream<File> mapped = components.stream().flatMap(serializableFunctionOf(component -> {
ModuleVersionIdentifier moduleVersion = component.getModuleVersion();
Set<DirectoryConfiguration> configurations = service.findConfigurationsFor(excludedModules, forcedVersions, moduleVersion);
return configurations.stream().filter(filter).map(configuration -> mapper.apply(moduleVersion, configuration));
});
return mapped.collect(collector);
});
return configurations.stream()
.filter(filter)
.map(serializableFunctionOf(configuration -> mapper.apply(moduleVersion, configuration)));
}));
return mapped.collect(Collectors.toList());
}));
}
return project.getProviders().provider(() -> Stream.<T>empty().collect(collector));
});
return project.getProviders().provider(Collections::emptyList);
}));
}

private Provider<GraalVMReachabilityMetadataService> graalVMReachabilityMetadataService(Project project,
Expand All @@ -387,7 +396,7 @@ private Provider<GraalVMReachabilityMetadataService> graalVMReachabilityMetadata
.registerIfAbsent("nativeConfigurationService", GraalVMReachabilityMetadataService.class, spec -> {
LogLevel logLevel = determineLogLevel();
spec.getParameters().getLogLevel().set(logLevel);
spec.getParameters().getUri().set(repositoryExtension.getUri().map(configuredUri -> computeMetadataRepositoryUri(project, repositoryExtension, configuredUri, GraalVMLogger.of(project.getLogger()))));
spec.getParameters().getUri().set(repositoryExtension.getUri().map(serializableTransformerOf(configuredUri -> computeMetadataRepositoryUri(project, repositoryExtension, configuredUri, GraalVMLogger.of(project.getLogger())))));
spec.getParameters().getCacheDir().set(
new File(project.getGradle().getGradleUserHomeDir(), "native-build-tools/repositories"));
});
Expand Down Expand Up @@ -417,15 +426,15 @@ private static URI computeMetadataRepositoryUri(Project project,
return files.iterator().next().toURI();
} else {
logger.warn("Unable to find the GraalVM reachability metadata repository in Maven repository. " +
"Falling back to the default repository at " + defaultUri);
"Falling back to the default repository at " + defaultUri);
}
}
return configuredUri;
}

private void configureJvmReachabilityExcludeConfigArgs(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) {
GraalVMReachabilityMetadataRepositoryExtension repositoryExtension = reachabilityExtensionOn(graalExtension);
Provider<GraalVMReachabilityMetadataService> serviceProvider = project.getGradle()
project.getGradle()
.getSharedServices()
.registerIfAbsent("nativeConfigurationService", GraalVMReachabilityMetadataService.class, spec -> {
LogLevel logLevel = determineLogLevel();
Expand Down Expand Up @@ -514,7 +523,7 @@ private void configureNativeConfigurationRepo(ExtensionAware graalvmNative) {
GraalVMReachabilityMetadataRepositoryExtension configurationRepository = graalvmNative.getExtensions().create("metadataRepository", GraalVMReachabilityMetadataRepositoryExtension.class);
configurationRepository.getEnabled().convention(false);
configurationRepository.getVersion().convention(VersionInfo.METADATA_REPO_VERSION);
configurationRepository.getUri().convention(configurationRepository.getVersion().map(this::getReachabilityMetadataRepositoryUrlForVersion));
configurationRepository.getUri().convention(configurationRepository.getVersion().map(serializableTransformerOf(this::getReachabilityMetadataRepositoryUrlForVersion)));
configurationRepository.getExcludedModules().convention(Collections.emptySet());
configurationRepository.getModuleToConfigVersion().convention(Collections.emptyMap());
}
Expand Down Expand Up @@ -711,7 +720,7 @@ private static void addExcludeConfigArg(List<String> args, Path jarPath, List<St
}

private static void setupExtensionConfigExcludes(NativeImageOptions options, NativeConfigurations configs) {
options.getExcludeConfigArgs().set(options.getExcludeConfig().map(excludedConfig -> {
options.getExcludeConfigArgs().set(options.getExcludeConfig().map(serializableTransformerOf(excludedConfig -> {
List<String> args = new ArrayList<>();
excludedConfig.forEach((entry, listOfResourcePatterns) -> {
if (entry instanceof File) {
Expand Down Expand Up @@ -741,7 +750,7 @@ private static void setupExtensionConfigExcludes(NativeImageOptions options, Nat
}
});
return args;
}));
})));
}

private static List<String> agentSessionDirectories(Directory outputDirectory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@
import org.gradle.api.Transformer;

import java.io.Serializable;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;

/**
* Helper class to deal with Gradle configuration cache.
Expand Down Expand Up @@ -82,6 +85,33 @@ public static <OUT, IN> Transformer<OUT, IN> serializableTransformerOf(Serializa
return transformer;
}

/**
* Generates a serializable function lambda.
* @param function the bifunction
* @param <F> the type of the parameter
* @param <T> the type of the result
* @return a serializable function
*/
public static <F, T> Function<F, T> serializableFunctionOf(SerializableFunction<F, T> function) {
return function;
}

/**
* Generates a serializable bifunction lambda.
* @param bifunction the bifunction
* @param <T> the type of the first parameter
* @param <U> the type of the second parameter
* @param <R> the type of the result
* @return a serializable bifunction
*/
public static <T, U, R> BiFunction<T, U, R> serializableBiFunctionOf(SerializableBiFunction<T, U, R> bifunction) {
return bifunction;
}

public static <T, A, R> Collector<T, A, R> serializableCollectorOf(SerializableCollector<T, A, R> collector) {
return collector;
}

public interface SerializableSupplier<T> extends Supplier<T>, Serializable {

}
Expand All @@ -94,4 +124,16 @@ public interface SerializableTransformer<OUT, IN> extends Transformer<OUT, IN>,

}

public interface SerializableFunction<F, T> extends Function<F, T>, Serializable {

}

public interface SerializableBiFunction<T, U, R> extends BiFunction<T, U, R>, Serializable {

}

public interface SerializableCollector<T, A, R> extends Collector<T, A, R>, Serializable {

}

}

0 comments on commit 556a671

Please sign in to comment.