Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main' into bump-ehc…
Browse files Browse the repository at this point in the history
…ache

# Conflicts:
#	project/BuildSettings.scala
  • Loading branch information
sdudzin committed Apr 30, 2024
2 parents 4ddbb61 + 7a355e3 commit e846478
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 40 deletions.
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
version: 2
updates:
- package-ecosystem: "gradle"
directory: "dev-mode/gradle-plugin"
schedule:
interval: "weekly"
commit-message:
prefix: "[Gradle] "
- package-ecosystem: "github-actions"
directory: "/"
schedule:
Expand All @@ -9,8 +15,12 @@ updates:
schedule:
interval: "weekly"
target-branch: "3.0.x"
commit-message:
prefix: "[3.0.x] "
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
target-branch: "2.9.x"
commit-message:
prefix: "[2.9.x] "
12 changes: 12 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"enabledManagers": ["gradle-wrapper"],
"labels": [
"type:updates"
],
"commitMessageTopic": "`{{depName}}`",
"commitMessageExtra": "to `{{#if isPinDigest}}{{{newDigestShort}}}{{else}}{{#if isMajor}}v{{{newMajor}}}{{else}}{{#if isSingleVersion}}v{{{newVersion}}}{{else}}{{#if newValue}}{{{newValue}}}{{else}}{{{newDigestShort}}}{{/if}}{{/if}}{{/if}}{{/if}}` (was `{{currentVersion}}`)"
}
4 changes: 4 additions & 0 deletions .github/workflows/dependency-graph.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ jobs:
with:
fetch-depth: 0
ref: ${{ inputs.ref }}
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- uses: scalacenter/sbt-dependency-submission@v2
with:
# We submit ./documentation/build.sbt because the documentation project depends on the root project(s)
Expand Down
1 change: 1 addition & 0 deletions dev-mode/gradle-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ dependencies {
testImplementation(libs.assertj)
testImplementation(libs.commons.io)
testImplementation(libs.freemarker)
testImplementation(libs.mockito)
}

tasks.jar {
Expand Down
10 changes: 6 additions & 4 deletions dev-mode/gradle-plugin/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
[versions]
gradle-plugin-publish = "1.2.1"
nexus-publish = "1.3.0"
spotless = "6.19.0"
assertj = "3.24.2"
commons-io = "2.13.0"
nexus-publish = "2.0.0"
spotless = "6.25.0"
assertj = "3.25.3"
commons-io = "2.16.1"
freemarker = "2.3.32"
twirl = "2.0.3"
mockito = "5.11.0"

[libraries]
assertj = { group = "org.assertj", name = "assertj-core", version.ref = "assertj" }
commons-io = { group = "commons-io", name = "commons-io", version.ref = "commons-io" }
freemarker = { group = "org.freemarker", name = "freemarker", version.ref = "freemarker" }
mockito = { group = "org.mockito", name = "mockito-core", version.ref = "mockito" }

[plugins]
gradle-plugin-publish = { id = "com.gradle.plugin-publish", version.ref = "gradle-plugin-publish" }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=f2b9ed0faf8472cbe469255ae6c86eddb77076c75191741b4a462f33128dd419
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
distributionSha256Sum=194717442575a6f96e1c1befa2c30e9a4fc90f701d7aee33eb879b79e7ff05c0
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.gradle.api.Incubating;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
Expand All @@ -29,8 +30,7 @@
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.api.tasks.scala.ScalaCompile;
import org.gradle.api.tasks.compile.AbstractCompile;
import org.gradle.language.jvm.tasks.ProcessResources;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -63,26 +63,18 @@ private FileCollection filterNonChangingArtifacts(Configuration configuration) {

private List<File> findClasspathDirectories(@Nullable Project project) {
if (project == null) return List.of();
return List.of(
project
.getTasks()
.named(COMPILE_JAVA_TASK_NAME, JavaCompile.class)
.get()
.getDestinationDirectory()
.get()
.getAsFile(),
project
.getTasks()
.named("compileScala", ScalaCompile.class)
.get()
.getDestinationDirectory()
.get()
.getAsFile(),
project
.getTasks()
.named(PROCESS_RESOURCES_TASK_NAME, ProcessResources.class)
.get()
.getDestinationDir());
return project.getTasks().stream()
.map(
task -> {
if (List.of(COMPILE_JAVA_TASK_NAME, "compileScala").contains(task.getName())) {
return ((AbstractCompile) task).getDestinationDirectory().get().getAsFile();
} else if (task.getName().equals(PROCESS_RESOURCES_TASK_NAME)) {
return ((ProcessResources) task).getDestinationDir();
}
return null;
})
.filter(Objects::nonNull)
.toList();
}

private List<DirectoryProperty> findAssetsDirectories(@Nullable Project project) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
*/
package play.gradle;

import static org.assertj.core.api.Assertions.assertThat;

import org.gradle.api.Project;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/** A simple unit test to check a Play Gradle Plugin */
class PlayPluginTest {

private Project project;

@BeforeEach
void init() {
project = ProjectBuilder.builder().build();
project.getPluginManager().apply("application");
project.getPluginManager().apply("org.playframework.play");
}

@Test
@DisplayName("Play extension should be registered")
void extensionShouldBeRegistered() {
PlayExtension ext = (PlayExtension) project.getExtensions().findByName("play");
assertThat(ext).isNotNull();
assertThat((ext).getLang().getOrNull()).isEqualTo(Language.JAVA);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
*/
package play.gradle;

import static org.assertj.core.api.Assertions.assertThat;
import static play.gradle.internal.Utils.javaPluginExtension;

import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.SourceDirectorySet;
import org.gradle.api.internal.artifacts.configurations.DefaultConfiguration;
import org.gradle.api.tasks.SourceSet;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import play.gradle.plugin.PlayPlugin;

/** A simple unit test to check a Play Routes Plugin */
class PlayRoutesPluginTest {

private Project project;

@BeforeEach
void init() {
project = ProjectBuilder.builder().build();
project.getPluginManager().apply("application");
project.getPluginManager().apply("org.playframework.play");
}

@Test
@DisplayName("Play Routes configuration should be registered")
void routesConfigurationShouldBeRegistered() {
Configuration conf = project.getConfigurations().findByName("playRoutes");
assertThat(conf).isNotNull();
assertThat(conf.isTransitive()).isTrue();
assertThat(conf.isVisible()).isFalse();
((DefaultConfiguration) conf).runDependencyActions();
assertThat(conf.getDependencies())
.anyMatch(
dependency ->
PlayPlugin.PLAY_GROUP_ID.equals(dependency.getGroup())
&& dependency.getName().startsWith("play-routes-compiler"));
}

@Test
@DisplayName("Routes source directory set should be registered for main source set")
void routesSourceDirectorySetShouldBeRegisteredForMainSourceSet() {
checkRoutesSourceDirectorySet(javaPluginExtension(project).getSourceSets().getByName("main"));
}

@Test
@DisplayName("Routes source directory set should be registered for test source set")
void routesSourceDirectorySetShouldBeRegisteredForTestSourceSet() {
checkRoutesSourceDirectorySet(javaPluginExtension(project).getSourceSets().getByName("test"));
}

@Test
@DisplayName("Routes compile task should be registered for main/test source sets")
void compileTasksShouldBeRegistered() {
assertThat(project.getTasks().findByName("compilePlayRoutes")).isNotNull();
assertThat(project.getTasks().findByName("compileTestPlayRoutes")).isNotNull();
}

private void checkRoutesSourceDirectorySet(SourceSet sourceSet) {
assertThat(sourceSet).isNotNull();
SourceDirectorySet routesSourceSet =
(SourceDirectorySet) sourceSet.getExtensions().findByName("routes");
assertThat(routesSourceSet).isNotNull();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (C) from 2022 The Play Framework Contributors <https://github.com/playframework>, 2011-2021 Lightbend Inc. <https://www.lightbend.com>
*/
package play.gradle;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.File;
import org.gradle.api.Project;
import org.gradle.api.internal.SettingsInternal;
import org.gradle.api.internal.project.DefaultProject;
import org.gradle.groovy.scripts.ScriptSource;
import org.gradle.initialization.SettingsState;
import org.gradle.internal.resource.ResourceLocation;
import org.gradle.internal.resource.TextResource;
import org.gradle.invocation.DefaultGradle;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import play.gradle.task.PlayRun;

/** A simple unit test to check a Play Run Plugin */
class PlayRunPluginTest {

private Project project;

@BeforeEach
void init() {
project = ProjectBuilder.builder().build();
project.getPluginManager().apply("application");
project.getPluginManager().apply("org.playframework.play");
((DefaultGradle) project.getGradle()).attachSettings(mockSettings());
}

/** Workaround <a href="https://github.com/gradle/gradle/issues/20301">gradle#20301</a> */
private SettingsState mockSettings() {
var locationMock = mock(ResourceLocation.class);
when(locationMock.getFile()).thenReturn(new File("."));
var resourcesMock = mock(TextResource.class);
when(resourcesMock.getLocation()).thenReturn(locationMock);
var settingsScriptMock = mock(ScriptSource.class);
when(settingsScriptMock.getResource()).thenReturn(resourcesMock);
var settingsInternal = mock(SettingsInternal.class);
when(settingsInternal.getSettingsScript()).thenReturn(settingsScriptMock);
SettingsState settings = mock(SettingsState.class);
when(settings.getSettings()).thenReturn(settingsInternal);
return settings;
}

@Test
@DisplayName("Check classpath with submodules")
void checkClasspathWithSubmodules() {
Project javaLib = ProjectBuilder.builder().withParent(project).withName("java-lib").build();
javaLib.getPluginManager().apply("java");

Project scalaLib = ProjectBuilder.builder().withParent(project).withName("scala-lib").build();
scalaLib.getPluginManager().apply("scala");

project.getRepositories().add(project.getRepositories().mavenCentral());
project.getDependencies().add("implementation", javaLib);
project.getDependencies().add("implementation", scalaLib);

((DefaultProject) project).evaluate();

assertThat(((PlayRun) project.getTasks().findByName("playRun")).getClasses())
.contains(
project.getLayout().getBuildDirectory().file("classes/scala/main").get().getAsFile(),
project.getLayout().getBuildDirectory().file("classes/java/main").get().getAsFile(),
project.getLayout().getBuildDirectory().file("resources/main").get().getAsFile(),
javaLib.getLayout().getBuildDirectory().file("classes/java/main").get().getAsFile(),
javaLib.getLayout().getBuildDirectory().file("resources/main").get().getAsFile(),
scalaLib.getLayout().getBuildDirectory().file("classes/scala/main").get().getAsFile(),
scalaLib.getLayout().getBuildDirectory().file("classes/java/main").get().getAsFile(),
scalaLib.getLayout().getBuildDirectory().file("resources/main").get().getAsFile());
}
}
46 changes: 46 additions & 0 deletions documentation/manual/releases/release29/migration29/Migration29.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ play.core.server.SelfSignedSSLEngineProvider.sslContext(SelfSigned.scala:36)
...
```

#### Self-Signed Certificates in tests

To circumvent this exception within a standard Play application setup, the [[binding of the HTTPS port for tests has been disabled|Migration29#Test-servers-no-longer-bind-an-HTTPS-port-by-default]] as a default configuration. It is noteworthy that the unbinding of the HTTPS port in tests is a reversion to an older behavior, as HTTPS port binding was unintentionally activated by us after being disabled in earlier Play versions.

Should you desire to conduct tests against the HTTPS port while using a Play-generated self-signed certificate, a workaround is required for Java 17. It involves adding an `--add-export` flag to the Java 17 command line. Moreover, it is crucial to fork a new Java Virtual Machine (JVM) instance during test execution:
Expand All @@ -341,6 +343,50 @@ Alternatively, you can set the `JAVA_TOOL_OPTIONS` environment variable:
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS --add-exports=java.base/sun.security.x509=ALL-UNNAMED";
```

#### Self-Signed Certificates in DEV mode

If you, for whatever reason, serve your application [[in DEV mode via HTTPS|ConfigFile#Using-with-the-run-command]] using a Play-generated self-signed certificate, you also have to add the `--add-export` flag to the `sbt` command (which eventually starts a Java process in which your application runs):

```sh
# For example, to enter the interactive sbt shell:
sbt -J"--add-exports=java.base/sun.security.x509=ALL-UNNAMED"

# Or, mixed with other arguments and directly running the application:
sbt -J"-Dhttp.port=disabled" -J"-Dhttps.port=9443" -J"--add-exports=java.base/sun.security.x509=ALL-UNNAMED" run
```

Instead of passing the flag on the command line, you can also put it into either a `.jvmopts` file within the root directory of your project

```
--add-exports=java.base/sun.security.x509=ALL-UNNAMED
```

or inside a `.sbtopts` file, again in the root of your project (be aware of the `-J` prefix):

```
-J--add-exports=java.base/sun.security.x509=ALL-UNNAMED
```

As a last option, you could, again, also set the `JAVA_TOOL_OPTIONS` environment variable.

#### Self-Signed Certificates in production

It's not recommended to serve websites via self-signed certificates in production. However, if you do so, e.g., to test [[the packaged application|Deploying]] locally, you also need to add the `--add-export` flag to the script that starts the Java process in which your application runs:

```sh
<my-project-script> -J--add-exports=java.base/sun.security.x509=ALL-UNNAMED #-Dhttp.port=disabled -Dhttps.port=9443
```

Instead of passing the flag via the command line, you can set it once in `build.sbt` and it will be appended to the start script automatically:

```sbt
Universal / javaOptions += "-J--add-exports=java.base/sun.security.x509=ALL-UNNAMED"
```

Alternatively, you can make use of the `JAVA_TOOL_OPTIONS` environment variable, as described above.

#### Self-Signed Certificates in Java 21

Unfortunately, the aforementioned workaround is not sufficient for Java 21. In this case, you may encounter the following exception:

```sh
Expand Down
Loading

0 comments on commit e846478

Please sign in to comment.