Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazily acquire JDK storage locations #2263

Merged
merged 12 commits into from
May 12, 2022
Merged
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-2263.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: More lazily acquire JDK storage locations
links:
- https://github.com/palantir/gradle-baseline/pull/2263
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ package com.palantir.baseline.plugins

import com.google.common.collect.ImmutableMap
import com.palantir.baseline.IntellijSupport
import com.palantir.baseline.extensions.BaselineJavaVersionExtension
import com.palantir.baseline.extensions.BaselineJavaVersionsExtension
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersionExtension
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersionsExtension
import com.palantir.baseline.util.GitUtils
import groovy.transform.CompileStatic
import groovy.xml.XmlUtil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.palantir.baseline.extensions.BaselineModuleJvmArgsExtension;
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersion;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.palantir.baseline.plugins;

import com.google.common.collect.ImmutableList;
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersion;
import java.util.Collections;
import java.util.Optional;
import org.gradle.api.JavaVersion;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved.
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,12 +14,8 @@
* limitations under the License.
*/

package com.palantir.baseline.plugins;
package com.palantir.baseline.plugins.javaversions;

import com.palantir.baseline.extensions.BaselineJavaVersionExtension;
import com.palantir.baseline.extensions.BaselineJavaVersionsExtension;
import com.palantir.baseline.plugins.javaversions.BaselineJavaToolchain;
import com.palantir.baseline.plugins.javaversions.JavaToolchains;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (c) Copyright 2019 Palantir Technologies Inc. All rights reserved.
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,7 +14,7 @@
* limitations under the License.
*/

package com.palantir.baseline.extensions;
package com.palantir.baseline.plugins.javaversions;

import javax.inject.Inject;
import org.gradle.api.Project;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved.
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,12 +14,10 @@
* limitations under the License.
*/

package com.palantir.baseline.plugins;
package com.palantir.baseline.plugins.javaversions;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.palantir.baseline.extensions.BaselineJavaVersionExtension;
import com.palantir.baseline.extensions.BaselineJavaVersionsExtension;
import java.util.Objects;
import org.gradle.api.GradleException;
import org.gradle.api.Named;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (c) Copyright 2019 Palantir Technologies Inc. All rights reserved.
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,11 +14,12 @@
* limitations under the License.
*/

