From 556a6711f1e618419784375abf9e7e7b9407f103 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Mon, 17 Oct 2022 14:57:29 +0200 Subject: [PATCH] Use serializable lambdas This is an attempt to fix #338 --- .../buildtools/gradle/NativeImagePlugin.java | 71 +++++++++++-------- .../internal/ConfigurationCacheSupport.java | 42 +++++++++++ 2 files changed, 82 insertions(+), 31 deletions(-) diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java index b845c9100..fb6288f6b 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/NativeImagePlugin.java @@ -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; @@ -287,12 +288,12 @@ private void configureJavaProject(Project project, Provider GraalVMReachabilityMetadataRepositoryExtension metadataRepositoryExtension = reachabilityExtensionOn(graalExtension); TaskCollection reachabilityMetadataCopyTasks = project.getTasks() .withType(CollectReachabilityMetadata.class); - reachabilityMetadataCopyTasks.configureEach(task -> { - Provider reachabilityMetadataService = graalVMReachabilityMetadataService( - project, metadataRepositoryExtension); + reachabilityMetadataCopyTasks.configureEach(task -> { + Provider 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()); @@ -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 Provider graalVMReachabilityQuery(Project project, GraalVMExtension graalExtension, - SourceSet sourceSet, Predicate filter, - BiFunction mapper, Collector collector) { + private Provider> graalVMReachabilityQuery(Project project, + GraalVMExtension graalExtension, + SourceSet sourceSet, + Predicate filter, + BiFunction 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 excludedModules = extension.getExcludedModules().getOrElse(Collections.emptySet()); Map forcedVersions = extension.getModuleToConfigVersion().getOrElse(Collections.emptyMap()); - return graalVMReachabilityMetadataService(project, extension).map(service -> { + return graalVMReachabilityMetadataService(project, extension).map(serializableTransformerOf(service -> { Set components = classpath.getIncoming().getResolutionResult().getAllComponents(); - Stream mapped = components.stream().flatMap(component -> { + Stream mapped = components.stream().flatMap(serializableFunctionOf(component -> { ModuleVersionIdentifier moduleVersion = component.getModuleVersion(); Set 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.empty().collect(collector)); - }); + return project.getProviders().provider(Collections::emptyList); + })); } private Provider graalVMReachabilityMetadataService(Project project, @@ -387,7 +396,7 @@ private Provider 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")); }); @@ -417,7 +426,7 @@ 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; @@ -425,7 +434,7 @@ private static URI computeMetadataRepositoryUri(Project project, private void configureJvmReachabilityExcludeConfigArgs(Project project, GraalVMExtension graalExtension, NativeImageOptions options, SourceSet sourceSet) { GraalVMReachabilityMetadataRepositoryExtension repositoryExtension = reachabilityExtensionOn(graalExtension); - Provider serviceProvider = project.getGradle() + project.getGradle() .getSharedServices() .registerIfAbsent("nativeConfigurationService", GraalVMReachabilityMetadataService.class, spec -> { LogLevel logLevel = determineLogLevel(); @@ -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()); } @@ -711,7 +720,7 @@ private static void addExcludeConfigArg(List args, Path jarPath, List { + options.getExcludeConfigArgs().set(options.getExcludeConfig().map(serializableTransformerOf(excludedConfig -> { List args = new ArrayList<>(); excludedConfig.forEach((entry, listOfResourcePatterns) -> { if (entry instanceof File) { @@ -741,7 +750,7 @@ private static void setupExtensionConfigExcludes(NativeImageOptions options, Nat } }); return args; - })); + }))); } private static List agentSessionDirectories(Directory outputDirectory) { diff --git a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java index ffc491755..9112e2bf8 100644 --- a/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java +++ b/native-gradle-plugin/src/main/java/org/graalvm/buildtools/gradle/internal/ConfigurationCacheSupport.java @@ -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. @@ -82,6 +85,33 @@ public static Transformer serializableTransformerOf(Serializa return transformer; } + /** + * Generates a serializable function lambda. + * @param function the bifunction + * @param the type of the parameter + * @param the type of the result + * @return a serializable function + */ + public static Function serializableFunctionOf(SerializableFunction function) { + return function; + } + + /** + * Generates a serializable bifunction lambda. + * @param bifunction the bifunction + * @param the type of the first parameter + * @param the type of the second parameter + * @param the type of the result + * @return a serializable bifunction + */ + public static BiFunction serializableBiFunctionOf(SerializableBiFunction bifunction) { + return bifunction; + } + + public static Collector serializableCollectorOf(SerializableCollector collector) { + return collector; + } + public interface SerializableSupplier extends Supplier, Serializable { } @@ -94,4 +124,16 @@ public interface SerializableTransformer extends Transformer, } + public interface SerializableFunction extends Function, Serializable { + + } + + public interface SerializableBiFunction extends BiFunction, Serializable { + + } + + public interface SerializableCollector extends Collector, Serializable { + + } + }