Skip to content

Complete Spring Boot Migration for faces-example2#9

Open
devin-ai-integration[bot] wants to merge 2 commits intotrunkfrom
devin/1769631824-spring-boot-migration-complete
Open

Complete Spring Boot Migration for faces-example2#9
devin-ai-integration[bot] wants to merge 2 commits intotrunkfrom
devin/1769631824-spring-boot-migration-complete

Conversation

@devin-ai-integration
Copy link

@devin-ai-integration devin-ai-integration bot commented Jan 28, 2026

Summary

This PR completes the Spring Boot migration for apps/faces-example2/ by adding the missing components needed to run the application as a standalone Spring Boot app.

Changes:

  • Added Example2Application.java as the main Spring Boot entry point (renamed from test's TestApplication.java)
  • Expanded DatabaseConfiguration to provide a UserDatabase bean using MemoryUserDatabase, replacing the legacy Struts MemoryDatabasePlugIn
  • Added spring-boot-maven-plugin for executable JAR/WAR packaging
  • Updated application.properties with database path and logging configuration
  • Added WelcomeController to handle root (/), /welcome, and /mainMenu routes

The DatabaseConfiguration handles three scenarios for database initialization:

  1. Load from file path if available
  2. Load from classpath resource (copying to temp file for JAR deployments)
  3. Create sample data if no database.xml is found

Updates Since Last Revision

  • Added WelcomeController.java to provide landing page routes that were missing, enabling the application to serve the welcome page at the root URL

Review & Testing Checklist for Human

  • Verify application starts: Run JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 mvn spring-boot:run and confirm the app starts without errors
  • Test login flow: Navigate to http://localhost:8080 and login with sample credentials (user/pass)
  • Test registration and subscription flows: Create a new user, add/edit/delete subscriptions
  • Review temp file handling: The deleteOnExit() approach in createTempDatabaseFile() may not clean up in all scenarios and data won't persist across restarts

Recommended test plan:

cd apps/faces-example2
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 mvn clean spring-boot:run
# Then navigate to http://localhost:8080 and test the flows

Demo recording of end-to-end testing:

Application testing

View original video (rec-45274a05ba684759a03251e1bb8b7bfd-edited.mp4)

Notes

The sample credentials in createEmptyDatabaseFile() are intentionally hardcoded demo data (matching the original webapp/WEB-INF/database.xml). This is expected for a demo application.

All 80 existing tests pass with these changes.


Link to Devin run: https://jack-meigel.devinenterprise.com/sessions/ed9261f012204fac84a73039ee15f61d
Requested by: Jack Meigel (@cogjack)


Open with Devin

- Add Example2Application.java as the main Spring Boot application class
- Update DatabaseConfiguration to include UserDatabase bean with MemoryUserDatabase
- Add spring-boot-maven-plugin for executable JAR/WAR packaging
- Update application.properties with database configuration
- DatabaseConfiguration creates sample data if database.xml not found on classpath
- Remove duplicate TestApplication.java (now using Example2Application)

The application can now be run with: mvn spring-boot:run

Co-Authored-By: Jack  Meigel <jack.meigel@cognition.ai>
@devin-ai-integration
Copy link
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

- Add WelcomeController to handle / and /welcome routes
- Add mainMenu route for logged-in users
- Completes the Spring Boot migration with proper landing pages

Co-Authored-By: Jack  Meigel <jack.meigel@cognition.ai>
Copy link
Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review


# Database configuration
# Uses the existing database.xml from webapp/WEB-INF for sample data
app.database.path=classpath:database.xml
Copy link
Author

Choose a reason for hiding this comment

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

🟡 Default classpath:database.xml resource does not exist, so configured database path never resolves

The application.properties configures app.database.path=classpath:database.xml, which is injected as a Spring Resource into DatabaseConfiguration.databaseResource. However, there is no database.xml file in src/main/resources/ — the only database.xml is located at src/main/webapp/WEB-INF/database.xml, which is NOT on the classpath.

Root Cause and Impact

Because the resource doesn't exist on the classpath, databaseResource.exists() at DatabaseConfiguration.java:67 always returns false. This means the code always falls through to the else branch at line 78, which logs a warning and creates a hardcoded sample database via createEmptyDatabaseFile().

The comment in application.properties:16 — "Uses the existing database.xml from webapp/WEB-INF for sample data" — is misleading since that file is never actually loaded.

Impact: The first two branches (lines 67-77) of the userDatabase() method are dead code — they can never be reached with the default configuration. Any real database.xml customizations placed in WEB-INF/ will be silently ignored, and users will always get the hardcoded sample data instead of what they expect from the configured path.

Prompt for agents
Copy the database.xml file from apps/faces-example2/src/main/webapp/WEB-INF/database.xml to apps/faces-example2/src/main/resources/database.xml so that the classpath:database.xml resource actually resolves. This ensures the configured app.database.path property works as documented. Alternatively, change the property value in apps/faces-example2/src/main/resources/application.properties line 17 to point to a valid resource location.
Open in Devin Review

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

Comment on lines +60 to +61
@Bean
public UserDatabase userDatabase() throws Exception {
Copy link
Author

Choose a reason for hiding this comment

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

🟡 Database close()/save() called twice on shutdown due to @PreDestroy plus Spring's inferred destroy method

The @PreDestroy cleanup() method at DatabaseConfiguration.java:164 explicitly calls database.close(). However, Spring's @Bean annotation defaults to destroyMethod = "(inferred)", which auto-detects and invokes public no-arg close() or shutdown() methods on returned beans. Since UserDatabase declares public void close() throws Exception (UserDatabase.java:61), Spring will also automatically call close() on the userDatabase bean during shutdown.

Detailed Explanation

This results in MemoryUserDatabase.close() being called twice during application shutdown:

  1. Spring's inferred destroy method calls close() on the userDatabase bean
  2. @PreDestroy cleanup() on DatabaseConfiguration calls database.close() on the same instance

Each close() invocation triggers save() (MemoryUserDatabase.java:106-110), which performs a full file-write-and-rename dance to disk. While the second save() doesn't crash (it's effectively idempotent), it performs unnecessary file I/O during shutdown.

Fix: Either remove the @PreDestroy cleanup() method entirely (relying on Spring's inferred destroy), or annotate the @Bean with an explicit destroyMethod to prevent double invocation, e.g. @Bean(destroyMethod = "close") and remove cleanup(), or @Bean(destroyMethod = "") to disable inference and keep cleanup().

Suggested change
@Bean
public UserDatabase userDatabase() throws Exception {
@Bean(destroyMethod = "")
public UserDatabase userDatabase() throws Exception {
Open in Devin Review

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants