From 859b5ca5e3887f364754d472f91f26c718f86108 Mon Sep 17 00:00:00 2001 From: Michael Vorburger Date: Wed, 19 Sep 2018 23:44:38 +0200 Subject: [PATCH] {WIP} examples/spring-devtools (fixes #171) --- .gitignore | 5 ++ java/examples/spring-devtools/README.md | 54 +++++++++++++++++ java/examples/spring-devtools/pom.xml | 58 +++++++++++++++++++ .../spring/example/ExampleApplication.java | 14 +++++ .../s2i/java/spring/example/HelloServlet.java | 17 ++++++ .../example/ExampleApplicationTests.java | 32 ++++++++++ java/templates/README.md | 12 ++-- java/templates/s2i/assemble | 2 +- test.sh | 12 +++- 9 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 java/examples/spring-devtools/README.md create mode 100644 java/examples/spring-devtools/pom.xml create mode 100644 java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/ExampleApplication.java create mode 100644 java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java create mode 100644 java/examples/spring-devtools/src/test/java/io/okd/s2i/java/spring/example/ExampleApplicationTests.java diff --git a/.gitignore b/.gitignore index 4b5bd55c..dcdb8b17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ .DS_Store old + +# Eclipse +.project +.classpath +.settings/ diff --git a/java/examples/spring-devtools/README.md b/java/examples/spring-devtools/README.md new file mode 100644 index 00000000..65ff448c --- /dev/null +++ b/java/examples/spring-devtools/README.md @@ -0,0 +1,54 @@ +# s2i-java-spring-devtools-example + +This is an project illustrating [Spring Boot Automatic Restarts](../../images/centos/README.md#spring-boot-automatic-restarts). + + +## Local without container + +Run using: + + mvn spring-boot:run + +Open [http://localhost:8080/hello](http://localhost:8080/hello) - see "hello, xorld" ? Wrong. + +Edit `src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java` to change "hello, xorld" to "hello, world". +Use an IDE like Eclipse, with incremental rebuild of the .class file (won't work with a raw text editor). + +Spring Boot devtools will automatically restart and (on reloading /hello) show "hello, world" - good. + + +## Local in container by S2I + +For local building, install s2i either from source https://github.com/openshift/source-to-image/releases/ or e.g. via: + + sudo dnf install source-to-image + +Now to locally build a container using OpenShift Source-To-Image (S2I) use: + + s2i build --copy . fabric8/s2i-java s2i-java-spring-devtools-example + +Now run it like this: + + docker run -p 8080:8080 s2i-java-spring-devtools-example + +and see "hello, xorld" when accessing [http://localhost:8080/hello](http://localhost:8080/hello) - it works, but oups, it's wrong. + +Edit `src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java` to change "hello, xorld" to "hello, world". +Use an IDE like Eclipse, with incremental rebuild of the .class file (won't work with a raw text editor). +Now copy the fixed class file into the running container: + + docker cp src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java $(docker ps --filter ancestor=s2i-java-spring-devtools-example --format "{{.ID}}"):/TODO + +_TODO NOK; cp .class or .java? What is the right path to copy it into? /deployments/ has .jar not .class? /tmp/src(/target) isn't what we want?? Check:_ + + docker exec -it $(docker ps --filter ancestor=s2i-java-spring-devtools-example --format "{{.ID}}") bash + +**Spring Boot devtools will automatically restart, in container, and (on reloading /hello) show "hello, world" - great!** + + + +## In OpenShift via MiniShift + +_[oc rsync](https://docs.okd.io/latest/dev_guide/copy_files_to_container.html)_ + +**TODO** diff --git a/java/examples/spring-devtools/pom.xml b/java/examples/spring-devtools/pom.xml new file mode 100644 index 00000000..16bf3133 --- /dev/null +++ b/java/examples/spring-devtools/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + io.okd.s2i.java.spring + example + 1.0.0-SNAPSHOT + jar + + example + Example project illustrating Spring Boot Devtools on OpenShift with S2I + + + org.springframework.boot + spring-boot-starter-parent + 2.0.5.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + true + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + false + + + + + diff --git a/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/ExampleApplication.java b/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/ExampleApplication.java new file mode 100644 index 00000000..ba257071 --- /dev/null +++ b/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/ExampleApplication.java @@ -0,0 +1,14 @@ +package io.okd.s2i.java.spring.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; + +@SpringBootApplication +@ServletComponentScan +public class ExampleApplication { + + public static void main(String[] args) { + SpringApplication.run(ExampleApplication.class, args); + } +} diff --git a/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java b/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java new file mode 100644 index 00000000..d1d0cab6 --- /dev/null +++ b/java/examples/spring-devtools/src/main/java/io/okd/s2i/java/spring/example/HelloServlet.java @@ -0,0 +1,17 @@ +package io.okd.s2i.java.spring.example; + +import java.io.IOException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet("/hello") +@SuppressWarnings("serial") +public class HelloServlet extends HttpServlet { + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + response.getOutputStream().print("hello, xorld"); + } +} diff --git a/java/examples/spring-devtools/src/test/java/io/okd/s2i/java/spring/example/ExampleApplicationTests.java b/java/examples/spring-devtools/src/test/java/io/okd/s2i/java/spring/example/ExampleApplicationTests.java new file mode 100644 index 00000000..f497e417 --- /dev/null +++ b/java/examples/spring-devtools/src/test/java/io/okd/s2i/java/spring/example/ExampleApplicationTests.java @@ -0,0 +1,32 @@ +package io.okd.s2i.java.spring.example; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) +public class ExampleApplicationTests { + + @Autowired private TestRestTemplate restTemplate; + + @Test + public void contextLoads() { + } + + @Test + public void testHelloXorld() { + ResponseEntity responseEntity = restTemplate.getForEntity("/hello", String.class); + + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + assertEquals("hello, xorld", responseEntity.getBody()); + } +} diff --git a/java/templates/README.md b/java/templates/README.md index 81617296..00853b14 100644 --- a/java/templates/README.md +++ b/java/templates/README.md @@ -23,11 +23,13 @@ The following environment variables can be used to influence the behaviour of th Application arguments can be provided by setting the variable **JAVA_ARGS** to the corresponding value. -## Spring Boot Automatic Restarts +## Spring Boot Automatic Restarts -This image also supports detecting jars with [Spring Boot devtools](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-devtools) included, which allows automatic restarts when files on the classpath are updated. Files can be easily updated in OpenShift using command [`oc rsync`](https://docs.openshift.org/latest/dev_guide/copy_files_to_container.html). +This image also supports detecting jars with [Spring Boot devtools](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-devtools) included, which allows automatic restarts when files on the classpath are updated. Files can be easily updated in OpenShift using command [`oc rsync`](https://docs.openshift.org/latest/dev_guide/copy_files_to_container.html). -To enable automatic restarts, three things are required: +A [ready made example show case project](../../examples/spring-devtools) is here. + +To enable automatic restarts, three things are required: 1. Add Spring Boot devtools dependency: @@ -57,7 +59,7 @@ To enable automatic restarts, three things are required: ``` -3. Set environment variables `JAVA_DEBUG=true` or `DEBUG=true` and optionally `JAVA_DEBUG_PORT=` or `DEBUG_PORT=`, which defaults to 5005. Since the `DEBUG` variable clashes with Spring Boot's recognition of the same variable to enable Spring Boot debug logging, use `SPRINGBOOT_DEBUG` instead. +3. Set environment variables `JAVA_DEBUG=true` or `DEBUG=true` and optionally `JAVA_DEBUG_PORT=` or `DEBUG_PORT=`, which defaults to 5005. Since the `DEBUG` variable clashes with Spring Boot's recognition of the same variable to enable Spring Boot debug logging, use `SPRINGBOOT_DEBUG` instead. -WARNING: Do not use devtools in production!!! This can be accomplished in Maven using a custom profile. +WARNING: Do not use devtools in production!!! This can be accomplished in Maven using a custom profile. diff --git a/java/templates/s2i/assemble b/java/templates/s2i/assemble index d9747cc4..cec496da 100755 --- a/java/templates/s2i/assemble +++ b/java/templates/s2i/assemble @@ -287,7 +287,7 @@ else fi # check if this is a fat jar executable archive. SpringBoot fat jars can be exploded -echo "Checking for fat jar archive..." +echo "Checking for 'fat JAR' archive..." old_dir=`pwd` cd "${DEPLOYMENTS_DIR}" nr_jars=`ls *.jar 2>/dev/null | grep -v '^original-' | wc -l | tr -d '[[:space:]]'` diff --git a/test.sh b/test.sh index ffb8ed58..01bc46be 100755 --- a/test.sh +++ b/test.sh @@ -32,6 +32,7 @@ function test_container() { # ---------------------------------------------------------------------------------- # Maven +# -------------------------------------------------------------------------------- s2i build --copy java/examples/maven fabric8/s2i-java fabric8/s2i-java-maven-example @@ -45,7 +46,6 @@ test_container "s2i-java-maven-example" # Gradle # -------------------------------------------------------------------------------- - s2i build --copy java/examples/gradle fabric8/s2i-java fabric8/s2i-java-gradle-example s2i build --copy java/examples/gradle fabric8/s2i-java fabric8/s2i-java-gradle-example --incremental @@ -65,6 +65,16 @@ rm java/examples/binary/deployments/* test_container "s2i-java-binary-example" + +# ---------------------------------------------------------------------------------- +# Spring Boot Developer Tools +# ---------------------------------------------------------------------------------- + +s2i build --copy java/examples/spring-devtools fabric8/s2i-java fabric8/s2i-java-spring-devtools-example + +test_container "s2i-java-spring-devtools-example" + + # ---------------------------------------------------------------------------------- # Maven Wrapper # ----------------------------------------------------------------------------------