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

java versions preview enhancements #2376

Merged
merged 10 commits into from
Sep 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions changelog/@unreleased/pr-2376.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
type: feature
feature:
description: |-
java versions preview enhancements

+ support setting preview on a project-by-project basis.
+ Fixes #2340
+ fails more elegantly if javaVersions is set on not-the-root.
links:
- https://github.com/palantir/gradle-baseline/pull/2376
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public final void setTarget(int value) {
target.set(ChosenJavaVersion.of(value));
}

public final void setTarget(String value) {
target.set(ChosenJavaVersion.fromString(value));
}

/** Runtime {@link ChosenJavaVersion} for testing and distributions. */
public final Property<ChosenJavaVersion> runtime() {
return runtime;
Expand All @@ -66,6 +70,10 @@ public final void setRuntime(int value) {
runtime.set(ChosenJavaVersion.of(value));
}

public final void setRuntime(String value) {
runtime.set(ChosenJavaVersion.fromString(value));
}

/**
* Overrides auto-detection if a value is present to force this module to be a
* library ({@code true}) or a distribution {@code false}).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public void apply(Project project) {
}
BaselineJavaVersionsExtension rootExtension =
project.getExtensions().create(EXTENSION_NAME, BaselineJavaVersionsExtension.class, project);
project.subprojects(proj ->
proj.getExtensions().create(EXTENSION_NAME, SubprojectBaselineJavaVersionsExtension.class, proj));

project.allprojects(proj -> proj.getPluginManager().withPlugin("java", unused -> {
proj.getPluginManager().apply(BaselineJavaVersion.class);
BaselineJavaVersionExtension projectVersions =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.provider.Property;
import org.gradle.jvm.toolchain.JavaInstallationMetadata;
Expand All @@ -29,7 +30,7 @@
* Extension named {@code javaVersions} on the root project used to configure all java modules
* with consistent java toolchains.
*/
public class BaselineJavaVersionsExtension {
public class BaselineJavaVersionsExtension implements BaselineJavaVersionsExtensionSetters {
private final Property<JavaLanguageVersion> libraryTarget;
private final Property<ChosenJavaVersion> distributionTarget;
private final Property<ChosenJavaVersion> runtime;
Expand Down Expand Up @@ -57,10 +58,22 @@ public final Property<JavaLanguageVersion> libraryTarget() {
return libraryTarget;
}

@Override
public final void setLibraryTarget(int value) {
libraryTarget.set(JavaLanguageVersion.of(value));
}

@Override
public final void setLibraryTarget(String value) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the bit that solves #2340.

ChosenJavaVersion version = ChosenJavaVersion.fromString(value);
if (version.enablePreview()) {
throw new GradleException("Because code compiled with preview features cannot be run on newer JVMs, "
+ "(Java 15 preview cannot be run on Java 17, e.g.) it is unsuitable for use on projects that"
+ " are published as libraries.");
}
libraryTarget.set(version.javaLanguageVersion());
}

/**
* Target {@link ChosenJavaVersion} for compilation of code used within distributions,
* but not published externally.
Expand All @@ -69,11 +82,13 @@ public final Property<ChosenJavaVersion> distributionTarget() {
return distributionTarget;
}

@Override
public final void setDistributionTarget(int value) {
distributionTarget.set(ChosenJavaVersion.of(value));
}

/** Accepts inputs such as '17_PREVIEW'. */
@Override
public final void setDistributionTarget(String value) {
distributionTarget.set(ChosenJavaVersion.fromString(value));
}
Expand All @@ -83,11 +98,13 @@ public final Property<ChosenJavaVersion> runtime() {
return runtime;
}

@Override
public final void setRuntime(int value) {
runtime.set(ChosenJavaVersion.of(value));
}

/** Accepts inputs such as '17_PREVIEW'. */
@Override
public final void setRuntime(String value) {
runtime.set(ChosenJavaVersion.fromString(value));
}
Expand All @@ -106,7 +123,7 @@ public final void jdks(LazyJdks lazyJdks) {
.map(javaInstallationMetadata -> ref -> ref.set(javaInstallationMetadata)));
}

public interface LazyJdks {
interface LazyJdks {
Optional<JavaInstallationMetadata> jdkFor(JavaLanguageVersion javaLanguageVersion, Project project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* (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;

/**
* This exists to keep the setters on the 'BaselineJavaVersionsExtension' in sync with those on
* 'SubprojectBaselineJavaVersionsExtension'. Ideally it would have a name like 'BaselineJavaVersionsExtension'
* with the main one called 'RootProjectBaselineJavaVersionsExtension', but that class is public API and is depended
* on by other Gradle plugins.
*/
public interface BaselineJavaVersionsExtensionSetters {
void setLibraryTarget(int value);

void setLibraryTarget(String value);

void setDistributionTarget(int value);

void setDistributionTarget(String value);

void setRuntime(int value);

void setRuntime(String value);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* (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 javax.inject.Inject;
import org.gradle.api.GradleException;
import org.gradle.api.Project;

public class SubprojectBaselineJavaVersionsExtension implements BaselineJavaVersionsExtensionSetters {
private final Project project;

@Inject
public SubprojectBaselineJavaVersionsExtension(Project project) {
this.project = project;
}

@Override
public final void setLibraryTarget(int _value) {
throw throwCannotSetFromSubproject();
}

@Override
public final void setLibraryTarget(String value) {
throw throwCannotSetFromSubproject();
}

@Override
public final void setDistributionTarget(int _value) {
throw throwCannotSetFromSubproject();
}

@Override
public final void setDistributionTarget(String _value) {
throw throwCannotSetFromSubproject();
}

@Override
public final void setRuntime(int _value) {
throw throwCannotSetFromSubproject();
}

@Override
public final void setRuntime(String _value) {
throw throwCannotSetFromSubproject();
}

private RuntimeException throwCannotSetFromSubproject() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FAILURE: Build failed with an exception.

* Where:
Build file '/Volumes/git/thermite/thermite-simulation/build.gradle' line: 2

* What went wrong:
A problem occurred evaluating project ':thermite-simulation'.
> The javaVersions extension can only be used from the root project. Did you mean javaVersion, which can be used to override on a project-by-project basis? You used it from thermite-simulation

throw new GradleException("The javaVersions extension can only be used from the root project."
+ " Did you mean javaVersion, which can be used to override on a project-by-project basis?"
+ " You used it from "
+ project.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,36 @@ class BaselineJavaVersionIntegrationTest extends IntegrationSpec {
assertBytecodeVersion(compiledClass, JAVA_17_BYTECODE, ENABLE_PREVIEW_BYTECODE)
}

def 'setting library target to preview version fails'() {
when:
buildFile << '''
javaVersions {
libraryTarget = '17_PREVIEW'
}
'''.stripIndent(true)
file('src/main/java/Main.java') << java17PreviewCode

then:
ExecutionResult result = runTasksWithFailure('compileJava', '-i')
result.standardError.contains 'cannot be run on newer JVMs'
}

def 'java 17 preview on single project works'() {
when:
buildFile << '''
javaVersion {
runtime = '17_PREVIEW'
target = '17_PREVIEW'
}
'''.stripIndent(true)
file('src/main/java/Main.java') << java17PreviewCode
File compiledClass = new File(projectDir, "build/classes/java/main/Main.class")

then:
runTasksSuccessfully('compileJava', '-i')
assertBytecodeVersion(compiledClass, JAVA_17_BYTECODE, ENABLE_PREVIEW_BYTECODE)
}

def 'java 17 preview javadoc works'() {
when:
buildFile << '''
Expand Down Expand Up @@ -220,7 +250,7 @@ class BaselineJavaVersionIntegrationTest extends IntegrationSpec {
when:
buildFile << '''
javaVersions {
libraryTarget = 11
libraryTarget = '11'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this just tests that the string format for setting versions works.

}
'''.stripIndent(true)
file('src/main/java/Main.java') << java11CompatibleCode
Expand Down