diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4fe0698e..670a83155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: path: ${{ env.PRIVATE_REPO }} test: - name: Gradle ${{ matrix.gradle }} on Java ${{ matrix.java }} + name: Gradle ${{ matrix.gradle }} on Java ${{ matrix.java }}${{ matrix.toolchainJavaVersion && format(' (Java {0} Container)', matrix.toolchainJavaVersion) || '' }} runs-on: ubuntu-latest needs: build @@ -49,13 +49,29 @@ jobs: gradle: '6.9.4' container: "['jetty9.3','jetty9.4','tomcat85','tomcat9']" + - java: 8 + gradle: '6.9.4' + container: "['jetty9.3','jetty9.4','tomcat85','tomcat9']" + toolchainJavaVersion: 17 + - java: 11 gradle: '6.9.4' container: "['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']" - + + - java: 11 + gradle: '6.9.4' + container: "['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']" + toolchainJavaVersion: 17 + + - java: 17 + gradle: '7.6.4' + container: "['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']" + properties: '-Pspock_version=2.3-groovy-3.0 -PgebVersion=5.1' + - java: 17 gradle: '7.6.4' container: "['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']" + toolchainJavaVersion: 21 properties: '-Pspock_version=2.3-groovy-3.0 -PgebVersion=5.1' # TODO: add a JDK-21 build but fix the following issue before that: @@ -66,6 +82,8 @@ jobs: TEST_ALL_CONTAINERS: ${{ matrix.container }} GRADLE_VERSION: ${{ matrix.gradle }} EXTRA_PROPERTIES: ${{ matrix.properties }} + TOOLCHAIN_JAVA_ARGS: "${{ matrix.toolchainJavaVersion && format('-PtoolchainJavaVersion={0}', matrix.toolchainJavaVersion) || '' }}" + GRADLE_TEST_TASK: "${{ matrix.toolchainJavaVersion && 'testAllJavaToolchain' || 'testAll' }}" steps: - uses: actions/checkout@v3 @@ -101,8 +119,8 @@ jobs: ../gradlew --no-daemon \ --warning-mode all \ -PprivateRepoDir=$PRIVATE_REPO \ - $EXTRA_PROPERTIES \ + $EXTRA_PROPERTIES $TOOLCHAIN_JAVA_ARGS \ -PgeckoDriverPlatform=linux64 \ -PtestAllContainers=$TEST_ALL_CONTAINERS \ - testAll + $GRADLE_TEST_TASK working-directory: integrationTests diff --git a/.gitignore b/.gitignore index 78ae5c553..5d4e9da2f 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ build *.iws bin/ .DS_Store +.docker-gradle/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..3a195bd1f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +FROM ubuntu as base +RUN apt-get update + +FROM base as base-utils +ENV _BASH_UTILS_DIR=/root/.bashrc.d +COPY <<-EOF $_BASH_UTILS_DIR/0_on_bash_ready.bash +shopt -s expand_aliases +export _on_bash_ready_i=\$(find $_BASH_UTILS_DIR -type f | wc -l) +function on_bash_ready (){ + ((_on_bash_ready_i++)) + local file="$_BASH_UTILS_DIR/\${_on_bash_ready_i}.bash" + echo "\$@" >> \$file && \ + sed -i 's/\r\$//' \$file && \ + source \$file +} +EOF +RUN sed -i 's/\r$//' $_BASH_UTILS_DIR/0_on_bash_ready.bash +RUN echo "while read -r FILE; do source \$FILE; done < <( find $_BASH_UTILS_DIR -name '*.bash' | sort)" >> ~/.profile +SHELL ["/bin/bash", "-l", "-c"] + + +FROM base-utils as firefox +RUN apt-get install -y wget +RUN install -d -m 0755 /etc/apt/keyrings +RUN wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- | tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null +RUN echo 'deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main' | tee -a /etc/apt/sources.list.d/mozilla.list > /dev/null +RUN apt-get update && apt-get install -y firefox-devedition-l10n-eu +RUN ln -s /usr/bin/firefox-devedition /usr/bin/firefox + + +FROM firefox as firefox-sdkman +RUN apt-get install -y curl unzip zip findutils +RUN curl -s "https://get.sdkman.io?rcupdate=false" | bash +RUN on_bash_ready source /root/.sdkman/bin/sdkman-init.sh + +FROM firefox-sdkman as firefox-jdk +ARG JAVA_VERSIONS="8.0.412-amzn" +ENV JAVA_VERSIONS="$JAVA_VERSIONS" +RUN on_bash_ready 'alias install_jdk="sdk install java $1"' +RUN for version in ${JAVA_VERSIONS//,/ } ; do install_jdk $version ; done + + +FROM firefox-jdk as firefox-jdk-gradle +ARG GRADLE_VERSION="6.9.4" +RUN sdk install gradle $GRADLE_VERSION diff --git a/docker_gradlew.sh b/docker_gradlew.sh new file mode 100644 index 000000000..c0ecf867a --- /dev/null +++ b/docker_gradlew.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -e + +function build_docker_gradlew_image(){ + docker build -t "docker_gradlew" . \ + --build-arg JAVA_VERSIONS="$_javas" \ + --build-arg GRADLE_VERSION="$_gradle" +} + +function run_docker(){ + build_docker_gradlew_image "$*" + + local working_dir="-w //project/${_working_dir}" + + local project_volume="-v //$(realpath .)://project" + + local gradle_home_volume="" + if [ "$_gradle_home" ]; then + gradle_home_volume="-v //$(realpath $_gradle_home)://root/.gradle" + fi + + local params="$DOCKER_ARGS $project_volume $working_dir $gradle_home_volume" + + + echo "RUNNING:" docker run --rm -it $params docker_gradlew "$@" + docker run --rm -it $params docker_gradlew "$@" +} + +function run_docker_gradle() { + run_docker bash -lc "gradle $*" +} + + +JDK["8"]="8.0.412-amzn" +JDK["11"]="11.0.23-amzn" +JDK["17"]="17.0.11-amzn" +JDK["21"]="21.0.3-amzn" + +GRADLE["6"]="6.9.4" +GRADLE["7"]="7.6.4" + +POSITIONAL_ARGS=() +while [[ $# -gt 0 ]]; do + case "$1" in + -j|--java) export _javas+=",${JDK[$2]:=$2}" && shift 2 ;; + -g|--gradle) export _gradle=${GRADLE[$2]:=$2} && shift 2 ;; + -h|--gradle-home) export _gradle_home=$2 && shift 2 ;; + -w|--working-dir) export _working_dir=$2 && shift 2 ;; + -b|--bash) export _bash="Yes" && shift 1 ;; + + *) POSITIONAL_ARGS+=("$1") && shift ;; + esac +done +set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters + +if [ "$_bash" ]; then + run_docker bash -l +else + run_docker_gradle "${@}" +fi \ No newline at end of file diff --git a/docker_integration_tests.sh b/docker_integration_tests.sh new file mode 100644 index 000000000..a94bbf740 --- /dev/null +++ b/docker_integration_tests.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -e + +export common_gradle_args="--console=plain --no-daemon -Porg.gradle.java.installations.auto-download=false -PgeckoDriverPlatform=linux64" + +#ci.yml plugin build step +./docker_gradlew.sh \ + --java 11 \ + --gradle 6 \ + --gradle-home .docker-gradle \ + $common_gradle_args \ + build + +#ci.yml matrix case #1 +./docker_gradlew.sh \ + --java 8 \ + --gradle 6 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','tomcat85','tomcat9']\"" \ + testAll + +#ci.yml matrix case #2 +./docker_gradlew.sh \ + --java 11 \ + --gradle 6 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']\"" \ + testAll + +#ci.yml matrix case #3 +./docker_gradlew.sh \ + --java 17 \ + --gradle 7 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']\"" \ + -Pspock_version=2.3-groovy-3.0 -PgebVersion=5.1 \ + testAll + +#ci.yml matrix case #1 + toolchain java v21 +./docker_gradlew.sh \ + --java 17 --java 8 \ + --gradle 6 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','tomcat85','tomcat9']\"" \ + -PtoolchainJavaVersion=17 \ + testAllJavaToolchain + +#ci.yml matrix case #2 + toolchain java v17 +./docker_gradlew.sh \ + --java 17 --java 11 \ + --gradle 6 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']\"" \ + -PtoolchainJavaVersion=17 \ + testAllJavaToolchain + + +#ci.yml matrix case #3 + toolchain java v21 +./docker_gradlew.sh \ + --java 21 --java 17 \ + --gradle 7 \ + --gradle-home .docker-gradle \ + --working-dir integrationTests \ + $common_gradle_args \ + -PtestAllContainers="\"['jetty9.3','jetty9.4','jetty10','tomcat85','tomcat9']\"" \ + -Pspock_version=2.3-groovy-3.0 -PgebVersion=5.1 \ + -PtoolchainJavaVersion=21 \ + testAllJavaToolchain \ No newline at end of file diff --git a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/AnyJavaVersion.java b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/AnyJavaVersion.java new file mode 100644 index 000000000..0d1202f74 --- /dev/null +++ b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/AnyJavaVersion.java @@ -0,0 +1,45 @@ +package org.akhikhl.gretty.internal.integrationTests; + +import java.util.Objects; + +public class AnyJavaVersion implements Comparable { + private int majorVersion; + + private AnyJavaVersion(int majorVersion) { + this.majorVersion = majorVersion; + } + + public int getMajorVersion() { + return majorVersion; + } + + public boolean isJava9Compatible() { + return majorVersion >= 9; + } + + public boolean isJava10Compatible() { + return majorVersion >= 10; + } + + @Override + public int compareTo(AnyJavaVersion o) { + return Integer.compare(this.majorVersion, o.majorVersion); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AnyJavaVersion that = (AnyJavaVersion) o; + return majorVersion == that.majorVersion; + } + + @Override + public int hashCode() { + return Objects.hashCode(majorVersion); + } + + public static AnyJavaVersion of(Integer integer) { + return new AnyJavaVersion(Objects.requireNonNull(integer)); + } +} \ No newline at end of file diff --git a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/BasePlugin.groovy b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/BasePlugin.groovy index faa94f54d..a65a77aec 100644 --- a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/BasePlugin.groovy +++ b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/BasePlugin.groovy @@ -1,6 +1,5 @@ package org.akhikhl.gretty.internal.integrationTests -import org.akhikhl.gretty.ServletContainerConfig import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.publish.maven.MavenPublication @@ -27,7 +26,9 @@ class BasePlugin implements Plugin { } protected void configureExtensions(Project project) { - // does nothing by default + if (!project.extensions.findByName('javaVersion')) { + project.extensions.add(AnyJavaVersion, 'javaVersion', JavaToolchainIntegrationTestPlugin.getToolchainJavaVersion(project)) + } } protected void configurePublications(Project project) { @@ -98,6 +99,9 @@ class BasePlugin implements Plugin { if(!project.rootProject.tasks.findByName('testAll')) project.rootProject.task 'testAll' + if(!project.rootProject.tasks.findByName('testAllJavaToolchain')) + project.rootProject.task 'testAllJavaToolchain' + project.tasks.withType(Test).configureEach { if (GradleVersion.current().baseVersion.version.startsWith("7.")) { useJUnitPlatform() diff --git a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/IntegrationTestPlugin.groovy b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/IntegrationTestPlugin.groovy index 1410474ca..b243042d6 100644 --- a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/IntegrationTestPlugin.groovy +++ b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/IntegrationTestPlugin.groovy @@ -3,7 +3,6 @@ package org.akhikhl.gretty.internal.integrationTests import org.akhikhl.gretty.AppAfterIntegrationTestTask import org.akhikhl.gretty.AppBeforeIntegrationTestTask import org.akhikhl.gretty.ServletContainerConfig -import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.tasks.Copy import org.gradle.api.tasks.testing.Test @@ -48,6 +47,14 @@ class IntegrationTestPlugin extends BasePlugin { protected void configureExtensions(Project project) { super.configureExtensions(project) + /** + * Makes the project aware of java toolchain if it has -PtoolchainJavaVersion=17 parameter. + * Toolchain DSL is configured automatically for the provided version of java. + **/ + project.ext.defineAsJavaToolchainAwareIntegrationTest = { + JavaToolchainIntegrationTestPlugin.applyPluginConditionally(project) + } + project.ext.defineIntegrationTest = { def integrationTestTask_ = project.tasks.findByName('integrationTest') @@ -62,6 +69,10 @@ class IntegrationTestPlugin extends BasePlugin { else testClassesDirs = project.sourceSets.integrationTest.output.classesDirs classpath = project.sourceSets.integrationTest.runtimeClasspath + + JavaToolchainIntegrationTestPlugin.whenApplied(project) { plugin -> + plugin.forceTaskToUseGradleJvm(it) + } } integrationTestTask_ @@ -76,16 +87,20 @@ class IntegrationTestPlugin extends BasePlugin { integrationTestAllContainersTask = project.task('integrationTestAllContainers') + JavaToolchainIntegrationTestPlugin.whenApplied(project) { plugin -> + plugin.forceTaskToUseGradleJvm(integrationTestAllContainersTask) + } + if (!integrationTestContainers) integrationTestContainers = ServletContainerConfig.getConfigNames().collect() // returns immutable and we want to filter later - if (JavaVersion.current().isJava9Compatible()) { + if (project.javaVersion.isJava9Compatible()) { // excluding jetty7 and jetty8 under JDK9, can no longer compile JSPs to default 1.5 target, // see https://github.com/gretty-gradle-plugin/gretty/issues/15 integrationTestContainers -= ['jetty7', 'jetty8'] } - if (JavaVersion.current().isJava10Compatible()) { + if (project.javaVersion.isJava10Compatible()) { // excluding jetty9 under JDK10, can no longer compile JSPs to default 1.7 target, integrationTestContainers -= ['jetty9'] } @@ -110,6 +125,10 @@ class IntegrationTestPlugin extends BasePlugin { else testClassesDirs = project.sourceSets.integrationTest.output.classesDirs classpath = project.sourceSets.integrationTest.runtimeClasspath + + JavaToolchainIntegrationTestPlugin.whenApplied(project) { plugin -> + plugin.forceTaskToUseGradleJvm(thisTask) + } } integrationTestAllContainersTask.dependsOn project.tasks['integrationTest_' + container] @@ -187,6 +206,10 @@ class IntegrationTestPlugin extends BasePlugin { srcDir 'src/integrationTest/resources' } runtimeClasspath += project.rootProject.files('config/gebConfig') + + JavaToolchainIntegrationTestPlugin.whenApplied(project) { plugin -> + plugin.forceSourceSetToUseGradleJvm(project, it) + } } } } diff --git a/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/JavaToolchainIntegrationTestPlugin.groovy b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/JavaToolchainIntegrationTestPlugin.groovy new file mode 100644 index 000000000..ae9c4661c --- /dev/null +++ b/integrationTests/buildSrc/gretty-integrationTest/src/main/groovy/org/akhikhl/gretty/internal/integrationTests/JavaToolchainIntegrationTestPlugin.groovy @@ -0,0 +1,91 @@ +package org.akhikhl.gretty.internal.integrationTests + +import org.gradle.api.Action +import org.gradle.api.JavaVersion +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.compile.GroovyCompile +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.api.tasks.testing.Test +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +import java.util.function.Consumer + +class JavaToolchainIntegrationTestPlugin implements Plugin { + public static final String PLUGIN_ID = "org.gretty.internal.integrationTests.JavaToolchainIntegrationTestPlugin" + private static final Logger log = LoggerFactory.getLogger(IntegrationTestPlugin) + + public static void applyPluginConditionally(Project project) { + if (project.findProperty('toolchainJavaVersion')) { + project.apply plugin: PLUGIN_ID + } + } + + public static void whenApplied(Project project, Consumer config) { + project.plugins.withId(PLUGIN_ID, new Action() { + @Override + void execute(Plugin plugin) { + config.accept((JavaToolchainIntegrationTestPlugin) plugin) + } + }) + } + + @Override + public void apply(Project project) { + int javaVersion = Integer.parseInt("${project.toolchainJavaVersion}") + + project.java { + toolchain { + languageVersion = JavaLanguageVersion.of(javaVersion) + } + } + + project.rootProject.tasks.named('testAllJavaToolchain').configure { + dependsOn project.tasks.testAll + } + } + + public void forceSourceSetToUseGradleJvm(Project project, SourceSet sourceSet) { + project.tasks.named(sourceSet.getCompileTaskName('java')).configure({ forceTaskToUseGradleJvm(it) }) + project.tasks.named(sourceSet.getCompileTaskName('groovy')).configure({ forceTaskToUseGradleJvm(it) }) + } + + public void forceTaskToUseGradleJvm(Task task) { + task.project.with { proj -> + if (task instanceof JavaCompile) { + task.javaCompiler.value(proj.javaToolchains.compilerFor(gradleJvmSpec)) + } + + if (task instanceof GroovyCompile) { + task.javaLauncher.value(proj.javaToolchains.launcherFor(gradleJvmSpec)) + } + + if (task instanceof Test) { + task.javaLauncher.value(proj.javaToolchains.launcherFor(gradleJvmSpec)) + } + } + } + + public static AnyJavaVersion getToolchainJavaVersion(Project project) { + //java 8 compatible, Optional.or() available from java 9 + String majorVersion = project.findProperty('toolchainJavaVersion') ?: JavaVersion.current().majorVersion + + return Optional.ofNullable(majorVersion) + .map({ Integer.parseInt("$it") }) + .map({ AnyJavaVersion.of(it) }) + .get() + } + + public static JavaVersion getGradleJavaVersion() { + return JavaVersion.current() + } + + private static def getGradleJvmSpec() { + def gradleJvmVerson = Integer.valueOf(getGradleJavaVersion().getMajorVersion()) + return { languageVersion = JavaLanguageVersion.of(gradleJvmVerson) } + } +} diff --git a/integrationTests/buildSrc/gretty-integrationTest/src/main/resources/META-INF/gradle-plugins/org.gretty.internal.integrationTests.JavaToolchainIntegrationTestPlugin.properties b/integrationTests/buildSrc/gretty-integrationTest/src/main/resources/META-INF/gradle-plugins/org.gretty.internal.integrationTests.JavaToolchainIntegrationTestPlugin.properties new file mode 100644 index 000000000..738554447 --- /dev/null +++ b/integrationTests/buildSrc/gretty-integrationTest/src/main/resources/META-INF/gradle-plugins/org.gretty.internal.integrationTests.JavaToolchainIntegrationTestPlugin.properties @@ -0,0 +1 @@ +implementation-class=org.akhikhl.gretty.internal.integrationTests.JavaToolchainIntegrationTestPlugin diff --git a/integrationTests/extraResourceBases/build.gradle b/integrationTests/extraResourceBases/build.gradle index 96479db05..4ee3aa996 100644 --- a/integrationTests/extraResourceBases/build.gradle +++ b/integrationTests/extraResourceBases/build.gradle @@ -13,5 +13,6 @@ gretty { extraResourceBase 'extra1' } +defineAsJavaToolchainAwareIntegrationTest() defineIntegrationTest() testAll.dependsOn defineIntegrationTestAllContainers() diff --git a/integrationTests/farm/MyWebApp/build.gradle b/integrationTests/farm/MyWebApp/build.gradle index afd4aa6a1..3e0d85e8d 100644 --- a/integrationTests/farm/MyWebApp/build.gradle +++ b/integrationTests/farm/MyWebApp/build.gradle @@ -21,6 +21,7 @@ product { additionalFiles = ['./farm/README.md': './README.md'] } +defineAsJavaToolchainAwareIntegrationTest() defineIntegrationTest() testAll.dependsOn defineFarmIntegrationTestAllContainers({ diff --git a/integrationTests/farm/MyWebService/build.gradle b/integrationTests/farm/MyWebService/build.gradle index b8fd39886..c84076b2e 100644 --- a/integrationTests/farm/MyWebService/build.gradle +++ b/integrationTests/farm/MyWebService/build.gradle @@ -2,4 +2,5 @@ apply plugin: 'war' apply plugin: 'org.gretty' apply plugin: 'org.gretty.internal.integrationTests.IntegrationTestPlugin' +defineAsJavaToolchainAwareIntegrationTest() defineIntegrationTest() diff --git a/integrationTests/gradle-java-toolchain/README.md b/integrationTests/gradle-java-toolchain/README.md new file mode 100644 index 000000000..07c3a4a55 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/README.md @@ -0,0 +1,30 @@ +# gradle-java-toolchain + +Simple gretty servlet application powered by gradle java toolchain. + +## How to run + +```bash +cd integrationTests/gradle-java-toolchain +gradle appRun +``` + + +## How to test + +```bash +cd integrationTests/gradle-java-toolchain +gradle integrationTest -PgeckoDriverPlatform=linux64 -PtoolchainJavaVersion=21 +``` +or +```bash +./docker_gradlew.sh --java 21 --java 11 --gradle 7 --working-dir integrationTests/gradle-java-toolchain -PtoolchainJavaVersion=21 -Pspock_version=2.3-groovy-3.0 -PgebVersion=5.1 integrationTest +``` +## How to build a product + + +```bash +cd integrationTests/gradle-java-toolchain +gradle buildProduct +``` + diff --git a/integrationTests/gradle-java-toolchain/build.gradle b/integrationTests/gradle-java-toolchain/build.gradle new file mode 100644 index 000000000..644c17f65 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'org.gretty' +apply plugin: 'org.gretty.internal.integrationTests.IntegrationTestPlugin' + +dependencies { + implementation localGroovy() + implementation 'org.webjars:bootstrap:3.2.0' + implementation 'org.webjars:jquery:2.1.1' + // We use Velocity for example of template processing within the webapp. + implementation 'org.apache.velocity:velocity:1.7' +} + +gretty { + if (project.javaVersion.isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" +} + +defineAsJavaToolchainAwareIntegrationTest() +defineIntegrationTest() +testAll.dependsOn defineIntegrationTestAllContainers(['jetty8', 'jetty9', 'jetty10', 'tomcat85', 'tomcat9']) + +//typical toolchain DSL +java { + toolchain { + languageVersion = JavaLanguageVersion.of("${project.javaVersion.majorVersion}") + } +} + +//toolchain aware integration test +tasks.withType(Test).configureEach { + systemProperty 'toolchainJavaVersion', "${project.javaVersion.majorVersion}" +} diff --git a/integrationTests/gradle-java-toolchain/src/integrationTest/groovy/org/akhikhl/examples/gretty/gradle/toolchain/PageSpec.groovy b/integrationTests/gradle-java-toolchain/src/integrationTest/groovy/org/akhikhl/examples/gretty/gradle/toolchain/PageSpec.groovy new file mode 100644 index 000000000..696a6babd --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/integrationTest/groovy/org/akhikhl/examples/gretty/gradle/toolchain/PageSpec.groovy @@ -0,0 +1,40 @@ +/* + * Gretty + * + * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. + * + * See the file "LICENSE" for copying and usage permission. + * See the file "CONTRIBUTORS" for complete list of contributors. + */ +package org.akhikhl.examples.gretty.gradle.toolchain + +import geb.spock.GebReportingSpec + +class PageSpec extends GebReportingSpec { + + private static String baseURI + private static String toolchainJavaVersion + + void setupSpec() { + baseURI = System.getProperty('gretty.baseURI') + toolchainJavaVersion = Objects.requireNonNull(System.getProperty('toolchainJavaVersion')) + ?.with({ it == '8' ? '1.8' : it }) + } + + def 'should get expected static page'() { + when: + go "${baseURI}/index.html" + then: + $('h1').text() == 'Hello, world!' + $('p', 0).text() == /This is static HTML page./ + } + + def 'should get expected response from servlet'() { + when: + go "${baseURI}/dynamic" + then: + $('h1').text() == 'Hello, world!' + $('p', 0).text() == /This is dynamic HTML page generated by servlet./ + $('h2').text().startsWith('javaVersion=' + "$toolchainJavaVersion") + } +} diff --git a/integrationTests/gradle-java-toolchain/src/main/java/org/akhikhl/examples/gretty/gradle/toolchain/ExampleServlet.java b/integrationTests/gradle-java-toolchain/src/main/java/org/akhikhl/examples/gretty/gradle/toolchain/ExampleServlet.java new file mode 100644 index 000000000..38baac73a --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/java/org/akhikhl/examples/gretty/gradle/toolchain/ExampleServlet.java @@ -0,0 +1,53 @@ +/* + * Gretty + * + * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. + * + * See the file "LICENSE" for copying and usage permission. + * See the file "CONTRIBUTORS" for complete list of contributors. + */ +package org.akhikhl.examples.gretty.gradle.toolchain; + +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +public class ExampleServlet extends HttpServlet { + + private static final long serialVersionUID = -6506276378398106663L; + + private VelocityEngine ve = new VelocityEngine(); + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Template template = ve.getTemplate("/org/akhikhl/examples/gretty/hellogretty/templates/servletpage.html", "UTF-8"); + VelocityContext context = new VelocityContext(); + context.put("contextPath", request.getContextPath()); + context.put("today", new java.util.Date()); + context.put("javaVersion", System.getProperty("java.specification.version")); + PrintWriter out = response.getWriter(); + try { + template.merge(context, out); + out.flush(); + } finally { + out.close(); + } + } + + @Override + public void init() throws ServletException { + super.init(); + ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); + ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + ve.init(); + } +} diff --git a/integrationTests/gradle-java-toolchain/src/main/resources/org/akhikhl/examples/gretty/hellogretty/templates/servletpage.html b/integrationTests/gradle-java-toolchain/src/main/resources/org/akhikhl/examples/gretty/hellogretty/templates/servletpage.html new file mode 100644 index 000000000..fe3f7ed23 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/resources/org/akhikhl/examples/gretty/hellogretty/templates/servletpage.html @@ -0,0 +1,26 @@ + + + + Hello-world page + + + + + + + + + +
+
+
+

