From 0dcc92eb237bea33fae970e7f4bb6729e61aea06 Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Wed, 20 Sep 2023 18:15:38 -0500 Subject: [PATCH 1/3] Add support for SpringBoot 3 --- .github/workflows/gradle.yml | 4 +- docs/spring-boot-support.md | 8 +- .../tools/gradle/LibertyTasks.groovy | 6 +- .../gradle/tasks/AbstractLibertyTask.groovy | 38 +++++- .../gradle/tasks/AbstractServerTask.groovy | 9 +- .../tools/gradle/tasks/DeployTask.groovy | 24 ++-- .../gradle/TestSpringBootApplication30.groovy | 122 ++++++++++++++++++ .../sample.springboot3/settings.gradle | 1 + .../java/com/ibm/test/springboot/App.java | 18 +++ .../src/main/liberty/config/server30.xml | 14 ++ .../src/main/resources/application.properties | 0 .../test_spring_boot_apps_30.gradle | 39 ++++++ ...test_spring_boot_classifier_apps_30.gradle | 43 ++++++ .../test_spring_boot_dropins_30.gradle | 48 +++++++ .../test_spring_boot_war_apps_30.gradle | 39 ++++++ ..._spring_boot_war_classifier_apps_30.gradle | 43 ++++++ 16 files changed, 431 insertions(+), 25 deletions(-) create mode 100644 src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy create mode 100644 src/test/resources/sample.springboot3/settings.gradle create mode 100644 src/test/resources/sample.springboot3/src/main/java/com/ibm/test/springboot/App.java create mode 100644 src/test/resources/sample.springboot3/src/main/liberty/config/server30.xml create mode 100644 src/test/resources/sample.springboot3/src/main/resources/application.properties create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 86a805d9c..8b07fedd2 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -70,7 +70,7 @@ jobs: # Run tests - name: Run tests with Gradle on Ubuntu run: - ./gradlew clean install check -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info + ./gradlew clean install check -P"test.exclude"="**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info # Copy build reports and upload artifact if build failed - name: Copy build/report/tests/test for upload if: ${{ failure() }} @@ -149,7 +149,7 @@ jobs: - name: Run tests with Gradle on Windows working-directory: C:/ci.gradle # LibertyTest is excluded because test0_run hangs - run: ./gradlew clean install check -P"test.exclude"="**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info --no-daemon + run: ./gradlew clean install check -P"test.exclude"="**/Polling*,**/LibertyTest*,**/GenerateFeaturesTest*,**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info --no-daemon timeout-minutes: 75 # Copy build reports and upload artifact if build failed - name: Copy build/report/tests/test for upload diff --git a/docs/spring-boot-support.md b/docs/spring-boot-support.md index af2000ec5..69c939372 100644 --- a/docs/spring-boot-support.md +++ b/docs/spring-boot-support.md @@ -18,18 +18,20 @@ The `server.xml` file provided by the `configDirectory` or `serverXmlFile` param | Feature | Description | | ------- | ----------- | | springBoot-1.5 | Required to support applications with Spring Boot version 1.5.x. | -| springBoot-2.0 | Required to support applications with Spring Boot version 2.0.x and above. | +| springBoot-2.0 | Required to support applications with Spring Boot version 2.x. | +| springBoot-3.0 | Required to support applications with Spring Boot version 3.x. | The Liberty features that support the Spring Boot starters can be found [here](https://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.wlp.nd.multiplatform.doc/ae/rwlp_springboot.html). They should be enabled in the `server.xml` along with the appropriate Spring Boot feature. ### Gradle Compatibility -There is a known build conflict that Spring Boot Gradle plugin 1.5.x is incompatible with Gradle 5.x. As the Spring Boot 1.5.x plugin will not be updated to support Gradle 5.x, consider upgrading the Spring Boot plugin or downgrading Gradle. +The Spring Boot Gradle plugin 3.x requires Java 17 and a minimum of Gradle 7.5. There is a known build conflict that Spring Boot Gradle plugin 1.5.x is incompatible with Gradle 5.x. As the Spring Boot 1.5.x plugin will not be updated to support Gradle 5.x, consider upgrading the Spring Boot plugin or downgrading Gradle. | Spring Boot version | Advised Gradle version | | ------------------- | -------------- | -| 2.0.x | 4.x+ | +| 3.x | 7.5+ or 8.x | +| 2.x | 4.x+ | | 1.5.x | 2.9 or 3.x (Although we observed compatibility up to 4.10, proceed at your own risk)| Refer to the [current release Spring docs](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#introduction) to be advised on Gradle compatibility for the latest Spring Boot Gradle plugin. \ No newline at end of file diff --git a/src/main/groovy/io/openliberty/tools/gradle/LibertyTasks.groovy b/src/main/groovy/io/openliberty/tools/gradle/LibertyTasks.groovy index 10d896d60..888122d4a 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/LibertyTasks.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/LibertyTasks.groovy @@ -17,6 +17,7 @@ package io.openliberty.tools.gradle import io.openliberty.tools.gradle.extensions.ServerExtension import io.openliberty.tools.gradle.tasks.AbstractServerTask +import io.openliberty.tools.gradle.tasks.AbstractLibertyTask import org.gradle.api.Project import org.gradle.api.tasks.TaskDependency @@ -92,8 +93,9 @@ public class LibertyTasks { } project.deploy { - if (AbstractServerTask.findSpringBootVersion(project) != null) { - if (springBootVersion?.startsWith('2')) { + String springBootVersion = AbstractServerTask.findSpringBootVersion(project) + if (springBootVersion != null) { + if (AbstractLibertyTask.isSpringBoot2plus(springBootVersion)) { dependsOn 'bootJar' } else { //version 1.5.x dependsOn 'bootRepackage' diff --git a/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractLibertyTask.groovy b/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractLibertyTask.groovy index ec377ae0b..d43ec2a31 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractLibertyTask.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractLibertyTask.groovy @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corporation 2017, 2021. + * (C) Copyright IBM Corporation 2017, 2023. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,19 +78,51 @@ abstract class AbstractLibertyTask extends DefaultTask { return version } + protected static boolean isSpringBoot1(String springBootVersion) { + if (springBootVersion == null) { + return false + } + return springBootVersion.startsWith('1.') + } + + protected static boolean isSpringBoot2plus(String springBootVersion) { + if (springBootVersion == null) { + return false + } + if (springBootVersion.contains('.')) { + String majorVersion = springBootVersion.substring(0,springBootVersion.indexOf('.')) + try { + int majorVersionNumber = Integer.parseInt(majorVersion) + return majorVersionNumber > 1 + } catch (NumberFormatException e) { + } + } + return false + } + + protected static String getLibertySpringBootFeature(String springBootVersion) { + if (isSpringBoot1(springBootVersion)) { + return "springBoot-1.5" + } else if (isSpringBoot2plus(springBootVersion)) { + String majorVersion = springBootVersion.substring(0,springBootVersion.indexOf('.')) + return "springBoot-"+majorVersion+".0" + } + return null + } + protected static Task findSpringBootTask(Project project, String springBootVersion) { if (springBootVersion == null) { return null } Task task //Do not change the order of war and java - if (springBootVersion.startsWith('2.')) { + if (isSpringBoot2plus(springBootVersion)) { if (project.plugins.hasPlugin('war')) { task = project.bootWar } else if (project.plugins.hasPlugin('java')) { task = project.bootJar } - } else if (springBootVersion.startsWith('1.')) { + } else if (isSpringBoot1(springBootVersion)) { if (project.plugins.hasPlugin('war')) { task = project.war } else if (project.plugins.hasPlugin('java')) { diff --git a/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractServerTask.groovy b/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractServerTask.groovy index 5fbedf11d..4dfc079b0 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractServerTask.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/tasks/AbstractServerTask.groovy @@ -138,10 +138,9 @@ abstract class AbstractServerTask extends AbstractLibertyTask { } protected determineSpringBootBuildTask() { - if (springBootVersion ?. startsWith('2') ) { + if (isSpringBoot2plus(springBootVersion)) { return project.bootJar - } - else if ( springBootVersion ?. startsWith('1') ) { + } else if (isSpringBoot1(springBootVersion)) { return project.bootRepackage } } @@ -564,7 +563,7 @@ abstract class AbstractServerTask extends AbstractLibertyTask { } protected String getArchiveName(Task task){ - if (springBootVersion?.startsWith('1')) { + if (isSpringBoot1(springBootVersion)) { task = project.jar } if (server.stripVersion){ @@ -648,7 +647,7 @@ abstract class AbstractServerTask extends AbstractLibertyTask { appList.each { Object appObj -> Node application = new Node(null, 'application') if (appObj instanceof Task) { - if (springBootVersion?.startsWith('1')) { + if (isSpringBoot1(springBootVersion)) { appObj = project.jar } application.appendNode('appsDirectory', appDir) diff --git a/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy b/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy index a1a2f2039..9e4e386de 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy @@ -165,10 +165,10 @@ class DeployTask extends AbstractServerTask { private String getArchiveOutputPath() { String archiveOutputPath; - if (springBootVersion.startsWith('2.')) { + if (isSpringBoot2plus(springBootVersion)) { archiveOutputPath = springBootTask.archivePath.getAbsolutePath() } - else if(springBootVersion.startsWith('1.')) { + else if(isSpringBoot1(springBootVersion)) { archiveOutputPath = springBootTask.archivePath.getAbsolutePath() if (project.bootRepackage.classifier != null && !project.bootRepackage.classifier.isEmpty()) { archiveOutputPath = archiveOutputPath.substring(0, archiveOutputPath.lastIndexOf(".")) + "-" + project.bootRepackage.classifier + "." + springBootTask.getArchiveExtension().get() @@ -223,14 +223,18 @@ class DeployTask extends AbstractServerTask { String fileSuffix = isWindows ? ".bat" : "" File installUtil = new File(getInstallDir(project), "bin/installUtility"+fileSuffix) - def installCommand = installUtil.toString() + " install springBoot-1.5 springBoot-2.0 --acceptLicense" - def sbuff = new StringBuffer() - def proc = installCommand.execute() - proc.consumeProcessOutput(sbuff, sbuff) - proc.waitFor() - logger.info(sbuff.toString()) - if (proc.exitValue()!=0) { - throw new GradleException("Error installing required spring boot support features.") + // only install springBoot feature that matches required version + String sbFeature = getLibertySpringBootFeature(springBootVersion) + if (sbFeature != null) { + def installCommand = installUtil.toString() + " install " + sbFeature + " --acceptLicense" + def sbuff = new StringBuffer() + def proc = installCommand.execute() + proc.consumeProcessOutput(sbuff, sbuff) + proc.waitFor() + logger.info(sbuff.toString()) + if (proc.exitValue()!=0) { + throw new GradleException("Error installing required spring boot support feature: "+sbFeature) + } } } } diff --git a/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy b/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy new file mode 100644 index 000000000..3572f9ace --- /dev/null +++ b/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy @@ -0,0 +1,122 @@ +/* + * (C) Copyright IBM Corporation 2023. + * + * 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 io.openliberty.tools.gradle + +import groovy.xml.QName +import org.junit.* +import org.junit.rules.TestName + +public class TestSpringBootApplication30 extends AbstractIntegrationTest{ + static File resourceDir = new File("build/resources/test/sample.springboot3") + static String buildFilename = "springboot_3_archive.gradle" + + File buildDir; + + @Rule + public TestName testName = new TestName(); + + @Before + public void setup() { + buildDir = new File(integTestDir, "/" + testName.getMethodName()) + createDir(buildDir) + createTestProject(buildDir, resourceDir, testName.getMethodName() + '.gradle') + } + + @After + public void tearDown() throws Exception { + runTasks(buildDir,'libertyStop') + } + + + @Test + public void test_spring_boot_apps_30() { + try { + runTasks(buildDir, 'deploy', 'libertyStart') + + String webPage = new URL("http://localhost:9080").getText() + Assert.assertEquals("Did not get expected http response.","Hello!", webPage) + Assert.assertTrue('defaultServer/dropins has app deployed', + new File(buildDir, 'build/wlp/usr/servers/defaultServer/dropins').list().size() == 0) + Assert.assertTrue('no app in apps folder', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps/thin-${testName.getMethodName()}-1.0-SNAPSHOT.jar").exists() ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } + + @Test + public void test_spring_boot_classifier_apps_30() { + try { + runTasks(buildDir, 'deploy', 'libertyStart') + + String webPage = new URL("http://localhost:9080").getText() + Assert.assertEquals("Did not get expected http response.","Hello!", webPage) + Assert.assertTrue('defaultServer/dropins has app deployed', + new File(buildDir, 'build/wlp/usr/servers/defaultServer/dropins').list().size() == 0) + Assert.assertTrue('no app in apps folder', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps/thin-${testName.getMethodName()}-1.0-SNAPSHOT-test.jar").exists() ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } + + @Test + public void test_spring_boot_war_apps_30() { + try { + runTasks(buildDir, 'deploy', 'libertyStart') + + String webPage = new URL("http://localhost:9080").getText() + Assert.assertEquals("Did not get expected http response.","Hello!", webPage) + Assert.assertTrue('defaultServer/dropins has app deployed', + new File(buildDir, 'build/wlp/usr/servers/defaultServer/dropins').list().size() == 0) + Assert.assertTrue('no app in apps folder', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps/thin-${testName.getMethodName()}-1.0-SNAPSHOT.war").exists() ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } + + @Test + public void test_spring_boot_war_classifier_apps_30() { + try { + runTasks(buildDir, 'deploy', 'libertyStart') + + String webPage = new URL("http://localhost:9080").getText() + Assert.assertEquals("Did not get expected http response.","Hello!", webPage) + Assert.assertTrue('defaultServer/dropins has app deployed', + new File(buildDir, 'build/wlp/usr/servers/defaultServer/dropins').list().size() == 0) + Assert.assertTrue('no app in apps folder', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps/thin-${testName.getMethodName()}-1.0-SNAPSHOT-test.war").exists() ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } + + @Test + public void test_spring_boot_dropins_30() { + try { + runTasks(buildDir, 'deploy', 'libertyStart') + String webPage = new URL("http://localhost:9080").getText() + Assert.assertEquals("Did not get expected http response.","Hello!", webPage) + Assert.assertTrue('defaultServer/dropins/spring has no app', + new File(buildDir, "build/wlp/usr/servers/defaultServer/dropins/spring/thin-${testName.getMethodName()}-1.0-SNAPSHOT.jar").exists()) + Assert.assertTrue('apps folder should be empty', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps").list().size() == 0 ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } +} diff --git a/src/test/resources/sample.springboot3/settings.gradle b/src/test/resources/sample.springboot3/settings.gradle new file mode 100644 index 000000000..c2d3edc19 --- /dev/null +++ b/src/test/resources/sample.springboot3/settings.gradle @@ -0,0 +1 @@ +//Empty \ No newline at end of file diff --git a/src/test/resources/sample.springboot3/src/main/java/com/ibm/test/springboot/App.java b/src/test/resources/sample.springboot3/src/main/java/com/ibm/test/springboot/App.java new file mode 100644 index 000000000..e7688517a --- /dev/null +++ b/src/test/resources/sample.springboot3/src/main/java/com/ibm/test/springboot/App.java @@ -0,0 +1,18 @@ +package com.ibm.test.springboot; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +@RestController +public class App { + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } + @RequestMapping("/") + public String index() { + return "Hello!"; + } +} diff --git a/src/test/resources/sample.springboot3/src/main/liberty/config/server30.xml b/src/test/resources/sample.springboot3/src/main/liberty/config/server30.xml new file mode 100644 index 000000000..a9f10f6b5 --- /dev/null +++ b/src/test/resources/sample.springboot3/src/main/liberty/config/server30.xml @@ -0,0 +1,14 @@ + + + + springBoot-3.0 + servlet-6.0 + + + + + + + diff --git a/src/test/resources/sample.springboot3/src/main/resources/application.properties b/src/test/resources/sample.springboot3/src/main/resources/application.properties new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle new file mode 100644 index 000000000..3cb20f397 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle @@ -0,0 +1,39 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'java' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + +liberty { + server { + serverXmlFile = file("src/main/liberty/config/server30.xml") + } +} \ No newline at end of file diff --git a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle new file mode 100644 index 000000000..db31d7330 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle @@ -0,0 +1,43 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'java' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + +bootJar { + archiveClassifier = 'test' +} + +liberty { + server { + serverXmlFile = file("src/main/liberty/config/server30.xml") + } +} diff --git a/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle new file mode 100644 index 000000000..4cd2e1cc8 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle @@ -0,0 +1,48 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'java' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + + +liberty { + server { + serverXmlFile = file("src/main/liberty/config/server30.xml") + install.useOpenLiberty = false + looseApplication = false + deploy { + dropins = [bootJar] + } + features { + acceptLicense = true + } + } +} diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle new file mode 100644 index 000000000..62ddb41a2 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle @@ -0,0 +1,39 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'war' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + +liberty { + server { + serverXmlFile = file("src/main/liberty/config/server30.xml") + } +} \ No newline at end of file diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle new file mode 100644 index 000000000..0f71363c0 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle @@ -0,0 +1,43 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'war' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion +} + +bootWar { + archiveClassifier = 'test' +} + +liberty { + server { + serverXmlFile = file("src/main/liberty/config/server30.xml") + } +} \ No newline at end of file From c92a60276fecb5f6359f619aa353e4c15a1bfce1 Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Thu, 21 Sep 2023 11:56:31 -0500 Subject: [PATCH 2/3] Use openliberty-runtime in test case to get past error --- .../sample.springboot3/test_spring_boot_apps_30.gradle | 2 +- .../test_spring_boot_classifier_apps_30.gradle | 2 +- .../test_spring_boot_dropins_30.gradle | 10 +++++----- .../test_spring_boot_war_apps_30.gradle | 2 +- .../test_spring_boot_war_classifier_apps_30.gradle | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle index 3cb20f397..2a4aec6a6 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' } liberty { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle index db31d7330..099f77809 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' } bootJar { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle index 4cd2e1cc8..ecd7b9389 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle @@ -29,20 +29,20 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' } liberty { server { serverXmlFile = file("src/main/liberty/config/server30.xml") - install.useOpenLiberty = false + //install.useOpenLiberty = false looseApplication = false deploy { dropins = [bootJar] } - features { - acceptLicense = true - } + // features { + // acceptLicense = true + // } } } diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle index 62ddb41a2..8d2d0ffa0 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' } liberty { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle index 0f71363c0..6b043b2ef 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: runtimeGroup, name: runtimeArtifactId, version: runtimeVersion + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' } bootWar { From 1ee28afb6ccb7b6833057d4cd60983c7abfbc825 Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Wed, 18 Oct 2023 16:46:03 -0500 Subject: [PATCH 3/3] Update tests and code to install feature if no springBootUtility found --- .github/workflows/gradle.yml | 10 +++++ .../tools/gradle/tasks/DeployTask.groovy | 16 ++++--- .../gradle/TestSpringBootApplication30.groovy | 14 ++++++ .../main/liberty/alternateConfig/server30.xml | 13 ++++++ .../test_spring_boot_apps_30.gradle | 2 +- ...test_spring_boot_classifier_apps_30.gradle | 2 +- ..._boot_classifier_apps_30_no_feature.gradle | 43 +++++++++++++++++++ .../test_spring_boot_dropins_30.gradle | 2 +- .../test_spring_boot_war_apps_30.gradle | 2 +- ..._spring_boot_war_classifier_apps_30.gradle | 2 +- 10 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/test/resources/sample.springboot3/src/main/liberty/alternateConfig/server30.xml create mode 100644 src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30_no_feature.gradle diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index e92622bc8..ee7c7b374 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -67,6 +67,11 @@ jobs: run: | mvn -V clean install -f ci.ant --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false mvn -V clean install -f ci.common --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false + # Run tests that require Java 17 or later + - name: Run tests that require Java 17 or later + if: ${{ matrix.java == '17' }} + run: + ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info # Run tests - name: Run tests with Gradle on Ubuntu run: @@ -145,6 +150,11 @@ jobs: - name: Install ci.common working-directory: C:/ci.common run: mvn -V clean install --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false + # Run tests that require Java 17 or later + - name: Run tests that require Java 17 or later + if: ${{ matrix.java == '17' }} + run: + ./gradlew clean install check -P"test.include"="**/TestSpringBootApplication30*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" --stacktrace --info --no-daemon # Run tests - name: Run tests with Gradle on Windows working-directory: C:/ci.gradle diff --git a/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy b/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy index 9e4e386de..e79b8b3b0 100644 --- a/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy +++ b/src/main/groovy/io/openliberty/tools/gradle/tasks/DeployTask.groovy @@ -214,25 +214,29 @@ class DeployTask extends AbstractServerTask { return targetThinAppPath; } - private isSpringBootUtilAvailable() { - new FileNameFinder().getFileNames(new File(getInstallDir(project), "bin").getAbsolutePath(), "springBootUtility*") + private boolean isUtilityAvailable(File installDirectory, String utilityName) { + String utilFileName = isWindows ? utilityName+".bat" : utilityName; + File installUtil = new File(installDirectory, "bin/"+utilFileName); + return installUtil.exists(); } private installSpringBootFeatureIfNeeded() { - if (isClosedLiberty() && !isSpringBootUtilAvailable()) { + File installDir = getInstallDir(project) + if (!isUtilityAvailable(installDir, "springBootUtility") && isUtilityAvailable(installDir, "featureUtility")) { String fileSuffix = isWindows ? ".bat" : "" - File installUtil = new File(getInstallDir(project), "bin/installUtility"+fileSuffix) + File installUtil = new File(installDir, "bin/featureUtility"+fileSuffix) // only install springBoot feature that matches required version String sbFeature = getLibertySpringBootFeature(springBootVersion) if (sbFeature != null) { - def installCommand = installUtil.toString() + " install " + sbFeature + " --acceptLicense" + logger.info("Required springBootUtility not found in Liberty installation. Installing feature "+sbFeature+" to enable it."); + def installCommand = installUtil.toString() + " installFeature " + sbFeature + " --acceptLicense" def sbuff = new StringBuffer() def proc = installCommand.execute() proc.consumeProcessOutput(sbuff, sbuff) proc.waitFor() - logger.info(sbuff.toString()) if (proc.exitValue()!=0) { + logger.error(sbuff.toString()) throw new GradleException("Error installing required spring boot support feature: "+sbFeature) } } diff --git a/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy b/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy index 3572f9ace..4006d68df 100644 --- a/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy +++ b/src/test/groovy/io/openliberty/tools/gradle/TestSpringBootApplication30.groovy @@ -73,6 +73,20 @@ public class TestSpringBootApplication30 extends AbstractIntegrationTest{ } } + @Test + public void test_spring_boot_classifier_apps_30_no_feature() { + try { + runTasks(buildDir, 'deploy') + + Assert.assertTrue('defaultServer/dropins has app deployed', + new File(buildDir, 'build/wlp/usr/servers/defaultServer/dropins').list().size() == 0) + Assert.assertTrue('no app in apps folder', + new File(buildDir, "build/wlp/usr/servers/defaultServer/apps/thin-${testName.getMethodName()}-1.0-SNAPSHOT-test.jar").exists() ) + } catch (Exception e) { + throw new AssertionError ("Fail on task deploy.", e) + } + } + @Test public void test_spring_boot_war_apps_30() { try { diff --git a/src/test/resources/sample.springboot3/src/main/liberty/alternateConfig/server30.xml b/src/test/resources/sample.springboot3/src/main/liberty/alternateConfig/server30.xml new file mode 100644 index 000000000..9c1fd6140 --- /dev/null +++ b/src/test/resources/sample.springboot3/src/main/liberty/alternateConfig/server30.xml @@ -0,0 +1,13 @@ + + + + servlet-6.0 + + + + + + + diff --git a/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle index 2a4aec6a6..c2c1b537f 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' + libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.10' } liberty { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle index 099f77809..569db154b 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' + libertyRuntime group: 'com.ibm.websphere.appserver.runtime', name: 'wlp-jakartaee10', version: '23.0.0.10' } bootJar { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30_no_feature.gradle b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30_no_feature.gradle new file mode 100644 index 000000000..40801aba5 --- /dev/null +++ b/src/test/resources/sample.springboot3/test_spring_boot_classifier_apps_30_no_feature.gradle @@ -0,0 +1,43 @@ +buildscript { + ext { + springBootVersion = '3.1.3' + } + repositories { + mavenLocal() + mavenCentral() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" + classpath "io.openliberty.tools:liberty-gradle-plugin:$lgpVersion" + } +} + +apply plugin: 'java' +apply plugin: 'org.springframework.boot' +apply plugin: 'liberty' + +group = 'liberty.gradle' +version = '1.0-SNAPSHOT' +sourceCompatibility = 17 + +repositories { + mavenCentral() +} +dependencies { + implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") + testImplementation('org.springframework.boot:spring-boot-starter-test') + libertyRuntime group: 'com.ibm.websphere.appserver.runtime', name: 'wlp-jakartaee10', version: '23.0.0.10' +} + +bootJar { + archiveClassifier = 'test' +} + +liberty { + server { + serverXmlFile = file("src/main/liberty/alternateConfig/server30.xml") + } +} diff --git a/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle index ecd7b9389..bac019e86 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_dropins_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' + libertyRuntime group: 'com.ibm.websphere.appserver.runtime', name: 'wlp-jakartaee10', version: '23.0.0.10' } diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle index 8d2d0ffa0..2b0150509 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' + libertyRuntime group: 'io.openliberty', name: 'openliberty-kernel', version: '23.0.0.10' } liberty { diff --git a/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle index 6b043b2ef..be3382a2f 100644 --- a/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle +++ b/src/test/resources/sample.springboot3/test_spring_boot_war_classifier_apps_30.gradle @@ -29,7 +29,7 @@ repositories { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}") testImplementation('org.springframework.boot:spring-boot-starter-test') - libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '23.0.0.9' + libertyRuntime group: 'io.openliberty', name: 'openliberty-kernel', version: '23.0.0.10' } bootWar {