Repository: jhipster/jhipster-lite (java)

Issue:
Replace `gradleapp` with `fullapp` at `github-actions.yml`, using Gradle build tool, and improve generated code
Since Gradle is now fully supported, the temporary `gradleapp` will be removed. To achieve this, the code generated by the command `./tests-ci/generate.sh fullapp gradle yaml` must function correctly, pass SonarQube checks, and maintain high code quality.

To see the steps I need to take to accomplish this (WIP), please [check out this pull request](https://github.com/renanfranca/fullapp-gradle/pull/1/files).

TO-DO:

- [x] Fix checkstyle error at `RestBeer.java` and `Beer.java` in the used by `SampleFeatureModuleFactory.java`
- [x] `CucumberTest` isn't being executed. Change the `build.gradle.kts` template
- [x] JacocoModuleFactory: Fix deprecated `buildDir` use, must use `layout.buildDirectory` instead
- [x] `/.gradle/` add to `.gitignore` in the `gradle-java` module
- [x] Add `/buildSrc/.gradle/` and `/buildSrc/build/` in the spring-boot-local-profile module
- [ ] Remove `gradleapp` from `generate.sh`
- [x] Replace `gradleapp` with `fullapp` at `/.github/workflows/github-actions.yml`

Wish list:
- [x] Add `spring-boot-local-profile` at `fullapp`
- [x] Improve sonar plugin gradle configuration by using `import java.util.Properties`

Pull request:
fix and improve code generated by fullapp using gradle and replace gradleapp with fullapp at ci
See #9849 

Patch:
diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml
index 6ba6ba0a3..d1819e766 100644
--- a/.github/workflows/github-actions.yml
+++ b/.github/workflows/github-actions.yml
@@ -255,7 +255,7 @@ jobs:
             java-version: 22
           - app: vueapp
             node-version: 'latest'
-          - app: gradleapp
+          - app: fullapp
             java-build-tool: gradle
     steps:
       - name: 'Setup: checkout project from main branch'
diff --git a/src/main/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactory.java
index c1933a866..ec619c385 100644
--- a/src/main/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactory.java
@@ -23,6 +23,7 @@ public class GradleModuleFactory {
         .and()
       .gitIgnore()
         .comment("Gradle")
+        .pattern("/.gradle/")
         .pattern("/build/")
         .and()
       .files()
diff --git a/src/main/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactory.java
index 1d4b3a602..23966ae3a 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactory.java
@@ -164,7 +164,7 @@ public class JacocoModuleFactory {
             xml.required.set(true)
             html.required.set(true)
           }
-          executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+          executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
         }
         """
       )
@@ -187,7 +187,7 @@ public class JacocoModuleFactory {
             xml.required.set(true)
             html.required.set(true)
           }
-          executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+          executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
         }
 
         tasks.jacocoTestCoverageVerification {
@@ -210,7 +210,7 @@ public class JacocoModuleFactory {
                   }
               }
           }
-          executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+          executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
         }
         """
       )
diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactory.java b/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactory.java
index a5dbb3b01..5e6f6660f 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactory.java
@@ -103,22 +103,16 @@ public class SonarQubeModulesFactory {
   private GradleMainBuildPlugin gradleSonarPlugin() {
     String configuration =
       """
-      fun loadSonarProperties(): Map<String, List<String>> {
-          val properties = mutableMapOf<String, List<String>>()
-          File("sonar-project.properties").forEachLine { line ->
-              if (!line.startsWith("#") && line.contains("=")) {
-                  val (key, value) = line.split("=", limit = 2)
-                  properties[key.trim()] = value.split(",").map { it.trim() }
-              }
-          }
-          return properties
+      val sonarProperties = Properties()
+      File("sonar-project.properties").inputStream().use { inputStream ->
+          sonarProperties.load(inputStream)
       }
 
       sonarqube {
           properties {
-            loadSonarProperties().forEach { (key, value) ->
-              property(key, value)
-            }
+            sonarProperties
+              .map { it -> it.key as String to (it.value as String).split(",").map { it.trim() } }
+              .forEach { (key, values) -> property(key, values) }
             property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml")
             property("sonar.junit.reportPaths", "build/test-results/test,build/test-results/integrationTest")
           }
@@ -129,6 +123,7 @@ public class SonarQubeModulesFactory {
       .id("org.sonarqube")
       .pluginSlug(SONARQUBE)
       .versionSlug(SONARQUBE)
+      .withBuildGradleImport("java.util.Properties")
       .configuration(configuration)
       .build();
   }
diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactory.java
index db34bd4e6..fd0852ee3 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactory.java
@@ -21,6 +21,11 @@ public class LocalProfileModuleFactory {
 
     //@formatter:off
     return moduleBuilder(properties)
+      .gitIgnore()
+        .comment("Gradle")
+        .pattern("./buildSrc/.gradle/")
+        .pattern("./buildSrc/build/")
+        .and()
       .javaBuildProperties()
         .set(new PropertyKey(SPRING_PROFILES_ACTIVE), new PropertyValue(""))
         .and()
diff --git a/src/main/resources/generator/buildtool/gradle/build.gradle.kts.mustache b/src/main/resources/generator/buildtool/gradle/build.gradle.kts.mustache
index 4212b1de5..6f5e6de1a 100644
--- a/src/main/resources/generator/buildtool/gradle/build.gradle.kts.mustache
+++ b/src/main/resources/generator/buildtool/gradle/build.gradle.kts.mustache
@@ -54,7 +54,6 @@ val integrationTest = task<Test>("integrationTest") {
   filter {
     includeTestsMatching("**IT*")
     includeTestsMatching("**CucumberTest*")
-    excludeTestsMatching("**Test*")
   }
   useJUnitPlatform()
 }
diff --git a/src/main/resources/generator/server/springboot/mvc/sample/feature/main/domain/beer/Beer.java.mustache b/src/main/resources/generator/server/springboot/mvc/sample/feature/main/domain/beer/Beer.java.mustache
index 5cea321cc..7ae245ce6 100644
--- a/src/main/resources/generator/server/springboot/mvc/sample/feature/main/domain/beer/Beer.java.mustache
+++ b/src/main/resources/generator/server/springboot/mvc/sample/feature/main/domain/beer/Beer.java.mustache
@@ -54,7 +54,7 @@ public final class Beer {
     return sellingState;
   }
 
-  private static class BeerBuilder
+  private static final class BeerBuilder
     implements BeerIdBuilder, BeerNameBuilder, BeerUnitPriceBuilder, BeerSellStateBuilder, BeerOptionalBuilder {
 
     private BeerId id;
diff --git a/src/main/resources/generator/server/springboot/mvc/sample/feature/main/infrastructure/primary/beer/RestBeer.java.mustache b/src/main/resources/generator/server/springboot/mvc/sample/feature/main/infrastructure/primary/beer/RestBeer.java.mustache
index baec3959d..f8534c827 100644
--- a/src/main/resources/generator/server/springboot/mvc/sample/feature/main/infrastructure/primary/beer/RestBeer.java.mustache
+++ b/src/main/resources/generator/server/springboot/mvc/sample/feature/main/infrastructure/primary/beer/RestBeer.java.mustache
@@ -42,7 +42,7 @@ final class RestBeer {
     return unitPrice;
   }
 
-  private static class RestBeerBuilder {
+  private static final class RestBeerBuilder {
 
     private UUID id;
     private String name;


Test patch:
diff --git a/src/test/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactoryTest.java
index c4ee0c886..eb60c9c2a 100644
--- a/src/test/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/buildtool/gradle/domain/GradleModuleFactoryTest.java
@@ -28,6 +28,7 @@ class GradleModuleFactoryTest {
       .containing(
         """
         # Gradle
+        /.gradle/
         /build/\
         """
       )
diff --git a/src/test/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactoryTest.java
index 76af50239..403695f63 100644
--- a/src/test/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/server/javatool/jacoco/domain/JacocoModuleFactoryTest.java
@@ -174,7 +174,7 @@ class JacocoModuleFactoryTest {
               xml.required.set(true)
               html.required.set(true)
             }
-            executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+            executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
           }
           """
         )
@@ -216,7 +216,7 @@ class JacocoModuleFactoryTest {
             xml.required.set(true)
             html.required.set(true)
           }
-          executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+          executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
         }
 
         tasks.jacocoTestCoverageVerification {
@@ -239,7 +239,7 @@ class JacocoModuleFactoryTest {
                   }
               }
           }
-          executionData.setFrom(fileTree(buildDir).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
+          executionData.setFrom(fileTree(layout.buildDirectory).include("**/jacoco/test.exec", "**/jacoco/integrationTest.exec"))
         }
         """
       )
diff --git a/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactoryTest.java
index 25c573868..5761a290f 100644
--- a/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModulesFactoryTest.java
@@ -167,6 +167,12 @@ class SonarQubeModulesFactoryTest {
         )
         .and()
         .hasFile("build.gradle.kts")
+        .containing(
+          """
+          import java.util.Properties
+          // jhipster-needle-gradle-imports\
+          """
+        )
         .containing(
           """
             alias(libs.plugins.sonarqube)
@@ -175,22 +181,16 @@ class SonarQubeModulesFactoryTest {
         )
         .containing(
           """
-          fun loadSonarProperties(): Map<String, List<String>> {
-              val properties = mutableMapOf<String, List<String>>()
-              File("sonar-project.properties").forEachLine { line ->
-                  if (!line.startsWith("#") && line.contains("=")) {
-                      val (key, value) = line.split("=", limit = 2)
-                      properties[key.trim()] = value.split(",").map { it.trim() }
-                  }
-              }
-              return properties
+          val sonarProperties = Properties()
+          File("sonar-project.properties").inputStream().use { inputStream ->
+              sonarProperties.load(inputStream)
           }
 
           sonarqube {
               properties {
-                loadSonarProperties().forEach { (key, value) ->
-                  property(key, value)
-                }
+                sonarProperties
+                  .map { it -> it.key as String to (it.value as String).split(",").map { it.trim() } }
+                  .forEach { (key, values) -> property(key, values) }
                 property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml")
                 property("sonar.junit.reportPaths", "build/test-results/test,build/test-results/integrationTest")
               }
diff --git a/src/test/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactoryTest.java
index 75299e549..b5f64dfa2 100644
--- a/src/test/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/server/springboot/localeprofile/domain/LocalProfileModuleFactoryTest.java
@@ -109,6 +109,15 @@ class LocalProfileModuleFactoryTest {
       JHipsterModule module = factory.buildModule(properties);
 
       assertThatModuleWithFiles(module, gradleBuildFile(), gradleLibsVersionFile())
+        .hasFile(".gitignore")
+        .containing(
+          """
+          # Gradle
+          ./buildSrc/.gradle/
+          ./buildSrc/build/\
+          """
+        )
+        .and()
         .hasFile("build.gradle.kts")
         .containing(
           """
diff --git a/src/test/resources/projects/empty-gradle/build.gradle.kts b/src/test/resources/projects/empty-gradle/build.gradle.kts
index 53ea9b616..0555f64b0 100644
--- a/src/test/resources/projects/empty-gradle/build.gradle.kts
+++ b/src/test/resources/projects/empty-gradle/build.gradle.kts
@@ -55,7 +55,6 @@ val integrationTest = task<Test>("integrationTest") {
   filter {
     includeTestsMatching("**IT*")
     includeTestsMatching("**CucumberTest*")
-    excludeTestsMatching("**Test*")
   }
   useJUnitPlatform()
 }
diff --git a/src/test/resources/projects/gradle-with-properties/build.gradle.kts b/src/test/resources/projects/gradle-with-properties/build.gradle.kts
index 464c7cbe4..f23b1c109 100644
--- a/src/test/resources/projects/gradle-with-properties/build.gradle.kts
+++ b/src/test/resources/projects/gradle-with-properties/build.gradle.kts
@@ -51,7 +51,6 @@ val integrationTest = task<Test>("integrationTest") {
   filter {
     includeTestsMatching("**IT*")
     includeTestsMatching("**CucumberTest*")
-    excludeTestsMatching("**Test*")
   }
   useJUnitPlatform()
 }
diff --git a/src/test/resources/projects/init-gradle/build.gradle.kts b/src/test/resources/projects/init-gradle/build.gradle.kts
index 87594d2d1..209760c06 100644
--- a/src/test/resources/projects/init-gradle/build.gradle.kts
+++ b/src/test/resources/projects/init-gradle/build.gradle.kts
@@ -55,7 +55,6 @@ val integrationTest = task<Test>("integrationTest") {
   filter {
     includeTestsMatching("**IT*")
     includeTestsMatching("**CucumberTest*")
-    excludeTestsMatching("**Test*")
   }
   useJUnitPlatform()
 }
diff --git a/tests-ci/generate.sh b/tests-ci/generate.sh
index 169b6607b..683dd5e08 100755
--- a/tests-ci/generate.sh
+++ b/tests-ci/generate.sh
@@ -172,6 +172,7 @@ elif [[ $application == 'fullapp' ]]; then
   "gitpod" \
   "java-memoizers" \
   "java-enums" \
+  "spring-boot-local-profile" \
   "internationalized-errors" \
   "spring-boot-cache" \
   "caffeine-cache" \