diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 138b7ca23..a732481a5 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -21,7 +21,7 @@
"extensions": [
"vscjava.vscode-java-pack",
"redhat.vscode-xml",
- "Pivotal.vscode-boot-dev-pack",
+ "vmware.vscode-boot-dev-pack",
"mhutchie.git-graph"
],
"forwardPorts": [8080],
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 000000000..21de586dd
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+mvnw text eol=lf
+*.java text eol=lf
diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
index 13bf81a4c..5de223fc6 100644
--- a/.github/workflows/maven-build.yml
+++ b/.github/workflows/maven-build.yml
@@ -15,10 +15,10 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- java: [ '8', '11', '17' ]
+ java: [ '17' ]
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up JDK ${{matrix.java}}
uses: actions/setup-java@v2
with:
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
index 2cc7d4a55..bf82ff01c 100644
Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index 4be234949..ca5ab4bab 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,3 +1,18 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.2/apache-maven-3.8.2-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
-
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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
+#
+# https://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.
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
diff --git a/build.gradle b/build.gradle
index 5f62c0615..d0a34bf67 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,21 +1,22 @@
plugins {
- id 'org.springframework.boot' version '2.7.3'
- id 'io.spring.dependency-management' version '1.0.13.RELEASE'
id 'java'
+ id 'org.springframework.boot' version '3.0.4'
+ id 'io.spring.dependency-management' version '1.1.0'
+ id 'org.graalvm.buildtools.native' version '0.9.20'
}
apply plugin: 'java'
group = 'org.springframework.samples'
-version = '2.7.3'
-sourceCompatibility = '11'
+version = '3.0.0'
+sourceCompatibility = '17'
repositories {
mavenCentral()
}
ext.webjarsFontawesomeVersion = "4.7.0"
-ext.webjarsBootstrapVersion = "5.1.3"
+ext.webjarsBootstrapVersion = "5.2.3"
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-cache'
@@ -24,12 +25,13 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'javax.cache:cache-api'
+ implementation 'jakarta.xml.bind:jakarta.xml.bind-api'
runtimeOnly 'org.springframework.boot:spring-boot-starter-actuator'
runtimeOnly "org.webjars.npm:bootstrap:${webjarsBootstrapVersion}"
runtimeOnly "org.webjars.npm:font-awesome:${webjarsFontawesomeVersion}"
- runtimeOnly 'org.ehcache:ehcache'
+ runtimeOnly 'com.github.ben-manes.caffeine:caffeine'
runtimeOnly 'com.h2database:h2'
- runtimeOnly 'mysql:mysql-connector-java'
+ runtimeOnly 'com.mysql:mysql-connector-j'
runtimeOnly 'org.postgresql:postgresql'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
diff --git a/docker-compose.yml b/docker-compose.yml
index 4c81a828c..39601f1d7 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -2,7 +2,7 @@ version: "2.2"
services:
mysql:
- image: mysql:5.7
+ image: mysql:8.0
ports:
- "3306:3306"
environment:
@@ -14,7 +14,7 @@ services:
volumes:
- "./conf.d:/etc/mysql/conf.d:ro"
postgres:
- image: postgres:14.1
+ image: postgres:15.2
ports:
- "5432:5432"
environment:
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 7454180f2..249e5832f 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ae04661ee..774fae876 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 1b6c78733..a69d9cb6c 100755
--- a/gradlew
+++ b/gradlew
@@ -205,6 +205,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
diff --git a/gradlew.bat b/gradlew.bat
index ac1b06f93..53a6b238d 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,7 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,13 +75,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/mvnw b/mvnw
index 2c90d17e4..8a8fb2282 100755
--- a/mvnw
+++ b/mvnw
@@ -8,7 +8,7 @@
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0'
+# https://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
@@ -36,6 +36,10 @@
if [ -z "$MAVEN_SKIP_RC" ] ; then
+ if [ -f /usr/local/etc/mavenrc ] ; then
+ . /usr/local/etc/mavenrc
+ fi
+
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
@@ -145,7 +149,7 @@ if [ -z "$JAVACMD" ] ; then
JAVACMD="$JAVA_HOME/bin/java"
fi
else
- JAVACMD="`which java`"
+ JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
@@ -212,9 +216,9 @@ else
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
- jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
@@ -233,9 +237,9 @@ else
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
- wget "$jarUrl" -O "$wrapperJarPath"
+ wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
- wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
@@ -305,6 +309,8 @@ WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
+ $MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
- "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
+ "-Dmaven.home=${M2_HOME}" \
+ "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
diff --git a/mvnw.cmd b/mvnw.cmd
index 0d34af450..1d8ab018e 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -7,7 +7,7 @@
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
-@REM https://www.apache.org/licenses/LICENSE-2.0'
+@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@@ -46,8 +46,8 @@ if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
+if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
@@ -120,9 +120,9 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
-FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@@ -134,7 +134,7 @@ if exist %WRAPPER_JAR% (
)
) else (
if not "%MVNW_REPOURL%" == "" (
- SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
@@ -158,7 +158,13 @@ if exist %WRAPPER_JAR% (
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
+%MAVEN_JAVA_EXE% ^
+ %JVM_CONFIG_MAVEN_PROPS% ^
+ %MAVEN_OPTS% ^
+ %MAVEN_DEBUG_OPTS% ^
+ -classpath %WRAPPER_JAR% ^
+ "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
+ %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
@@ -168,15 +174,15 @@ set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
+if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
+if "%MAVEN_BATCH_PAUSE%"=="on" pause
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
-exit /B %ERROR_CODE%
+cmd /C exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index d29355c5f..a6c550fcc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,29 +3,29 @@
4.0.0
org.springframework.samples
spring-petclinic
- 2.7.3
+ 3.0.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
- 2.7.3
+ 3.0.4
petclinic
- 1.8
+ 17
UTF-8
UTF-8
- 5.1.3
+ 5.2.3
4.7.0
- 0.8.7
- 0.0.10
- 0.0.31
+ 0.8.8
+ 0.0.11
+ 0.0.38
@@ -68,8 +68,8 @@
runtime
- mysql
- mysql-connector-java
+ com.mysql
+ mysql-connector-j
runtime
@@ -84,8 +84,8 @@
cache-api
- org.ehcache
- ehcache
+ com.github.ben-manes.caffeine
+ caffeine
@@ -106,6 +106,12 @@
spring-boot-devtools
true
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+
+
@@ -123,15 +129,35 @@
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+
+
+ enforce-java
+
+ enforce
+
+
+
+
+ This build requires at least Java ${java.version}, update your JVM, and run the build again
+ ${java.version}
+
+
+
+
+
+
org.apache.maven.plugins
maven-checkstyle-plugin
- 3.1.2
+ 3.2.1
com.puppycrawl.tools
checkstyle
- 8.45.1
+ 10.8.1
io.spring.nohttp
@@ -157,6 +183,10 @@
+
+ org.graalvm.buildtools
+ native-maven-plugin
+
org.springframework.boot
spring-boot-maven-plugin
@@ -201,21 +231,9 @@
- pl.project13.maven
- git-commit-id-plugin
-
-
-
- revision
-
-
-
+ io.github.git-commit-id
+ git-commit-id-maven-plugin
- true
- yyyy-MM-dd'T'HH:mm:ssZ
- true
- ${project.build.outputDirectory}/git.properties
-
false
false
@@ -302,7 +320,7 @@
com.gitlab.haynes
libsass-maven-plugin
- 0.2.26
+ 0.2.29
generate-resources
diff --git a/readme.md b/readme.md
index 8ee884876..13b80742c 100644
--- a/readme.md
+++ b/readme.md
@@ -1,12 +1,15 @@
# Spring PetClinic Sample Application [](https://github.com/spring-projects/spring-petclinic/actions/workflows/maven-build.yml)
-[](https://gitpod.io/#https://github.com/spring-projects/spring-petclinic)
+[](https://gitpod.io/#https://github.com/spring-projects/spring-petclinic) [](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=7517918)
+
+
+
## Understanding the Spring Petclinic application with a few diagrams
See the presentation here
## Running petclinic locally
-Petclinic is a [Spring Boot](https://spring.io/guides/gs/spring-boot) application built using [Maven](https://spring.io/guides/gs/maven/) or [Gradle](https://spring.io/guides/gs/gradle/). You can build a jar file and run it from the command line (it should work just as well with Java 11 or newer):
+Petclinic is a [Spring Boot](https://spring.io/guides/gs/spring-boot) application built using [Maven](https://spring.io/guides/gs/maven/) or [Gradle](https://spring.io/guides/gs/gradle/). You can build a jar file and run it from the command line (it should work just as well with Java 17 or newer):
```
@@ -16,11 +19,11 @@ cd spring-petclinic
java -jar target/*.jar
```
-You can then access petclinic here: http://localhost:8080/
+You can then access petclinic at http://localhost:8080/
-Or you can run it from Maven directly using the Spring Boot Maven plugin. If you do this it will pick up changes that you make in the project immediately (changes to Java source files require a compile as well - most people use an IDE for this):
+Or you can run it from Maven directly using the Spring Boot Maven plugin. If you do this, it will pick up changes that you make in the project immediately (changes to Java source files require a compile as well - most people use an IDE for this):
```
./mvnw spring-boot:run
@@ -39,27 +42,27 @@ There is no `Dockerfile` in this project. You can build a container image (if yo
```
## In case you find a bug/suggested improvement for Spring Petclinic
-Our issue tracker is available here: https://github.com/spring-projects/spring-petclinic/issues
+Our issue tracker is available [here](https://github.com/spring-projects/spring-petclinic/issues)
## Database configuration
In its default configuration, Petclinic uses an in-memory database (H2) which
-gets populated at startup with data. The h2 console is automatically exposed at `http://localhost:8080/h2-console`
+gets populated at startup with data. The h2 console is exposed at `http://localhost:8080/h2-console`,
and it is possible to inspect the content of the database using the `jdbc:h2:mem:testdb` url.
-A similar setup is provided for MySQL and PostgreSQL in case a persistent database configuration is needed. Note that whenever the database type is changed, the app needs to be run with a different profile: `spring.profiles.active=mysql` for MySQL or `spring.profiles.active=postgres` for PostgreSQL.
+A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed. Note that whenever the database type changes, the app needs to run with a different profile: `spring.profiles.active=mysql` for MySQL or `spring.profiles.active=postgres` for PostgreSQL.
-You could start MySQL or PostgreSQL locally with whatever installer works for your OS, or with docker:
+You can start MySQL or PostgreSQL locally with whatever installer works for your OS or use docker:
```
-docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:5.7.8
+docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:8.0
```
or
```
-docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 postgres:14.1
+docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 postgres:15.2
```
Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt)
@@ -73,34 +76,34 @@ There is a `petclinic.css` in `src/main/resources/static/resources/css`. It was
### Prerequisites
The following items should be installed in your system:
-* Java 11 or newer (full JDK not a JRE).
-* git command line tool (https://help.github.com/articles/set-up-git)
+* Java 17 or newer (full JDK, not a JRE).
+* [git command line tool](https://help.github.com/articles/set-up-git)
* Your preferred IDE
* Eclipse with the m2e plugin. Note: when m2e is available, there is an m2 icon in `Help -> About` dialog. If m2e is
- not there, just follow the install process here: https://www.eclipse.org/m2e/
+ not there, follow the install process [here](https://www.eclipse.org/m2e/)
* [Spring Tools Suite](https://spring.io/tools) (STS)
- * IntelliJ IDEA
+ * [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [VS Code](https://code.visualstudio.com)
### Steps:
-1) On the command line
+1) On the command line run:
```
git clone https://github.com/spring-projects/spring-petclinic.git
```
-2) Inside Eclipse or STS
+2) Inside Eclipse or STS:
```
File -> Import -> Maven -> Existing Maven project
```
- Then either build on the command line `./mvnw generate-resources` or using the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right clicking on it and choosing `Run As -> Java Application`.
+ Then either build on the command line `./mvnw generate-resources` or use the Eclipse launcher (right click on project and `Run As -> Maven install`) to generate the css. Run the application main method by right-clicking on it and choosing `Run As -> Java Application`.
3) Inside IntelliJ IDEA
In the main menu, choose `File -> Open` and select the Petclinic [pom.xml](pom.xml). Click on the `Open` button.
- CSS files are generated from the Maven build. You can either build them on the command line `./mvnw generate-resources` or right click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`.
+ CSS files are generated from the Maven build. You can build them on the command line `./mvnw generate-resources` or right-click on the `spring-petclinic` project then `Maven -> Generates sources and Update Folders`.
- A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate version. Otherwise, run the application by right clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`.
+ A run configuration named `PetClinicApplication` should have been created for you if you're using a recent Ultimate version. Otherwise, run the application by right-clicking on the `PetClinicApplication` main class and choosing `Run 'PetClinicApplication'`.
4) Navigate to Petclinic
@@ -118,15 +121,14 @@ The following items should be installed in your system:
## Interesting Spring Petclinic branches and forks
The Spring Petclinic "main" branch in the [spring-projects](https://github.com/spring-projects/spring-petclinic)
-GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are
-[quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in a special GitHub org
-[spring-petclinic](https://github.com/spring-petclinic). If you have a special interest in a different technology stack
-that could be used to implement the Pet Clinic then please join the community there.
+GitHub org is the "canonical" implementation based on Spring Boot and Thymeleaf. There are
+[quite a few forks](https://spring-petclinic.github.io/docs/forks.html) in the GitHub org
+[spring-petclinic](https://github.com/spring-petclinic). If you are interested in using a different technology stack to implement the Pet Clinic, please join the community there.
## Interaction with other open source projects
-One of the best parts about working on the Spring Petclinic application is that we have the opportunity to work in direct contact with many Open Source projects. We found some bugs/suggested improvements on various topics such as Spring, Spring Data, Bean Validation and even Eclipse! In many cases, they've been fixed/implemented in just a few days.
+One of the best parts about working on the Spring Petclinic application is that we have the opportunity to work in direct contact with many Open Source projects. We found bugs/suggested improvements on various topics such as Spring, Spring Data, Bean Validation and even Eclipse! In many cases, they've been fixed/implemented in just a few days.
Here is a list of them:
| Name | Issue |
diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
index 0b2ffc129..ac6e15030 100644
--- a/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
+++ b/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
@@ -18,6 +18,7 @@ package org.springframework.samples.petclinic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ImportRuntimeHints;
/**
* PetClinic Spring Boot Application.
@@ -26,6 +27,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
*
*/
@SpringBootApplication
+@ImportRuntimeHints(PetClinicRuntimeHints.class)
public class PetClinicApplication {
public static void main(String[] args) {
diff --git a/src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java b/src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java
new file mode 100644
index 000000000..2ac7e02e9
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/PetClinicRuntimeHints.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012-2019 the original author or authors.
+ *
+ * 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
+ *
+ * https://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 org.springframework.samples.petclinic;
+
+import org.springframework.aot.hint.RuntimeHints;
+import org.springframework.aot.hint.RuntimeHintsRegistrar;
+
+public class PetClinicRuntimeHints implements RuntimeHintsRegistrar {
+
+ @Override
+ public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
+ hints.resources().registerPattern("db/*"); // https://github.com/spring-projects/spring-boot/issues/32654
+ hints.resources().registerPattern("messages/*");
+ hints.resources().registerPattern("META-INF/resources/webjars/*");
+ }
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
index 4cb9ffc0c..3038bce3a 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/BaseEntity.java
@@ -17,10 +17,10 @@ package org.springframework.samples.petclinic.model;
import java.io.Serializable;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object with an id property. Used as a base class for objects
diff --git a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
index 088e52e81..7c2ccb2d6 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/NamedEntity.java
@@ -15,8 +15,8 @@
*/
package org.springframework.samples.petclinic.model;
-import javax.persistence.Column;
-import javax.persistence.MappedSuperclass;
+import jakarta.persistence.Column;
+import jakarta.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object adds a name property to BaseEntity
. Used as
diff --git a/src/main/java/org/springframework/samples/petclinic/model/Person.java b/src/main/java/org/springframework/samples/petclinic/model/Person.java
index 15fabacc3..e41b6ba90 100644
--- a/src/main/java/org/springframework/samples/petclinic/model/Person.java
+++ b/src/main/java/org/springframework/samples/petclinic/model/Person.java
@@ -15,9 +15,9 @@
*/
package org.springframework.samples.petclinic.model;
-import javax.persistence.Column;
-import javax.persistence.MappedSuperclass;
-import javax.validation.constraints.NotEmpty;
+import jakarta.persistence.Column;
+import jakarta.persistence.MappedSuperclass;
+import jakarta.validation.constraints.NotEmpty;
/**
* Simple JavaBean domain object representing an person.
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
index 52ff1190f..ac556459d 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Owner.java
@@ -18,21 +18,21 @@ package org.springframework.samples.petclinic.owner;
import java.util.ArrayList;
import java.util.List;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.OneToMany;
-import javax.persistence.OrderBy;
-import javax.persistence.Table;
-import javax.validation.constraints.Digits;
-import javax.validation.constraints.NotEmpty;
-
import org.springframework.core.style.ToStringCreator;
import org.springframework.samples.petclinic.model.Person;
import org.springframework.util.Assert;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.OrderBy;
+import jakarta.persistence.Table;
+import jakarta.validation.constraints.Digits;
+import jakarta.validation.constraints.NotEmpty;
+
/**
* Simple JavaBean domain object representing an owner.
*
@@ -109,7 +109,7 @@ public class Owner extends Person {
/**
* Return the Pet with the given id, or null if none found for this Owner.
- * @param name to test
+ * @param id to test
* @return a pet if pet id is already in use
*/
public Pet getPet(Integer id) {
@@ -145,10 +145,14 @@ public class Owner extends Person {
@Override
public String toString() {
- return new ToStringCreator(this).append("id", this.getId()).append("new", this.isNew())
- .append("lastName", this.getLastName()).append("firstName", this.getFirstName())
- .append("address", this.address).append("city", this.city).append("telephone", this.telephone)
- .toString();
+ return new ToStringCreator(this).append("id", this.getId())
+ .append("new", this.isNew())
+ .append("lastName", this.getLastName())
+ .append("firstName", this.getFirstName())
+ .append("address", this.address)
+ .append("city", this.city)
+ .append("telephone", this.telephone)
+ .toString();
}
/**
@@ -156,7 +160,7 @@ public class Owner extends Person {
* @param petId the identifier of the {@link Pet}, must not be {@literal null}.
* @param visit the visit to add, must not be {@literal null}.
*/
- public Owner addVisit(Integer petId, Visit visit) {
+ public void addVisit(Integer petId, Visit visit) {
Assert.notNull(petId, "Pet identifier must not be null!");
Assert.notNull(visit, "Visit must not be null!");
@@ -166,8 +170,6 @@ public class Owner extends Person {
Assert.notNull(pet, "Invalid Pet identifier!");
pet.addVisit(visit);
-
- return this;
}
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
index 3c9632710..c91a94c93 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerController.java
@@ -17,7 +17,7 @@ package org.springframework.samples.petclinic.owner;
import java.util.List;
import java.util.Map;
-import javax.validation.Valid;
+
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@@ -33,6 +33,8 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
+import jakarta.validation.Valid;
+
/**
* @author Juergen Hoeller
* @author Ken Krebs
@@ -78,8 +80,7 @@ class OwnerController {
}
@GetMapping("/owners/find")
- public String initFindForm(Map model) {
- model.put("owner", new Owner());
+ public String initFindForm() {
return "owners/findOwners";
}
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
index 062df4576..f44449439 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/OwnerRepository.java
@@ -73,7 +73,7 @@ public interface OwnerRepository extends Repository {
void save(Owner owner);
/**
- * Returnes all the owners from data store
+ * Returns all the owners from data store
**/
@Query("SELECT owner FROM Owner owner")
@Transactional(readOnly = true)
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
index a863c754f..0b0c08ac6 100755
--- a/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Pet.java
@@ -20,19 +20,19 @@ import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
-import javax.persistence.CascadeType;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.OneToMany;
-import javax.persistence.OrderBy;
-import javax.persistence.Table;
-
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.samples.petclinic.model.NamedEntity;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.OrderBy;
+import jakarta.persistence.Table;
+
/**
* Simple business object representing a pet.
*
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
index 2feae7ee2..9d88f0399 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetController.java
@@ -16,7 +16,7 @@
package org.springframework.samples.petclinic.owner;
import java.util.Collection;
-import javax.validation.Valid;
+
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
@@ -29,6 +29,8 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
+import jakarta.validation.Valid;
+
/**
* @author Juergen Hoeller
* @author Ken Krebs
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
index 6f0aa58d3..eeea6a758 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/PetType.java
@@ -15,11 +15,11 @@
*/
package org.springframework.samples.petclinic.owner;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
import org.springframework.samples.petclinic.model.NamedEntity;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+
/**
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
*/
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/Visit.java b/src/main/java/org/springframework/samples/petclinic/owner/Visit.java
index 8d9116533..d052a4e8d 100755
--- a/src/main/java/org/springframework/samples/petclinic/owner/Visit.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/Visit.java
@@ -17,14 +17,14 @@ package org.springframework.samples.petclinic.owner;
import java.time.LocalDate;
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-import javax.validation.constraints.NotEmpty;
-
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.samples.petclinic.model.BaseEntity;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+import jakarta.validation.constraints.NotEmpty;
+
/**
* Simple JavaBean domain object representing a visit.
*
diff --git a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
index 610a3c5b4..c823d91f2 100644
--- a/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
+++ b/src/main/java/org/springframework/samples/petclinic/owner/VisitController.java
@@ -17,8 +17,6 @@ package org.springframework.samples.petclinic.owner;
import java.util.Map;
-import javax.validation.Valid;
-
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
@@ -28,6 +26,8 @@ import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
+import jakarta.validation.Valid;
+
/**
* @author Juergen Hoeller
* @author Ken Krebs
diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java b/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java
index 3a7347f45..b0b6315fc 100644
--- a/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java
+++ b/src/main/java/org/springframework/samples/petclinic/vet/Specialty.java
@@ -15,11 +15,11 @@
*/
package org.springframework.samples.petclinic.vet;
-import javax.persistence.Entity;
-import javax.persistence.Table;
-
import org.springframework.samples.petclinic.model.NamedEntity;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Table;
+
/**
* Models a {@link Vet Vet's} specialty (for example, dentistry).
*
diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java
index 014becfce..7a70155c3 100644
--- a/src/main/java/org/springframework/samples/petclinic/vet/Vet.java
+++ b/src/main/java/org/springframework/samples/petclinic/vet/Vet.java
@@ -21,18 +21,18 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
-import javax.persistence.ManyToMany;
-import javax.persistence.Table;
-import javax.xml.bind.annotation.XmlElement;
-
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.samples.petclinic.model.Person;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.JoinTable;
+import jakarta.persistence.ManyToMany;
+import jakarta.persistence.Table;
+import jakarta.xml.bind.annotation.XmlElement;
+
/**
* Simple JavaBean domain object representing a veterinarian.
*
diff --git a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java
index 961e5c096..9b672d25e 100644
--- a/src/main/java/org/springframework/samples/petclinic/vet/Vets.java
+++ b/src/main/java/org/springframework/samples/petclinic/vet/Vets.java
@@ -15,11 +15,12 @@
*/
package org.springframework.samples.petclinic.vet;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
+import jakarta.xml.bind.annotation.XmlElement;
+import jakarta.xml.bind.annotation.XmlRootElement;
+
/**
* Simple domain object representing a list of veterinarians. Mostly here to be used for
* the 'vets' {@link org.springframework.web.servlet.view.xml.MarshallingView}.
diff --git a/src/main/resources/templates/fragments/layout.html b/src/main/resources/templates/fragments/layout.html
index 5c8d391eb..f58a18c5d 100755
--- a/src/main/resources/templates/fragments/layout.html
+++ b/src/main/resources/templates/fragments/layout.html
@@ -87,7 +87,7 @@
-
+