Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
/.idea/
/.idea/
target/
build/
.gradle/
1 change: 0 additions & 1 deletion .gitignore.txt

This file was deleted.

2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,24 @@ In addition, it uses


## Getting Started

Requires a locally installed JDK 17 (the Gradle build pins a Java 17 toolchain and no toolchain resolver is configured, so it will not download one).

1) Download or clone the project with link
(https://github.com/RehmanMuradAli/springboot-java8/)

2) Build and run with Maven
```
./mvnw clean package
java -jar target/gs-spring-boot-0.1.0.jar
```

or with Gradle
```
./gradlew clean bootJar
java -jar build/libs/gs-spring-boot-0.1.0.jar
```

## Available API's

Greetings
Expand Down Expand Up @@ -76,7 +91,7 @@ GET /datetime

### Prerequisites

1) Java sdk
1) JDK 17
2) POSTMAN

### Installing
Expand Down Expand Up @@ -126,6 +141,7 @@ https://dzone.com/articles/java-8-friday-goodies-new-new
## Built With

* [Maven](https://maven.apache.org/) - Dependency Management
* [Gradle](https://gradle.org/) - Alternative build, kept in sync with the Maven build

## Authors

Expand Down
1 change: 0 additions & 1 deletion application.properties

This file was deleted.

25 changes: 18 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ buildscript {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.2.RELEASE")
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.7.18")
classpath("io.spring.gradle:dependency-management-plugin:1.0.15.RELEASE")
}
}

Expand All @@ -14,19 +15,29 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
baseName = 'gs-spring-boot'
version = '0.1.0'
archiveBaseName = 'gs-spring-boot'
archiveVersion = '0.1.0'
}

repositories {
mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

tasks.withType(JavaCompile) {
options.release = 17
Comment on lines +26 to +33

@devin-ai-integration devin-ai-integration Bot Jul 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Gradle toolchain requires a locally installed JDK 17

The java.toolchain block plus options.release = 17 means Gradle will fail with a toolchain-resolution error on machines without a JDK 17 installed, since no toolchain resolver plugin is configured. This is documented in the README, but it makes the Gradle build stricter than the Maven build, which compiles with whatever JDK runs Maven as long as it supports --release 17.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented in 8255bf2: the README's Prerequisites now say JDK 17 (it said "Java sdk"), Getting Started calls out that the Gradle toolchain will not download a JDK because no resolver is configured, and both the Maven and Gradle build/run command pairs are listed. Kept the toolchain block rather than adding foojay-resolver — failing loudly with "No matching toolchains found" is better than silently compiling against whatever JDK happens to be on PATH, and options.release = 17 alone would not pin the JVM that runs the build.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, and intended: I'd rather the Gradle build refuse to run on a wrong JDK than compile with whatever is on PATH. Note Maven isn't as loose as it looks either — --release 17 fails outright on a JDK older than 17, so the practical difference is only that Maven tolerates a newer JDK while Gradle pins exactly 17.

}

dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
testCompile("junit:junit")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-jdbc")
runtimeOnly("com.h2database:h2")
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
testImplementation("junit:junit")
Comment on lines +37 to +41

@devin-ai-integration devin-ai-integration Bot Jul 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: properties-migrator kept on the runtime classpath in both builds

spring-boot-properties-migrator is intended as a temporary, single-upgrade aid and Spring's docs recommend removing it once the migration is done; it adds startup cost and log noise on every run. Now that the upgrade reports no renamed/removed properties, both the Maven runtime dependency and this new Gradle runtimeOnly entry could be dropped.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aligned in 20c978f: added runtimeOnly("org.springframework.boot:spring-boot-properties-migrator") to build.gradle, so both jars now report renamed/removed properties. Keeping the migrator for this PR is deliberate — it's the only signal available for Boot 2.0 -> 2.7 property renames in a repo with no tests; dropping it is a sensible follow-up once the upgrade has been exercised. The h2 scope difference is intentional and not a behavioural divergence: Maven's h2 is compile-scope only because that's what the original pom had, and nothing in the source references H2 classes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scopes now match exactly: h2 is <scope>runtime</scope> in the pom as of 2f4e18f, mirroring Gradle's runtimeOnly. Rebuilt and re-booted the Maven jar — GET / and the H2 table creation/insert/query still work, confirming nothing referenced H2 at compile time.

On the migrator: agreed it's temporary, and I'd remove it in a follow-up rather than here. This repo has no tests and no CI, so a startup report of renamed/removed properties is the only regression signal available while the Boot 2.0 -> 2.7 jump is being reviewed; dropping it in the same PR would remove that signal before anyone has exercised the upgrade.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Position unchanged from my earlier reply in this thread: the migrator stays for this PR and comes out in a follow-up. "Reports no renamed properties" is only true for the paths I exercised by hand — with no tests and no CI, a reviewer running this branch is the next chance to catch a rename, and removing the migrator now removes that chance.

}