package com.palantir.baseline.extensions;
package com.palantir.baseline.plugins.javaversions;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.jvm.toolchain.JavaInstallationMetadata;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
Expand All @@ -31,7 +32,8 @@ public class BaselineJavaVersionsExtension {
private final Property<JavaLanguageVersion> libraryTarget;
private final Property<JavaLanguageVersion> distributionTarget;
private final Property<JavaLanguageVersion> runtime;
private final MapProperty<JavaLanguageVersion, JavaInstallationMetadata> jdks;
private final LazilyConfiguredMapping<JavaLanguageVersion, AtomicReference<JavaInstallationMetadata>, Project>
jdks = new LazilyConfiguredMapping<>(AtomicReference::new);

@Inject
public BaselineJavaVersionsExtension(Project project) {
Expand All @@ -45,9 +47,6 @@ public BaselineJavaVersionsExtension(Project project) {
libraryTarget.finalizeValueOnRead();
distributionTarget.finalizeValueOnRead();
runtime.finalizeValueOnRead();

jdks = project.getObjects().mapProperty(JavaLanguageVersion.class, JavaInstallationMetadata.class);
jdks.finalizeValueOnRead();
}

/** Target {@link JavaLanguageVersion} for compilation of libraries that are published. */
Expand Down Expand Up @@ -80,7 +79,21 @@ public final void setRuntime(int value) {
runtime.set(JavaLanguageVersion.of(value));
}

public final MapProperty<JavaLanguageVersion, JavaInstallationMetadata> getJdks() {
return jdks;
public final Optional<JavaInstallationMetadata> jdkMetadataFor(
JavaLanguageVersion javaLanguageVersion, Project project) {
return jdks.get(javaLanguageVersion, project).map(AtomicReference::get);
}

public final void jdk(JavaLanguageVersion javaLanguageVersion, JavaInstallationMetadata javaInstallationMetadata) {
jdks.put(javaLanguageVersion, ref -> ref.set(javaInstallationMetadata));
}

public final void jdks(LazyJdks lazyJdks) {
jdks.put((javaLanguageVersion, project) -> lazyJdks.jdkFor(javaLanguageVersion, project)
.map(javaInstallationMetadata -> ref -> ref.set(javaInstallationMetadata)));
}

public interface LazyJdks {
Optional<JavaInstallationMetadata> jdkFor(JavaLanguageVersion javaLanguageVersion, Project project);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.palantir.baseline.plugins.javaversions;

import com.palantir.baseline.extensions.BaselineJavaVersionsExtension;
import org.gradle.api.Project;
import org.gradle.api.provider.Provider;
import org.gradle.jvm.toolchain.JavaInstallationMetadata;
Expand All @@ -34,15 +33,16 @@ public JavaToolchains(Project project, BaselineJavaVersionsExtension baselineJav

public Provider<BaselineJavaToolchain> forVersion(Provider<JavaLanguageVersion> javaLanguageVersionProvider) {
return javaLanguageVersionProvider.map(javaLanguageVersion -> {
Provider<JavaInstallationMetadata> configuredJdkMetadata = baselineJavaVersionsExtension
.getJdks()
.getting(javaLanguageVersion)
.orElse(project.provider(() -> project.getExtensions()
.getByType(JavaToolchainService.class)
.launcherFor(javaToolchainSpec ->
javaToolchainSpec.getLanguageVersion().set(javaLanguageVersion))
.get()
.getMetadata()));
Provider<JavaInstallationMetadata> configuredJdkMetadata =
project.provider(() -> baselineJavaVersionsExtension
.jdkMetadataFor(javaLanguageVersion, project)
.orElseGet(() -> project.getExtensions()
.getByType(JavaToolchainService.class)
.launcherFor(javaToolchainSpec -> javaToolchainSpec
.getLanguageVersion()
.set(javaLanguageVersion))
.get()
.getMetadata()));

return new ConfiguredJavaToolchain(
project.getObjects(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.baseline.plugins.javaversions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import org.gradle.api.Action;

final class LazilyConfiguredMapping<K, V, A> {
private final Supplier<V> valueFactory;
private final List<LazyValues<K, V, A>> values = new ArrayList<>();
private final Map<K, Optional<V>> computedValues = new HashMap<>();
private boolean finalized = false;

LazilyConfiguredMapping(Supplier<V> valueFactory) {
this.valueFactory = valueFactory;
}

public void put(LazyValues<K, V, A> lazyValues) {
ensureNotFinalized();

values.add(lazyValues);
}

public void put(K key, Action<V> value) {
ensureNotFinalized();

put((requestedKey, _ignored) -> {
if (requestedKey.equals(key)) {
return Optional.of(value);
}

return Optional.empty();
});
}

private void ensureNotFinalized() {
if (finalized) {
throw new IllegalStateException(String.format(
"This %s has already been finalized as get() hase been called. "
+ "No further elements can be added to it",
LazilyConfiguredMapping.class.getSimpleName()));
}
}

public Optional<V> get(K key, A additionalData) {
finalized = true;

return computedValues.computeIfAbsent(key, _ignored -> {
V value = valueFactory.get();
AtomicBoolean created = new AtomicBoolean(false);
values.forEach(lazyValues -> {
lazyValues.compute(key, additionalData).ifPresent(action -> {
created.set(true);
action.execute(value);
});
});

if (created.get()) {
return Optional.of(value);
}

return Optional.empty();
});
}

public interface LazyValues<K, V, A> {
Optional<Action<V>> compute(K key, A additionalData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package com.palantir.baseline.tasks;

import com.palantir.baseline.plugins.BaselineJavaVersion;
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersion;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
Expand All @@ -43,7 +43,7 @@
/**
* By default, Gradle will infer sourceCompat based on whatever JVM is currently being used to evaluate the
* build.gradle files. This is bad for reproducibility because if we make an automated PR to upgrade the Java major
* version (e.g. 11 -> 15) then a library might unintentionally start publishing jars containing Java15 bytecode!
* version (e.g. 11 to 15) then a library might unintentionally start publishing jars containing Java15 bytecode!
*
* Better to just require everyone to specify sourceCompatibility explicitly!
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
implementation-class=com.palantir.baseline.plugins.BaselineJavaVersion
implementation-class=com.palantir.baseline.plugins.javaversions.BaselineJavaVersion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
implementation-class=com.palantir.baseline.plugins.BaselineJavaVersions
implementation-class=com.palantir.baseline.plugins.javaversions.BaselineJavaVersions
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ class BaselineJavaVersionIntegrationTest extends IntegrationSpec {
javaVersions {
libraryTarget = 11

jdks.put JavaLanguageVersion.of(11), new JavaInstallationMetadata() {
jdk JavaLanguageVersion.of(11), new JavaInstallationMetadata() {
@Override
JavaLanguageVersion getLanguageVersion() {
return JavaLanguageVersion.of(11)
Expand Down
Loading