Hello, world!

+

This is dynamic HTML page generated by servlet.

+

Today is $today.

+

Click here to see static page.

+

javaVersion=$javaVersion

+
+
+
+ + diff --git a/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/filter.groovy b/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/filter.groovy new file mode 100644 index 000000000..812d3d5d4 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/filter.groovy @@ -0,0 +1,3 @@ +filter relPath: '/', { + redirect 'index.html' +} diff --git a/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/web.xml b/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..3399f8948 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,33 @@ + + + + RedirectFilter + org.akhikhl.gretty.RedirectFilter + + + RedirectFilter + /* + REQUEST + FORWARD + + + + jsp + *.html + + + + ExampleServlet + ExampleServlet + org.akhikhl.examples.gretty.gradle.toolchain.ExampleServlet + 1 + + + + ExampleServlet + /dynamic + + diff --git a/integrationTests/gradle-java-toolchain/src/main/webapp/css/default.css b/integrationTests/gradle-java-toolchain/src/main/webapp/css/default.css new file mode 100644 index 000000000..09e4763bb --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/webapp/css/default.css @@ -0,0 +1,14 @@ +body { + padding-top: 20px; + font-family: 'Open Sans', sans-serif; + font-size: 18px; +} + +h1 { + font-weight: 400; + font-size: 40px; +} + +.margin-base-vertical { + margin: 40px 0; +} diff --git a/integrationTests/gradle-java-toolchain/src/main/webapp/index.html b/integrationTests/gradle-java-toolchain/src/main/webapp/index.html new file mode 100644 index 000000000..87e2f4029 --- /dev/null +++ b/integrationTests/gradle-java-toolchain/src/main/webapp/index.html @@ -0,0 +1,24 @@ + + + + Hello-world page + + + + + + + + + +
+
+
+

Hello, world!

+

This is static HTML page.

+

Click here to see dynamic page generated by servlet.

+
+
+
+ + diff --git a/integrationTests/settings.gradle b/integrationTests/settings.gradle index 190d38137..0e48c75bc 100644 --- a/integrationTests/settings.gradle +++ b/integrationTests/settings.gradle @@ -7,6 +7,7 @@ include 'helloGrettyOverlay' include 'helloJersey' include 'extraResourceBases' include 'filterWebapp' +include 'gradle-java-toolchain' include 'testAnnotations' include 'testAnnotationsOverlay' include 'testDependency' diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-app/build.gradle b/integrationTests/spring-boot-farm-secure/spring-boot-app/build.gradle index c64ad5ba2..de1f0951a 100644 --- a/integrationTests/spring-boot-farm-secure/spring-boot-app/build.gradle +++ b/integrationTests/spring-boot-farm-secure/spring-boot-app/build.gradle @@ -16,7 +16,7 @@ gretty { realm = 'auth' realmConfigFile = '../security' singleSignOn = true - if (JavaVersion.current().isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" + if (project.javaVersion.isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" } farm { diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy b/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy deleted file mode 100644 index 37817aaa6..000000000 --- a/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootapp - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java b/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java new file mode 100644 index 000000000..fce931f0e --- /dev/null +++ b/integrationTests/spring-boot-farm-secure/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/Application.groovy b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/Application.groovy deleted file mode 100644 index 9a71801fb..000000000 --- a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/MyController.groovy b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/MyController.groovy deleted file mode 100644 index a1a996071..000000000 --- a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice/MyController.groovy +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice - -import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestMethod - -@RestController -@RequestMapping('/mycontroller') -class MyController { - - @RequestMapping(value = '/getdate', method = RequestMethod.POST) - Map home() { - return [ date: new Date().format('EEE, d MMM yyyy') ] - } -} diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/Application.java b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/Application.java new file mode 100644 index 000000000..c6bc1c355 --- /dev/null +++ b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootwebservice; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/MyController.java b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/MyController.java new file mode 100644 index 000000000..502c36fa0 --- /dev/null +++ b/integrationTests/spring-boot-farm-secure/spring-boot-webservice/src/main/java/org/akhikhl/examples/gretty/springbootwebservice/MyController.java @@ -0,0 +1,19 @@ +package org.akhikhl.examples.gretty.springbootwebservice; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +@RestController +@RequestMapping("/mycontroller") +public class MyController { + @RequestMapping(value = "/getdate", method = RequestMethod.POST) + public Map home() { + return Collections.singletonMap("date", new SimpleDateFormat("EEE, d MMM yyyy").format(new Date())); + } +} \ No newline at end of file diff --git a/integrationTests/spring-boot-farm/spring-boot-app/build.gradle b/integrationTests/spring-boot-farm/spring-boot-app/build.gradle index d4dc0b140..43cd607a6 100644 --- a/integrationTests/spring-boot-farm/spring-boot-app/build.gradle +++ b/integrationTests/spring-boot-farm/spring-boot-app/build.gradle @@ -10,7 +10,7 @@ dependencies { gretty { springBoot = true - if (JavaVersion.current().isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" + if (project.javaVersion.isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" } farm { diff --git a/integrationTests/spring-boot-farm/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy b/integrationTests/spring-boot-farm/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy deleted file mode 100644 index 37817aaa6..000000000 --- a/integrationTests/spring-boot-farm/spring-boot-app/src/main/groovy/org/akhikhl/examples/gretty/springbootapp/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootapp - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-farm/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java b/integrationTests/spring-boot-farm/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java new file mode 100644 index 000000000..6f7e31571 --- /dev/null +++ b/integrationTests/spring-boot-farm/spring-boot-app/src/main/java/org/akhikhl/examples/gretty/springbootapp/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootapp; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(java.lang.String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/Application.groovy b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/Application.groovy deleted file mode 100644 index 99d806e81..000000000 --- a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice1 - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/MyController.groovy b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/MyController.groovy deleted file mode 100644 index 7159e3940..000000000 --- a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice1/MyController.groovy +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice1 - -import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestMethod - -@RestController -@RequestMapping('/mycontroller') -class MyController { - - @RequestMapping(value = '/getdate', method = RequestMethod.POST) - Map home() { - return [ date: new Date().format('EEE, d MMM yyyy') ] - } -} diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/Application.java b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/Application.java new file mode 100644 index 000000000..f71df4632 --- /dev/null +++ b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootwebservice1; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/MyController.java b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/MyController.java new file mode 100644 index 000000000..b9a0c9291 --- /dev/null +++ b/integrationTests/spring-boot-farm/spring-boot-webservice1/src/main/java/org/akhikhl/examples/gretty/springbootwebservice1/MyController.java @@ -0,0 +1,19 @@ +package org.akhikhl.examples.gretty.springbootwebservice1; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +@RestController +@RequestMapping("/mycontroller") +public class MyController { + @RequestMapping(value = "/getdate", method = RequestMethod.POST) + public Map home() { + return Collections.singletonMap("date", new SimpleDateFormat("EEE, d MMM yyyy").format(new Date())); + } +} \ No newline at end of file diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/Application.groovy b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/Application.groovy deleted file mode 100644 index 79669d98a..000000000 --- a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice2 - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/MyController.groovy b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/MyController.groovy deleted file mode 100644 index c9e4c82b1..000000000 --- a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/groovy/org/akhikhl/examples/gretty/springbootwebservice2/MyController.groovy +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootwebservice2 - -import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestMethod - -@RestController -@RequestMapping('/mycontroller') -class MyController { - - @RequestMapping(value = '/getdate', method = RequestMethod.POST) - Map home() { - return [ date: new Date().format('EEE, d MMM yyyy') ] - } -} diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/Application.java b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/Application.java new file mode 100644 index 000000000..047cc3c8c --- /dev/null +++ b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootwebservice2; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/MyController.java b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/MyController.java new file mode 100644 index 000000000..521fbb522 --- /dev/null +++ b/integrationTests/spring-boot-farm/spring-boot-webservice2/src/main/java/org/akhikhl/examples/gretty/springbootwebservice2/MyController.java @@ -0,0 +1,19 @@ +package org.akhikhl.examples.gretty.springbootwebservice2; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +@RestController +@RequestMapping("/mycontroller") +public class MyController { + @RequestMapping(value = "/getdate", method = RequestMethod.POST) + public Map home() { + return Collections.singletonMap("date", new SimpleDateFormat("EEE, d MMM yyyy").format(new Date())); + } +} \ No newline at end of file diff --git a/integrationTests/spring-boot-simple/build.gradle b/integrationTests/spring-boot-simple/build.gradle index 46019a466..deaef4e9c 100644 --- a/integrationTests/spring-boot-simple/build.gradle +++ b/integrationTests/spring-boot-simple/build.gradle @@ -11,7 +11,7 @@ dependencies { gretty { springBoot = true - if (JavaVersion.current().isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" + if (project.javaVersion.isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" } defineIntegrationTest() diff --git a/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/Application.groovy b/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/Application.groovy deleted file mode 100644 index b9917b067..000000000 --- a/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/Application.groovy +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootsimple - -import java.util.Arrays - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.context.annotation.ComponentScan -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableAutoConfiguration -@ComponentScan -class Application { - - static void main(String[] args) { - SpringApplication.run(Application.class, args) - } -} - diff --git a/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/MyController.groovy b/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/MyController.groovy deleted file mode 100644 index 63651dbab..000000000 --- a/integrationTests/spring-boot-simple/src/main/groovy/org/akhikhl/examples/gretty/springbootsimple/MyController.groovy +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Gretty - * - * Copyright (C) 2013-2015 Andrey Hihlovskiy and contributors. - * - * See the file "LICENSE" for copying and usage permission. - * See the file "CONTRIBUTORS" for complete list of contributors. - */ -package org.akhikhl.examples.gretty.springbootsimple - -import org.springframework.web.bind.annotation.RestController -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RequestMethod - -@RestController -@RequestMapping('/mycontroller') -class MyController { - - @RequestMapping(value = '/getdate', method = RequestMethod.POST) - Map home() { - return [ date: new Date().format('EEE, d MMM yyyy') ] - } -} - diff --git a/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/Application.java b/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/Application.java new file mode 100644 index 000000000..6141caee9 --- /dev/null +++ b/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/Application.java @@ -0,0 +1,16 @@ +package org.akhikhl.examples.gretty.springbootsimple; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + public static void main(java.lang.String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/MyController.java b/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/MyController.java new file mode 100644 index 000000000..70cee6163 --- /dev/null +++ b/integrationTests/spring-boot-simple/src/main/java/org/akhikhl/examples/gretty/springbootsimple/MyController.java @@ -0,0 +1,19 @@ +package org.akhikhl.examples.gretty.springbootsimple; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +@RestController +@RequestMapping("/mycontroller") +public class MyController { + @RequestMapping(value = "/getdate", method = RequestMethod.POST) + public Map home() { + return Collections.singletonMap("date", new SimpleDateFormat("EEE, d MMM yyyy").format(new Date())); + } +} diff --git a/integrationTests/springBootWebSocket/build.gradle b/integrationTests/springBootWebSocket/build.gradle index fbb984e33..e03024381 100644 --- a/integrationTests/springBootWebSocket/build.gradle +++ b/integrationTests/springBootWebSocket/build.gradle @@ -10,7 +10,7 @@ dependencies { gretty { springBoot = true servletContainer = 'tomcat9' - if (JavaVersion.current().isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" + if (project.javaVersion.isJava9Compatible()) jvmArgs "--add-opens", "java.base/java.lang=ALL-UNNAMED" } defineIntegrationTest() diff --git a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/JavaExecParams.groovy b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/JavaExecParams.groovy index 7a3c7b69f..6ca0ddefa 100644 --- a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/JavaExecParams.groovy +++ b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/JavaExecParams.groovy @@ -19,6 +19,8 @@ class JavaExecParams { String main + String jvmExecutable + List jvmArgs = [] List args = [] @@ -29,6 +31,10 @@ class JavaExecParams { Map systemProperties = [:] + void jvmExecutable(String jvmExecutable) { + this.jvmExecutable = jvmExecutable + } + void arg(String a) { args.add(a) } diff --git a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/LauncherBase.groovy b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/LauncherBase.groovy index f64c6d13a..4e86c3020 100644 --- a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/LauncherBase.groovy +++ b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/LauncherBase.groovy @@ -188,6 +188,7 @@ abstract class LauncherBase implements Launcher { params.debug = config.getDebug() params.debugSuspend = config.getDebugSuspend() params.debugPort = config.getDebugPort() + params.jvmExecutable = sconfig.jvmExecutable params.jvmArgs = sconfig.jvmArgs params.systemProperties = sconfig.systemProperties if(!sconfig.secureRandom) { diff --git a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/ServerConfig.groovy b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/ServerConfig.groovy index 68cf87829..9d6d8af3d 100644 --- a/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/ServerConfig.groovy +++ b/libs/gretty-core/src/main/groovy/org/akhikhl/gretty/ServerConfig.groovy @@ -21,7 +21,7 @@ import groovy.transform.TypeCheckingMode class ServerConfig { static final int RANDOM_FREE_PORT = -1 - + String jvmExecutable List jvmArgs Map systemProperties String servletContainer @@ -161,4 +161,8 @@ class ServerConfig { systemProperties << m } } + + void jvmExecutable(String jvmExecutable) { + this.jvmExecutable = jvmExecutable + } } diff --git a/libs/gretty-starter/src/main/groovy/org/akhikhl/gretty/StarterLauncher.groovy b/libs/gretty-starter/src/main/groovy/org/akhikhl/gretty/StarterLauncher.groovy index b3567eb36..a9bee3cfb 100644 --- a/libs/gretty-starter/src/main/groovy/org/akhikhl/gretty/StarterLauncher.groovy +++ b/libs/gretty-starter/src/main/groovy/org/akhikhl/gretty/StarterLauncher.groovy @@ -57,13 +57,17 @@ class StarterLauncher extends LauncherBase { @Override protected void javaExec(JavaExecParams params) { - String javaExe = PlatformUtils.isWindows() ? 'java.exe' : 'java' - String javaPath = new File(System.getProperty("java.home"), "bin/$javaExe").absolutePath + String jvmExecutable = Optional.ofNullable(params.jvmExecutable).orElseGet({ + String javaExe = PlatformUtils.isWindows() ? 'java.exe' : 'java' + String javaPath = new File(System.getProperty("java.home"), "bin/$javaExe").absolutePath + return javaPath + }) + def classPath = [ new File(basedir, 'runner/*') ] classPath = classPath.collect { it.absolutePath }.join(System.getProperty('path.separator')) // Note that JavaExecParams debugging properties are intentionally ignored. // It is supposed that webapp debugging is performed via DefaultLauncher. - def procParams = [ javaPath ] + params.jvmArgs + ['-DgrettyProduct=true'] + params.systemProperties.collect { k, v -> "-D$k=$v" } + [ '-cp', classPath, params.main ] + params.args + def procParams = [ jvmExecutable ] + params.jvmArgs + ['-DgrettyProduct=true'] + params.systemProperties.collect { k, v -> "-D$k=$v" } + [ '-cp', classPath, params.main ] + params.args log.debug 'Launching runner process: {}', procParams.join(' ') Process proc = procParams.execute() proc.waitForProcessOutput(System.out, System.err) diff --git a/libs/gretty/src/main/groovy/org/akhikhl/gretty/DefaultLauncher.groovy b/libs/gretty/src/main/groovy/org/akhikhl/gretty/DefaultLauncher.groovy index 6497e1764..6b0bc588f 100644 --- a/libs/gretty/src/main/groovy/org/akhikhl/gretty/DefaultLauncher.groovy +++ b/libs/gretty/src/main/groovy/org/akhikhl/gretty/DefaultLauncher.groovy @@ -112,6 +112,11 @@ class DefaultLauncher extends LauncherBase { } log.info 'DEBUG MODE, port={}, suspend={}', params.debugPort, params.debugSuspend } + + if (params.jvmExecutable) { + spec.executable params.jvmExecutable + } + spec.jvmArgs jvmArgs spec.systemProperties params.systemProperties spec.mainClass.set(params.main) diff --git a/libs/gretty/src/main/groovy/org/akhikhl/gretty/StartBaseTask.groovy b/libs/gretty/src/main/groovy/org/akhikhl/gretty/StartBaseTask.groovy index d4d67d4b0..3bb3fb2b7 100644 --- a/libs/gretty/src/main/groovy/org/akhikhl/gretty/StartBaseTask.groovy +++ b/libs/gretty/src/main/groovy/org/akhikhl/gretty/StartBaseTask.groovy @@ -14,8 +14,12 @@ import org.akhikhl.gretty.scanner.JDKScannerManager import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.plugins.ExtensionAware +import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction +import org.gradle.jvm.toolchain.JavaLauncher +import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.jvm.toolchain.JavaToolchainSpec import org.gradle.process.JavaForkOptions import org.gradle.testing.jacoco.plugins.JacocoTaskExtension /** @@ -115,6 +119,10 @@ abstract class StartBaseTask extends DefaultTask { sconfig.systemProperty 'springloaded', 'exclusions=org.akhikhl.gretty..*' } + getJavaToolchainJvmExecutable().ifPresent({ jvmExecutable -> + sconfig.jvmExecutable(jvmExecutable) + }) + for(Closure c in prepareServerConfigClosures) { c = c.rehydrate(sconfig, c.owner, c.thisObject) c.resolveStrategy = Closure.DELEGATE_FIRST @@ -165,6 +173,27 @@ abstract class StartBaseTask extends DefaultTask { } } + private Optional getJavaToolchainLauncher() { + Optional toolchainService = Optional.ofNullable(project.extensions.findByName('javaToolchains')) + .filter({ it instanceof JavaToolchainService }) + + Optional launcher = Optional.ofNullable(project.extensions.findByType(JavaPluginExtension)) + .map({ it.getToolchain() }) + .flatMap({ JavaToolchainSpec spec -> + toolchainService + .map({ it.launcherFor(spec) }) + .map({ it.getOrNull() }) + }) + + return launcher + } + + private Optional getJavaToolchainJvmExecutable() { + return getJavaToolchainLauncher() + .map({ it.executablePath?.asFile?.path }) + } + + @Internal protected final LauncherConfig getLauncherConfig() { diff --git a/libs/gretty/src/main/groovy/org/akhikhl/gretty/TaskWithServerConfig.groovy b/libs/gretty/src/main/groovy/org/akhikhl/gretty/TaskWithServerConfig.groovy index 4981d79fe..a92a54dd3 100644 --- a/libs/gretty/src/main/groovy/org/akhikhl/gretty/TaskWithServerConfig.groovy +++ b/libs/gretty/src/main/groovy/org/akhikhl/gretty/TaskWithServerConfig.groovy @@ -10,6 +10,10 @@ import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity interface TaskWithServerConfig { + @Optional + @Input + String getJvmExecutable() + @Optional @Input List getJvmArgs()