2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.4-bin.zip
Empty file modified gradlew
100644 → 100755
Empty file.
Empty file modified mvnw
100644 → 100755
Empty file.
10 changes: 7 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

<groupId>org.springframework</groupId>
<artifactId>gs-spring-boot</artifactId>
<packaging>pom</packaging>
<packaging>jar</packaging>
<version>0.1.0</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<version>2.7.18</version>
</parent>

<dependencies>
Expand All @@ -31,11 +31,15 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<properties>
<java.version>1.8</java.version>
<java.version>17</java.version>
<maven.compiler.release>17</maven.compiler.release>
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<maven-surefire-plugin.version>3.5.6</maven-surefire-plugin.version>
Comment on lines +41 to +42

@devin-ai-integration devin-ai-integration Bot Jul 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Overridden plugin versions rely on parent property names

maven-compiler-plugin.version and maven-surefire-plugin.version only take effect because spring-boot-dependencies parameterises its pluginManagement with exactly those property names; if a future parent upgrade renames them the overrides silently become no-ops (the build would just use the parent's pinned versions). Also, with maven.compiler.release=17 set alongside the parent-derived source/target from java.version, release wins and source/target are ignored — harmless but redundant.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed effective, not inert. mvn help:effective-pom on this branch resolves maven-compiler-plugin to 3.13.0 and maven-surefire-plugin to 3.5.6 in both pluginManagement and build/plugins (parent 2.7.18 pins 3.10.1 / 2.22.2), so the property names match what spring-boot-dependencies parameterises.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping both. java.version is the property spring-boot-starter-parent documents, so it's what a reader (and any Boot tooling) expects to find; maven.compiler.release is the one that actually gives --release 17, which the parent has no property for. The redundancy is intentional rather than accidental. Agreed a future parent could rename the plugin-version properties — that's a general property-inheritance risk with spring-boot-starter-parent and would surface as the parent's pinned versions being used, not as a build failure.

</properties>


Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'gs-spring-boot'
27 changes: 17 additions & 10 deletions src/main/java/hello/Application.java

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Legacy H2 DDL kept intentionally, but H2 2.x compatibility is version-fragile

DROP TABLE customers IF EXISTS (trailing form) and the SERIAL type are legacy H2 grammar; they still parse in H2 2.1.x (managed by Boot 2.7.18) as the PR describes, but they are not standard and would break on a future H2 major bump. Modernising to DROP TABLE IF EXISTS customers and id IDENTITY/BIGINT AUTO_INCREMENT would remove that coupling to the managed H2 version.

(Refers to lines 72-73)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left as-is deliberately. The point of the H2 note in the description is that the legacy grammar still parses on the version Boot 2.7.18 manages (2.1.214) — verified at runtime here. Modernising the DDL is a good follow-up but is a source change unrelated to the Java/Boot upgrade, so I'd rather it not ride along in this PR.

Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class Application implements CommandLineRunner {

private static final Logger log = LoggerFactory.getLogger(Application.class);

private static final String QUOTE_URL = "http://gturnquist-quoters.cfapps.io/api/random";

public static void main(String[] args) {

ApplicationContext ctx = SpringApplication.run(Application.class, args);
Expand All @@ -35,9 +38,16 @@ public static void main(String[] args) {
System.out.println(beanName);
}

RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
logRandomQuote(new RestTemplate());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Quote is still fetched twice per startup

The quote is fetched once from the CommandLineRunner bean (with the builder-configured RestTemplate) and again from main() with a freshly constructed new RestTemplate(). This duplication is pre-existing, but now that both paths funnel through logRandomQuote, the dead host will produce two WARN lines on every start. Consolidating on the injected RestTemplate (and dropping the call in main) would be cleaner. Note also that Application itself implements CommandLineRunner (src/main/java/hello/Application.java:23) while also exposing a second CommandLineRunner bean named run, which is confusing but functional.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing duplication, left as-is: both call sites are demo code from the original Spring guide, and consolidating them changes runtime behaviour (one fewer startup fetch) beyond the scope of a version upgrade. Worth noting the second WARN is now visible only because the host is dead; when the endpoint worked, both paths logged a quote. Happy to collapse main()'s call and the redundant run bean into the existing CommandLineRunner implementation if the repo owner wants it.

}

private static void logRandomQuote(RestTemplate restTemplate) {
try {
Quote quote = restTemplate.getForObject(QUOTE_URL, Quote.class);
log.info(String.valueOf(quote));
} catch (RestClientException e) {
log.warn("Could not fetch a quote from {}: {}", QUOTE_URL, e.getMessage());
}
}


Expand All @@ -48,11 +58,7 @@ public RestTemplate restTemplate(RestTemplateBuilder builder) {

@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
return args -> logRandomQuote(restTemplate);
Comment on lines 59 to +61

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Two CommandLineRunner beans still run in an unspecified order

Application both implements CommandLineRunner (JDBC demo) and exposes a second CommandLineRunner bean (run(RestTemplate)). Neither is annotated with @Order, so ordering is unspecified; this is unchanged by the PR but worth noting since the quote runner is now the only place that swallows network failures — the JDBC runner still aborts startup on any SQL error.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing, unchanged, and left alone. The @Order gap doesn't matter here: the two runners share no state, one seeds an in-memory H2 table and the other logs a quote. The asymmetry you point out is deliberate — the quote fetch depends on a third-party host that no longer exists, so it must not be fatal, whereas a SQL failure against the embedded H2 the app just provisioned is a real defect and should still abort startup.

}


Expand Down Expand Up @@ -80,8 +86,9 @@ public void run(String... args) throws Exception {

log.info("Querying for customer records where first_name = 'Josh':");
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[]{"Josh"},
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?",
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name")),
"Josh"
).forEach(customer -> log.info(customer.toString()));

}
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#server.port=8081
Binary file removed target/classes/hello/Application.class
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed target/classes/hello/declaration/CustomPredicate.class
Binary file not shown.
Binary file removed target/classes/hello/declaration/TimeClient.class
Binary file not shown.
Binary file removed target/classes/hello/model/Customer.class
Binary file not shown.
Binary file removed target/classes/hello/model/Greeting.class
Binary file not shown.
Binary file removed target/classes/hello/model/Quote.class
Binary file not shown.
Binary file removed target/classes/hello/model/SimpleTimeClient.class
Binary file not shown.
Binary file removed target/classes/hello/model/Topic.class
Binary file not shown.
Binary file removed target/classes/hello/model/Value.class
Binary file not shown.
Binary file removed target/classes/hello/service/TopicService.class
Binary file not shown.
10 changes: 0 additions & 10 deletions target/classes/public/index.html

This file was deleted.