From b77d0e667528cfd259ee22d547b9342294ecfbc5 Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Wed, 20 Sep 2023 16:07:27 -0500 Subject: [PATCH 1/4] Add support for SpringBoot 3 --- docs/spring-boot-support.md | 7 +- liberty-maven-plugin/pom.xml | 4 + .../src/it/springboot-3-tests/pom.xml | 30 ++++ .../pom.xml | 158 ++++++++++++++++++ .../main/java/application/SpringBootApp.java | 35 ++++ .../application/InstallSpringBoot30AppIT.java | 37 ++++ .../SpringBoot30RestEndpointIT.java | 49 ++++++ .../src/test/resources/server.xml | 14 ++ .../pom.xml | 154 +++++++++++++++++ .../main/java/application/SpringBootApp.java | 35 ++++ .../application/InstallSpringBoot30AppIT.java | 37 ++++ .../SpringBoot30RestEndpointIT.java | 49 ++++++ .../src/test/resources/server.xml | 14 ++ .../tools/maven/applications/DeployMojo.java | 4 +- .../maven/applications/DeployMojoSupport.java | 75 +++++++++ .../tools/maven/utils/MavenProjectUtil.java | 5 +- .../tools/maven/utils/SpringBootUtil.java | 38 ++++- 17 files changed, 739 insertions(+), 6 deletions(-) create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/pom.xml create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/main/java/application/SpringBootApp.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/InstallSpringBoot30AppIT.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/SpringBoot30RestEndpointIT.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/resources/server.xml create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/main/java/application/SpringBootApp.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/InstallSpringBoot30AppIT.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/SpringBoot30RestEndpointIT.java create mode 100644 liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/resources/server.xml diff --git a/docs/spring-boot-support.md b/docs/spring-boot-support.md index 9d06ee3ed..a28df2aa2 100644 --- a/docs/spring-boot-support.md +++ b/docs/spring-boot-support.md @@ -15,10 +15,15 @@ The `server.xml` provided by the `serverXmlFile` parameter or located in the `co | 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.0.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. +### Java Support + +The Spring Boot version 3.x requires Java 17 or above. + ### Example To use the `liberty-maven-plugin` to install a Spring Boot application packaged as a Spring Boot Uber JAR, include the appropriate XML in the `plugins` section of your `pom.xml`. diff --git a/liberty-maven-plugin/pom.xml b/liberty-maven-plugin/pom.xml index 442d00c62..c9b24968d 100644 --- a/liberty-maven-plugin/pom.xml +++ b/liberty-maven-plugin/pom.xml @@ -223,6 +223,7 @@ binary-scanner-it/pom.xml + springboot-3-tests/pom.xml @@ -262,6 +263,7 @@ server-param-configdir-not-override-it/pom.xml install-features-it/pom.xml binary-scanner-it/pom.xml + springboot-3-tests/pom.xml @@ -300,6 +302,7 @@ dev-it/pom.xml generate-features-it/pom.xml binary-scanner-it/pom.xml + springboot-3-tests/pom.xml @@ -343,6 +346,7 @@ install-features-it/pom.xml generate-features-it/pom.xml binary-scanner-it/pom.xml + springboot-3-tests/pom.xml diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/pom.xml new file mode 100644 index 000000000..321abfb93 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + + io.openliberty.tools.it + tests + 1.0-SNAPSHOT + + + springboot-3-tests + pom + + + UTF-8 + UTF-8 + 17 + 17 + + + + springboot-3-appsdirectory-apps-it + springboot-3-appsdirectory-dropins-it + + + \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml new file mode 100644 index 000000000..b0fe0accc --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml @@ -0,0 +1,158 @@ + + + 4.0.0 + + springboot-3-appsdirectory-apps-it + 1.0.0.Final + jar + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + UTF-8 + UTF-8 + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + 4.13.2 + test + + + + javax.xml.bind + jaxb-api + 2.3.1 + provided + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + provided + + + javax.activation + activation + 1.1.1 + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + exec + + + + + io.openliberty.tools + liberty-maven-plugin + @pom.version@ + + + + test + src/test/resources/server.xml + + ${runtimeGroupId} + ${runtimeArtifactId} + 23.0.0.9 + zip + + apps + spring-boot-project + + + + + stop-server-before-clean + pre-clean + + stop + + + + create-server + prepare-package + + install-server + create + install-feature + + + + install-apps + package + + deploy + + + + test-start-server + pre-integration-test + + test-start + + + + test-stop-server + post-integration-test + + test-stop + + + + + + + maven-failsafe-plugin + 3.1.2 + + alphabetical + + + + default-integration-test + integration-test + + integration-test + + + + default-verify + verify + + verify + + + + + + + + diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/main/java/application/SpringBootApp.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/main/java/application/SpringBootApp.java new file mode 100644 index 000000000..3612be4a9 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/main/java/application/SpringBootApp.java @@ -0,0 +1,35 @@ +/** + * (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 application; + +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 SpringBootApp { + public static void main(String[] args) { + SpringApplication.run(SpringBootApp.class, args); + } + + @RequestMapping("/spring") + public String hello() { + return "HELLO SPRING BOOT!!"; + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/InstallSpringBoot30AppIT.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/InstallSpringBoot30AppIT.java new file mode 100644 index 000000000..2525e2121 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/InstallSpringBoot30AppIT.java @@ -0,0 +1,37 @@ +/** + * (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 application; + +import static org.junit.Assert.*; + +import java.io.File; +import org.junit.Test; + +public class InstallSpringBoot30AppIT { + + @Test + public void testThinApplicationExistsInAppsDirectory() throws Exception { + + File f = new File("target/liberty/wlp/usr/servers/test/apps/thin-springboot-3-appsdirectory-apps-it-1.0.0.Final-exec.jar"); + assertTrue(f.getCanonicalFile() + " doesn't exist. Plugin failed to place the file at right destination.", f.exists()); + } + + @Test + public void testLibIndexCacheExists() throws Exception { + File f = new File("target/liberty/wlp/usr/shared/resources/lib.index.cache"); + assertTrue(f.getCanonicalFile()+ " doesn't exist. Plugin failed to place the cache directory at right destination.", f.exists()); + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/SpringBoot30RestEndpointIT.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/SpringBoot30RestEndpointIT.java new file mode 100644 index 000000000..ac3123679 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/java/application/SpringBoot30RestEndpointIT.java @@ -0,0 +1,49 @@ +/** + * (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 application; + +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.Test; + +public class SpringBoot30RestEndpointIT { + + @Test + public void testSpringRestBootEndpoint() throws Exception { + + URL requestUrl = new URL("http://localhost:9080/spring/"); + HttpURLConnection conn = (HttpURLConnection) requestUrl.openConnection(); + + if (conn != null) { + assertEquals("Expected response code not found.", 200, conn.getResponseCode()); + } + + StringBuffer response = new StringBuffer(); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { + String line; + while ((line = in.readLine()) != null) { + response.append(line); + } + } + assertEquals("Expected body not found.", "HELLO SPRING BOOT!!", response.toString()); + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/resources/server.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/resources/server.xml new file mode 100644 index 000000000..790a7c85a --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/src/test/resources/server.xml @@ -0,0 +1,14 @@ + + + + + + springBoot-3.0 + servlet-6.0 + + + + + \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml new file mode 100644 index 000000000..0b90735ad --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + + springboot-3-appsdirectory-dropins-it + 1.0.0.Final + jar + + + org.springframework.boot + spring-boot-starter-parent + 3.1.3 + + + + + UTF-8 + UTF-8 + 17 + 17 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + 4.13.2 + test + + + + javax.xml.bind + jaxb-api + 2.3.1 + provided + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + provided + + + javax.activation + activation + 1.1.1 + provided + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + io.openliberty.tools + liberty-maven-plugin + @pom.version@ + + + + test + src/test/resources/server.xml + + ${runtimeGroupId} + ${runtimeArtifactId} + 23.0.0.9 + zip + + spring-boot-project + + + + + stop-server-before-clean + pre-clean + + stop + + + + create-server + prepare-package + + install-server + create + install-feature + + + + install-apps + package + + deploy + + + + test-start-server + pre-integration-test + + test-start + + + + test-stop-server + post-integration-test + + test-stop + + + + + + + maven-failsafe-plugin + 3.1.2 + + alphabetical + + + + default-integration-test + integration-test + + integration-test + + + + default-verify + verify + + verify + + + + + + + + \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/main/java/application/SpringBootApp.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/main/java/application/SpringBootApp.java new file mode 100644 index 000000000..3612be4a9 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/main/java/application/SpringBootApp.java @@ -0,0 +1,35 @@ +/** + * (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 application; + +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 SpringBootApp { + public static void main(String[] args) { + SpringApplication.run(SpringBootApp.class, args); + } + + @RequestMapping("/spring") + public String hello() { + return "HELLO SPRING BOOT!!"; + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/InstallSpringBoot30AppIT.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/InstallSpringBoot30AppIT.java new file mode 100644 index 000000000..2e72ae978 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/InstallSpringBoot30AppIT.java @@ -0,0 +1,37 @@ +/** + * (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 application; + +import static org.junit.Assert.*; + +import java.io.File; +import org.junit.Test; + +public class InstallSpringBoot30AppIT { + + @Test + public void testThinApplicationExistsInDropinsDirectory() throws Exception { + + File f = new File("target/liberty/wlp/usr/servers/test/dropins/spring/thin-springboot-3-appsdirectory-dropins-it-1.0.0.Final.jar"); + assertTrue(f.getCanonicalFile() + " doesn't exist. Plugin failed to place the file at right destination.", f.exists()); + } + + @Test + public void testLibIndexCacheExists() throws Exception { + File f = new File("target/liberty/wlp/usr/shared/resources/lib.index.cache"); + assertTrue(f.getCanonicalFile()+ " doesn't exist. Plugin failed to place the cache directory at right destination.", f.exists()); + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/SpringBoot30RestEndpointIT.java b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/SpringBoot30RestEndpointIT.java new file mode 100644 index 000000000..ac3123679 --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/java/application/SpringBoot30RestEndpointIT.java @@ -0,0 +1,49 @@ +/** + * (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 application; + +import static org.junit.Assert.*; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.Test; + +public class SpringBoot30RestEndpointIT { + + @Test + public void testSpringRestBootEndpoint() throws Exception { + + URL requestUrl = new URL("http://localhost:9080/spring/"); + HttpURLConnection conn = (HttpURLConnection) requestUrl.openConnection(); + + if (conn != null) { + assertEquals("Expected response code not found.", 200, conn.getResponseCode()); + } + + StringBuffer response = new StringBuffer(); + + try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { + String line; + while ((line = in.readLine()) != null) { + response.append(line); + } + } + assertEquals("Expected body not found.", "HELLO SPRING BOOT!!", response.toString()); + } +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/resources/server.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/resources/server.xml new file mode 100644 index 000000000..790a7c85a --- /dev/null +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/src/test/resources/server.xml @@ -0,0 +1,14 @@ + + + + + + springBoot-3.0 + servlet-6.0 + + + + + \ No newline at end of file diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojo.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojo.java index 4fb56fdcb..01ed846e6 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojo.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojo.java @@ -123,9 +123,11 @@ private void installSpringBootApp() throws MojoExecutionException, IOException { File libIndexCacheTarget = getLibIndexCacheTarget(); validateAppConfig(thinArchiveTarget.getCanonicalPath(), thinArchiveTarget.getName(), project.getArtifactId(), true); + installSpringBootFeatureIfNeeded(installDirectory); invokeSpringBootUtilCommand(installDirectory, fatArchiveSrc.getCanonicalPath(), thinArchiveTarget.getCanonicalPath(), libIndexCacheTarget.getCanonicalPath()); } else { - throw new MojoExecutionException(fatArchiveSrc.getCanonicalPath() +" file is not an executable archive. " + File fatArchive = SpringBootUtil.getSpringBootUberJARLocation(project, getLog()); // fatArchiveSrc can be null - so get location of file to use in message + throw new MojoExecutionException(fatArchive.getCanonicalPath() +" file is not an executable archive. " + "The repackage goal of the spring-boot-maven-plugin must be configured to run first in order to create the required executable archive."); } } diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java index e1df929ed..f8e250745 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java @@ -15,12 +15,15 @@ */ package io.openliberty.tools.maven.applications; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; import java.text.MessageFormat; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.Validate; import org.apache.maven.artifact.Artifact; @@ -37,11 +40,16 @@ import io.openliberty.tools.maven.server.LooseAppSupport; import io.openliberty.tools.maven.utils.CommonLogger; import io.openliberty.tools.maven.utils.MavenProjectUtil; +import io.openliberty.tools.maven.utils.SpringBootUtil; import io.openliberty.tools.common.plugins.config.ApplicationXmlDocument; import io.openliberty.tools.common.plugins.config.LooseApplication; import io.openliberty.tools.common.plugins.config.LooseConfigData; import io.openliberty.tools.common.plugins.config.ServerConfigDocument; import io.openliberty.tools.common.plugins.util.DevUtil; +import io.openliberty.tools.common.plugins.util.InstallFeatureUtil; +import io.openliberty.tools.common.plugins.util.InstallFeatureUtil.ProductProperties; +import io.openliberty.tools.common.plugins.util.OSUtil; +import io.openliberty.tools.common.plugins.util.PluginExecutionException; /** * Support for installing and deploying applications to a Liberty server. @@ -474,6 +482,73 @@ protected void invokeSpringBootUtilCommand(File installDirectory, String fatArch springBootUtilTask.execute(); } + protected boolean isSpringBootUtilAvailable(File installDirectory) { + String fileSuffix = OSUtil.isWindows() ? ".bat" : ""; + File installUtil = new File(installDirectory, "bin/installUtility"+fileSuffix); + return installUtil.exists(); + } + + protected void installSpringBootFeatureIfNeeded(File installDirectory) throws MojoExecutionException { + List propertiesList; + Process pr = null; + BufferedReader in = null; + try { + propertiesList = InstallFeatureUtil.loadProperties(installDirectory); + if (InstallFeatureUtil.isClosedLiberty(propertiesList) && !isSpringBootUtilAvailable(installDirectory)) { + String fileSuffix = OSUtil.isWindows() ? ".bat" : ""; + File installUtil = new File(installDirectory, "bin/installUtility"+fileSuffix); + + // only install springBoot feature that matches required version + int springBootMajorVersion = SpringBootUtil.getSpringBootMavenPluginVersion(project); + String sbFeature = SpringBootUtil.getLibertySpringBootFeature(springBootMajorVersion); + if (sbFeature != null) { + StringBuilder sb = new StringBuilder(); + String installUtilCmd; + if (OSUtil.isWindows()) { + installUtilCmd = "\"" + installDirectory + "\\bin\\installUtility.bat\""; + } else { + installUtilCmd = installDirectory + "/bin/installUtility"; + } + ProcessBuilder pb = new ProcessBuilder(installUtilCmd, "install", sbFeature, "--acceptLicense"); + pr = pb.start(); + + in = new BufferedReader(new InputStreamReader(pr.getInputStream())); + String line; + while ((line = in.readLine()) != null) { + sb.append(line).append(System.lineSeparator()); + } + + boolean exited = pr.waitFor(300, TimeUnit.SECONDS); + if(!exited) { // Command did not exit in time + throw new MojoExecutionException("installUtility command timed out"); + } + + int exitValue = pr.exitValue(); + if (exitValue != 0) { + throw new MojoExecutionException("installUtility exited with return code " + exitValue +". The installUtility command run was `"+installUtil+" install "+sbFeature+" --acceptLicense`"); + } + } + } + } catch (IOException ex) { + throw new MojoExecutionException("installUtility error: " + ex); + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new MojoExecutionException("installUtility error: " + ex); + } catch (PluginExecutionException e) { + throw new MojoExecutionException("installUtility error: " + e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } + if (pr != null) { + pr.destroy(); + } + } + } + protected boolean matches(Artifact artifact, Dependency assemblyArtifact) { return artifact.getGroupId().equals(assemblyArtifact.getGroupId()) && artifact.getArtifactId().equals(assemblyArtifact.getArtifactId()) diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/MavenProjectUtil.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/MavenProjectUtil.java index a18899daa..514ca7990 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/MavenProjectUtil.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/MavenProjectUtil.java @@ -207,7 +207,10 @@ public static File getManifestFile(MavenProject proj, String pluginArtifactId) { */ public static int getMajorPluginVersion(MavenProject project, String pluginKey) { Plugin plugin = project.getPlugin(pluginKey); - return Character.getNumericValue(plugin.getVersion().charAt(0)); + if (plugin != null) { + return Character.getNumericValue(plugin.getVersion().charAt(0)); + } + return 0; } } diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/SpringBootUtil.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/SpringBootUtil.java index bfa23ee63..aaf608b67 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/SpringBootUtil.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/utils/SpringBootUtil.java @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corporation 2018, 2020. + * (C) Copyright IBM Corporation 2018, 2023. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,13 +25,22 @@ public class SpringBootUtil { /** - * Checks that the plugin exists for the given pluginKey. + * Checks that the spring-boot-maven-plugin repackage goal execution exists. * */ public static boolean doesSpringBootRepackageGoalExecutionExist(MavenProject project) { return MavenProjectUtil.doesPluginGoalExecutionExist(project, "org.springframework.boot:spring-boot-maven-plugin", "repackage"); } + /** + * Returns the major version number of the configured spring-boot-maven-plugin, or zero if not configured. + * + */ + public static int getSpringBootMavenPluginVersion(MavenProject project) { + return MavenProjectUtil.getMajorPluginVersion(project, "org.springframework.boot:spring-boot-maven-plugin"); + + } + /** * Read the value of the classifier configuration parameter from the * spring-boot-maven-plugin @@ -69,7 +78,11 @@ public static File getSpringBootUberJAR(MavenProject project, Log log) { return fatArchive; } - log.warn("Spring Boot Uber JAR was not found in expected location: " + fatArchive.getAbsolutePath()); + if (fatArchive.exists()) { + log.warn("The file at the following location is not a Spring Boot Uber JAR: " + fatArchive.getAbsolutePath()); + } else { + log.warn("Spring Boot Uber JAR was not found in expected location: " + fatArchive.getAbsolutePath()); + } return null; } @@ -97,4 +110,23 @@ public static File getSpringBootUberJARLocation(MavenProject project, Log log) { } + /* + * Returns the required Open Liberty springBoot feature given the passed springBootMajorVersion. + */ + public static String getLibertySpringBootFeature(int springBootMajorVersion) { + if (isSpringBoot1(springBootMajorVersion)) { + return "springBoot-1.5"; + } else if (isSpringBoot2plus(springBootMajorVersion)) { + return "springBoot-"+springBootMajorVersion+".0"; + } + return null; + } + + public static boolean isSpringBoot1(int springBootMajorVersion) { + return springBootMajorVersion == 1; + } + + public static boolean isSpringBoot2plus(int springBootMajorVersion) { + return springBootMajorVersion > 1; + } } From b78ee8a10f97b3be97cce23b3a8d985c38be7ccc Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Thu, 21 Sep 2023 11:57:01 -0500 Subject: [PATCH 2/4] Use openliberty-runtime in test case to get past error --- .../springboot-3-appsdirectory-apps-it/pom.xml | 6 +++--- .../springboot-3-appsdirectory-dropins-it/pom.xml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml index b0fe0accc..3707ad57c 100644 --- a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml @@ -79,8 +79,8 @@ test src/test/resources/server.xml - ${runtimeGroupId} - ${runtimeArtifactId} + io.openliberty + openliberty-runtime 23.0.0.9 zip @@ -102,7 +102,7 @@ install-server create - install-feature + diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml index 0b90735ad..434427e15 100644 --- a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml @@ -76,8 +76,8 @@ test src/test/resources/server.xml - ${runtimeGroupId} - ${runtimeArtifactId} + io.openliberty + openliberty-runtime 23.0.0.9 zip @@ -98,7 +98,7 @@ install-server create - install-feature + From 420f2a9006c1d66c1d03cc7ba88226396688008d Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Wed, 18 Oct 2023 12:41:26 -0500 Subject: [PATCH 3/4] Add support for SpringBoot 3 --- .github/workflows/maven.yml | 8 +++++ .../pom.xml | 8 ++--- .../pom.xml | 9 +++--- .../maven/applications/DeployMojoSupport.java | 29 +++++++++---------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index adce6d7b1..27ea06464 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -64,6 +64,10 @@ jobs: run: | ./mvnw -V clean install -f ci.ant --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false ./mvnw -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: ./mvnw -V verify --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -Ponline-its -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" # Run tests - name: Run tests run: ./mvnw -V verify --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -Ponline-its -D"invoker.streamLogsOnFailures"=true -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" @@ -112,6 +116,10 @@ jobs: - name: Install ci.common working-directory: C:/ci.common run: .\mvnw.cmd -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: .\mvnw.cmd -V verify -Ponline-its --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" # Run tests - name: Run tests working-directory: C:/ci.maven diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml index 3707ad57c..148318219 100644 --- a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-apps-it/pom.xml @@ -79,9 +79,9 @@ test src/test/resources/server.xml - io.openliberty - openliberty-runtime - 23.0.0.9 + com.ibm.websphere.appserver.runtime + wlp-jakartaee10 + 23.0.0.10 zip apps @@ -102,7 +102,7 @@ install-server create - + install-feature diff --git a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml index 434427e15..d4311e3a2 100644 --- a/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml +++ b/liberty-maven-plugin/src/it/springboot-3-tests/springboot-3-appsdirectory-dropins-it/pom.xml @@ -75,12 +75,12 @@ test src/test/resources/server.xml - + io.openliberty - openliberty-runtime - 23.0.0.9 + openliberty-kernel + 23.0.0.10 zip - + spring-boot-project @@ -98,7 +98,6 @@ install-server create - diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java index f8e250745..7fc8222a8 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/applications/DeployMojoSupport.java @@ -482,34 +482,33 @@ protected void invokeSpringBootUtilCommand(File installDirectory, String fatArch springBootUtilTask.execute(); } - protected boolean isSpringBootUtilAvailable(File installDirectory) { - String fileSuffix = OSUtil.isWindows() ? ".bat" : ""; - File installUtil = new File(installDirectory, "bin/installUtility"+fileSuffix); + protected boolean isUtilityAvailable(File installDirectory, String utilityName) { + String utilFileName = OSUtil.isWindows() ? utilityName+".bat" : utilityName; + File installUtil = new File(installDirectory, "bin/"+utilFileName); return installUtil.exists(); } protected void installSpringBootFeatureIfNeeded(File installDirectory) throws MojoExecutionException { - List propertiesList; Process pr = null; BufferedReader in = null; try { - propertiesList = InstallFeatureUtil.loadProperties(installDirectory); - if (InstallFeatureUtil.isClosedLiberty(propertiesList) && !isSpringBootUtilAvailable(installDirectory)) { + if (!isUtilityAvailable(installDirectory, "springBootUtility") && isUtilityAvailable(installDirectory, "featureUtility")) { String fileSuffix = OSUtil.isWindows() ? ".bat" : ""; - File installUtil = new File(installDirectory, "bin/installUtility"+fileSuffix); + File installUtil = new File(installDirectory, "bin/featureUtility"+fileSuffix); // only install springBoot feature that matches required version int springBootMajorVersion = SpringBootUtil.getSpringBootMavenPluginVersion(project); String sbFeature = SpringBootUtil.getLibertySpringBootFeature(springBootMajorVersion); if (sbFeature != null) { + getLog().info("Required springBootUtility not found in Liberty installation. Installing feature "+sbFeature+" to enable it."); StringBuilder sb = new StringBuilder(); String installUtilCmd; if (OSUtil.isWindows()) { - installUtilCmd = "\"" + installDirectory + "\\bin\\installUtility.bat\""; + installUtilCmd = "\"" + installDirectory + "\\bin\\featureUtility.bat\""; } else { - installUtilCmd = installDirectory + "/bin/installUtility"; + installUtilCmd = installDirectory + "/bin/featureUtility"; } - ProcessBuilder pb = new ProcessBuilder(installUtilCmd, "install", sbFeature, "--acceptLicense"); + ProcessBuilder pb = new ProcessBuilder(installUtilCmd, "installFeature", sbFeature, "--acceptLicense"); pr = pb.start(); in = new BufferedReader(new InputStreamReader(pr.getInputStream())); @@ -520,22 +519,20 @@ protected void installSpringBootFeatureIfNeeded(File installDirectory) throws Mo boolean exited = pr.waitFor(300, TimeUnit.SECONDS); if(!exited) { // Command did not exit in time - throw new MojoExecutionException("installUtility command timed out"); + throw new MojoExecutionException("featureUtility command timed out"); } int exitValue = pr.exitValue(); if (exitValue != 0) { - throw new MojoExecutionException("installUtility exited with return code " + exitValue +". The installUtility command run was `"+installUtil+" install "+sbFeature+" --acceptLicense`"); + throw new MojoExecutionException("featureUtility exited with return code " + exitValue +". The featureUtility command run was `"+installUtil+" installFeature "+sbFeature+" --acceptLicense`"); } } } } catch (IOException ex) { - throw new MojoExecutionException("installUtility error: " + ex); + throw new MojoExecutionException("featureUtility error: " + ex); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); - throw new MojoExecutionException("installUtility error: " + ex); - } catch (PluginExecutionException e) { - throw new MojoExecutionException("installUtility error: " + e); + throw new MojoExecutionException("featureUtility error: " + ex); } finally { if (in != null) { try { From fc1ed5c3ad3418166155997ff06159177a2ee468 Mon Sep 17 00:00:00 2001 From: Cheryl King Date: Wed, 18 Oct 2023 12:57:33 -0500 Subject: [PATCH 4/4] Add setup to Java 17 test run --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index c35ba3c0c..83cbd8022 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -67,7 +67,7 @@ jobs: # Run tests that require Java 17 or later - name: Run tests that require Java 17 or later if: ${{ matrix.java == '17' }} - run: ./mvnw -V verify --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -Ponline-its -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" + run: ./mvnw -V verify --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -Ponline-its -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*setup*,*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" # Run tests - name: Run tests run: ./mvnw -V verify --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -Ponline-its -D"invoker.streamLogsOnFailures"=true -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" @@ -119,7 +119,7 @@ jobs: # Run tests that require Java 17 or later - name: Run tests that require Java 17 or later if: ${{ matrix.java == '17' }} - run: .\mvnw.cmd -V verify -Ponline-its --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" + run: .\mvnw.cmd -V verify -Ponline-its --batch-mode --no-transfer-progress --errors -DtrimStackTrace=false -D"invoker.streamLogsOnFailures"=true -D"invoker.test"="*setup*,*springboot-3-*" -Druntime=${{ matrix.RUNTIME }} -DruntimeVersion="${{ matrix.RUNTIME_VERSION }}" # Run tests - name: Run tests working-directory: C:/ci.maven