|
| 1 | +# Migration Guide |
| 2 | + |
| 3 | +This guide covers migrating applications using the Spring User Framework between major versions. |
| 4 | + |
| 5 | +## Table of Contents |
| 6 | + |
| 7 | +- [Migration Guide](#migration-guide) |
| 8 | + - [Table of Contents](#table-of-contents) |
| 9 | + - [Migrating to 4.0.x (Spring Boot 4.0)](#migrating-to-40x-spring-boot-40) |
| 10 | + - [Prerequisites](#prerequisites) |
| 11 | + - [Step 1: Update Java Version](#step-1-update-java-version) |
| 12 | + - [Step 2: Update Dependencies](#step-2-update-dependencies) |
| 13 | + - [Step 3: Spring Security 7 Changes](#step-3-spring-security-7-changes) |
| 14 | + - [URL Pattern Requirements](#url-pattern-requirements) |
| 15 | + - [Security Configuration Changes](#security-configuration-changes) |
| 16 | + - [Step 4: Update Test Infrastructure](#step-4-update-test-infrastructure) |
| 17 | + - [Test Dependency Changes](#test-dependency-changes) |
| 18 | + - [Test Annotation Import Changes](#test-annotation-import-changes) |
| 19 | + - [Step 5: Jackson 3 Changes](#step-5-jackson-3-changes) |
| 20 | + - [Step 6: API Changes](#step-6-api-changes) |
| 21 | + - [Profile Update Endpoint](#profile-update-endpoint) |
| 22 | + - [Step 7: Configuration Changes](#step-7-configuration-changes) |
| 23 | + - [For Developers Extending the Framework](#for-developers-extending-the-framework) |
| 24 | + - [Extending Security Configuration](#extending-security-configuration) |
| 25 | + - [Custom User Services](#custom-user-services) |
| 26 | + - [Custom Controllers](#custom-controllers) |
| 27 | + - [Event Listeners](#event-listeners) |
| 28 | + - [Troubleshooting](#troubleshooting) |
| 29 | + - [Common Issues](#common-issues) |
| 30 | + - [Version Compatibility Matrix](#version-compatibility-matrix) |
| 31 | + |
| 32 | +## Migrating to 4.0.x (Spring Boot 4.0) |
| 33 | + |
| 34 | +This section covers migrating from Spring User Framework 3.x (Spring Boot 3.x) to 4.x (Spring Boot 4.0). |
| 35 | + |
| 36 | +### Prerequisites |
| 37 | + |
| 38 | +Before starting the migration: |
| 39 | + |
| 40 | +1. Ensure your application is running on the latest 3.5.x version |
| 41 | +2. Review your custom security configurations |
| 42 | +3. Audit any code that extends framework classes |
| 43 | +4. Back up your database (schema changes are minimal but recommended) |
| 44 | + |
| 45 | +### Step 1: Update Java Version |
| 46 | + |
| 47 | +**Spring Boot 4.0 requires Java 21 or higher.** |
| 48 | + |
| 49 | +Update your build configuration: |
| 50 | + |
| 51 | +**Gradle:** |
| 52 | +```groovy |
| 53 | +java { |
| 54 | + toolchain { |
| 55 | + languageVersion = JavaLanguageVersion.of(21) |
| 56 | + } |
| 57 | +} |
| 58 | +``` |
| 59 | + |
| 60 | +**Maven:** |
| 61 | +```xml |
| 62 | +<properties> |
| 63 | + <java.version>21</java.version> |
| 64 | +</properties> |
| 65 | +``` |
| 66 | + |
| 67 | +Ensure your CI/CD pipelines and deployment environments support Java 21. |
| 68 | + |
| 69 | +### Step 2: Update Dependencies |
| 70 | + |
| 71 | +Update the framework dependency version: |
| 72 | + |
| 73 | +**Gradle:** |
| 74 | +```groovy |
| 75 | +implementation 'com.digitalsanctuary:ds-spring-user-framework:4.0.0' |
| 76 | +``` |
| 77 | + |
| 78 | +**Maven:** |
| 79 | +```xml |
| 80 | +<dependency> |
| 81 | + <groupId>com.digitalsanctuary</groupId> |
| 82 | + <artifactId>ds-spring-user-framework</artifactId> |
| 83 | + <version>4.0.0</version> |
| 84 | +</dependency> |
| 85 | +``` |
| 86 | + |
| 87 | +Update Spring Boot: |
| 88 | +```groovy |
| 89 | +plugins { |
| 90 | + id 'org.springframework.boot' version '4.0.0' |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +### Step 3: Spring Security 7 Changes |
| 95 | + |
| 96 | +Spring Boot 4.0 includes Spring Security 7, which has breaking changes from Spring Security 6.x. |
| 97 | + |
| 98 | +#### URL Pattern Requirements |
| 99 | + |
| 100 | +**All URL patterns must now start with `/`.** |
| 101 | + |
| 102 | +This affects: |
| 103 | +- `user.security.unprotectedURIs` configuration |
| 104 | +- `user.security.protectedURIs` configuration |
| 105 | +- Any custom security matchers in your code |
| 106 | + |
| 107 | +**Before (3.x):** |
| 108 | +```yaml |
| 109 | +user: |
| 110 | + security: |
| 111 | + unprotectedURIs: /,/index.html,/css/**,/js/**,error,error.html |
| 112 | +``` |
| 113 | +
|
| 114 | +**After (4.x):** |
| 115 | +```yaml |
| 116 | +user: |
| 117 | + security: |
| 118 | + unprotectedURIs: /,/index.html,/css/**,/js/**,/error,/error.html |
| 119 | +``` |
| 120 | +
|
| 121 | +Note the `/error` and `/error.html` now have leading slashes. |
| 122 | + |
| 123 | +#### Security Configuration Changes |
| 124 | + |
| 125 | +If you have custom security configuration extending or working with the framework: |
| 126 | + |
| 127 | +**Deprecated methods removed:** |
| 128 | +- `authorizeRequests()` → use `authorizeHttpRequests()` |
| 129 | +- `antMatchers()` → use `requestMatchers()` |
| 130 | +- `mvcMatchers()` → use `requestMatchers()` |
| 131 | + |
| 132 | +**Example migration:** |
| 133 | + |
| 134 | +```java |
| 135 | +// Before (3.x) |
| 136 | +http.authorizeRequests() |
| 137 | + .antMatchers("/public/**").permitAll() |
| 138 | + .anyRequest().authenticated(); |
| 139 | +
|
| 140 | +// After (4.x) |
| 141 | +http.authorizeHttpRequests(authz -> authz |
| 142 | + .requestMatchers("/public/**").permitAll() |
| 143 | + .anyRequest().authenticated()); |
| 144 | +``` |
| 145 | + |
| 146 | +### Step 4: Update Test Infrastructure |
| 147 | + |
| 148 | +Spring Boot 4.0 introduces modular test packages. |
| 149 | + |
| 150 | +#### Test Dependency Changes |
| 151 | + |
| 152 | +Add the new modular test starters: |
| 153 | + |
| 154 | +**Gradle:** |
| 155 | +```groovy |
| 156 | +testImplementation 'org.springframework.boot:spring-boot-starter-test' |
| 157 | +testImplementation 'org.springframework.boot:spring-boot-data-jpa-test' |
| 158 | +testImplementation 'org.springframework.boot:spring-boot-webmvc-test' |
| 159 | +testImplementation 'org.springframework.boot:spring-boot-starter-security-test' |
| 160 | +testImplementation 'org.springframework.security:spring-security-test' |
| 161 | +``` |
| 162 | + |
| 163 | +**Maven:** |
| 164 | +```xml |
| 165 | +<dependency> |
| 166 | + <groupId>org.springframework.boot</groupId> |
| 167 | + <artifactId>spring-boot-data-jpa-test</artifactId> |
| 168 | + <scope>test</scope> |
| 169 | +</dependency> |
| 170 | +<dependency> |
| 171 | + <groupId>org.springframework.boot</groupId> |
| 172 | + <artifactId>spring-boot-webmvc-test</artifactId> |
| 173 | + <scope>test</scope> |
| 174 | +</dependency> |
| 175 | +``` |
| 176 | + |
| 177 | +#### Test Annotation Import Changes |
| 178 | + |
| 179 | +Update imports for test annotations: |
| 180 | + |
| 181 | +| Annotation | Old Package (3.x) | New Package (4.x) | |
| 182 | +|------------|-------------------|-------------------| |
| 183 | +| `@AutoConfigureMockMvc` | `org.springframework.boot.test.autoconfigure.web.servlet` | `org.springframework.boot.webmvc.test.autoconfigure` | |
| 184 | +| `@WebMvcTest` | `org.springframework.boot.test.autoconfigure.web.servlet` | `org.springframework.boot.webmvc.test.autoconfigure` | |
| 185 | +| `@DataJpaTest` | `org.springframework.boot.test.autoconfigure.orm.jpa` | `org.springframework.boot.data.jpa.test.autoconfigure` | |
| 186 | +| `@AutoConfigureTestDatabase` | `org.springframework.boot.test.autoconfigure.jdbc` | `org.springframework.boot.jdbc.test.autoconfigure` | |
| 187 | + |
| 188 | +**Example:** |
| 189 | +```java |
| 190 | +// Before (3.x) |
| 191 | +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; |
| 192 | +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; |
| 193 | +
|
| 194 | +// After (4.x) |
| 195 | +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; |
| 196 | +import org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest; |
| 197 | +``` |
| 198 | + |
| 199 | +### Step 5: Jackson 3 Changes |
| 200 | + |
| 201 | +Spring Boot 4.0 uses Jackson 3.x for JSON processing. |
| 202 | + |
| 203 | +**ObjectMapper instantiation:** |
| 204 | +```java |
| 205 | +// Before (Jackson 2.x) |
| 206 | +ObjectMapper mapper = new ObjectMapper(); |
| 207 | +
|
| 208 | +// After (Jackson 3.x) |
| 209 | +ObjectMapper mapper = JsonMapper.builder().build(); |
| 210 | +``` |
| 211 | + |
| 212 | +**Package changes:** |
| 213 | +- Some classes moved from `com.fasterxml.jackson` to new packages |
| 214 | +- Check any custom serializers/deserializers |
| 215 | + |
| 216 | +### Step 6: API Changes |
| 217 | + |
| 218 | +#### Profile Update Endpoint |
| 219 | + |
| 220 | +The `/user/updateUser` endpoint now accepts `UserProfileUpdateDto` instead of `UserDto`. |
| 221 | + |
| 222 | +**Before (3.x):** |
| 223 | +```json |
| 224 | +POST /user/updateUser |
| 225 | +{ |
| 226 | + "email": "user@example.com", |
| 227 | + "firstName": "John", |
| 228 | + "lastName": "Doe", |
| 229 | + "password": "...", |
| 230 | + "matchingPassword": "..." |
| 231 | +} |
| 232 | +``` |
| 233 | + |
| 234 | +**After (4.x):** |
| 235 | +```json |
| 236 | +POST /user/updateUser |
| 237 | +{ |
| 238 | + "firstName": "John", |
| 239 | + "lastName": "Doe" |
| 240 | +} |
| 241 | +``` |
| 242 | + |
| 243 | +This change improves security by not requiring password fields for profile updates. |
| 244 | + |
| 245 | +**Update your frontend code** if you're calling this endpoint directly. |
| 246 | + |
| 247 | +### Step 7: Configuration Changes |
| 248 | + |
| 249 | +Review your `application.yml` for any deprecated properties: |
| 250 | + |
| 251 | +| Deprecated Property | Replacement | |
| 252 | +|---------------------|-------------| |
| 253 | +| (none currently) | - | |
| 254 | + |
| 255 | +Most configuration properties remain unchanged between 3.x and 4.x. |
| 256 | + |
| 257 | +## For Developers Extending the Framework |
| 258 | + |
| 259 | +If you've extended framework classes or implemented custom functionality, review these sections carefully. |
| 260 | + |
| 261 | +### Extending Security Configuration |
| 262 | + |
| 263 | +If you have a custom `WebSecurityConfig` or extend the framework's security configuration: |
| 264 | + |
| 265 | +1. **Ensure all URL patterns start with `/`** |
| 266 | +2. **Update to lambda DSL style** (required in Spring Security 7) |
| 267 | +3. **Review method security annotations** - `@PreAuthorize`, `@PostAuthorize` unchanged |
| 268 | + |
| 269 | +**Example custom security configuration:** |
| 270 | +```java |
| 271 | +@Configuration |
| 272 | +@EnableWebSecurity |
| 273 | +public class CustomSecurityConfig { |
| 274 | +
|
| 275 | + @Bean |
| 276 | + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
| 277 | + http |
| 278 | + .authorizeHttpRequests(authz -> authz |
| 279 | + // All patterns must start with / |
| 280 | + .requestMatchers("/api/public/**").permitAll() |
| 281 | + .requestMatchers("/api/admin/**").hasRole("ADMIN") |
| 282 | + .anyRequest().authenticated() |
| 283 | + ) |
| 284 | + .formLogin(form -> form |
| 285 | + .loginPage("/user/login.html") |
| 286 | + .permitAll() |
| 287 | + ); |
| 288 | + return http.build(); |
| 289 | + } |
| 290 | +} |
| 291 | +``` |
| 292 | + |
| 293 | +### Custom User Services |
| 294 | + |
| 295 | +If you extend `UserService` or implement custom user management: |
| 296 | + |
| 297 | +1. **Method signatures unchanged** - Core service methods remain compatible |
| 298 | +2. **Password encoding** - Still uses BCrypt, no changes required |
| 299 | +3. **User entity** - No schema changes required |
| 300 | + |
| 301 | +### Custom Controllers |
| 302 | + |
| 303 | +If you have controllers that extend or work alongside framework controllers: |
| 304 | + |
| 305 | +1. **DTOs** - Update any code using `UserDto` for profile updates to use `UserProfileUpdateDto` |
| 306 | +2. **Validation** - Bean validation works the same way |
| 307 | +3. **Response format** - `JSONResponse` unchanged |
| 308 | + |
| 309 | +### Event Listeners |
| 310 | + |
| 311 | +Event handling remains unchanged: |
| 312 | + |
| 313 | +- `OnRegistrationCompleteEvent` |
| 314 | +- `UserPreDeleteEvent` |
| 315 | +- `AuditEvent` |
| 316 | + |
| 317 | +All events fire as before with the same payload structures. |
| 318 | + |
| 319 | +## Troubleshooting |
| 320 | + |
| 321 | +### Common Issues |
| 322 | + |
| 323 | +**Issue: `pattern must start with a /`** |
| 324 | + |
| 325 | +This error occurs when URL patterns in security configuration don't start with `/`. |
| 326 | + |
| 327 | +**Solution:** Review all entries in: |
| 328 | +- `user.security.unprotectedURIs` |
| 329 | +- `user.security.protectedURIs` |
| 330 | +- Any custom `requestMatchers()` calls |
| 331 | + |
| 332 | +Ensure every pattern starts with `/`. |
| 333 | + |
| 334 | +--- |
| 335 | + |
| 336 | +**Issue: `ClassNotFoundException` for test annotations** |
| 337 | + |
| 338 | +Spring Boot 4.0 moved test annotations to new packages. |
| 339 | + |
| 340 | +**Solution:** |
| 341 | +1. Add the modular test dependencies (see [Step 4](#step-4-update-test-infrastructure)) |
| 342 | +2. Update imports to new package locations |
| 343 | + |
| 344 | +--- |
| 345 | + |
| 346 | +**Issue: `NoClassDefFoundError: com/fasterxml/jackson/...`** |
| 347 | + |
| 348 | +Jackson 3 has different package structures. |
| 349 | + |
| 350 | +**Solution:** Update ObjectMapper instantiation and check custom serializers. |
| 351 | + |
| 352 | +--- |
| 353 | + |
| 354 | +**Issue: Profile update returns validation error for password** |
| 355 | + |
| 356 | +The `/user/updateUser` endpoint now uses `UserProfileUpdateDto`. |
| 357 | + |
| 358 | +**Solution:** Update your frontend to only send `firstName` and `lastName` fields. |
| 359 | + |
| 360 | +--- |
| 361 | + |
| 362 | +**Issue: Java version incompatibility** |
| 363 | + |
| 364 | +Spring Boot 4.0 requires Java 21. |
| 365 | + |
| 366 | +**Solution:** |
| 367 | +1. Update your JDK to 21+ |
| 368 | +2. Update build configuration |
| 369 | +3. Update CI/CD pipelines |
| 370 | +4. Update deployment environments |
| 371 | + |
| 372 | +## Version Compatibility Matrix |
| 373 | + |
| 374 | +| Framework Version | Spring Boot | Spring Security | Java | Status | |
| 375 | +|-------------------|-------------|-----------------|------|--------| |
| 376 | +| 4.0.x | 4.0.x | 7.x | 21+ | Current | |
| 377 | +| 3.5.x | 3.5.x | 6.x | 17+ | Maintained | |
| 378 | +| 3.4.x | 3.4.x | 6.x | 17+ | Security fixes only | |
| 379 | +| < 3.4 | < 3.4 | < 6 | 17+ | End of life | |
| 380 | + |
| 381 | +--- |
| 382 | + |
| 383 | +For additional help, see: |
| 384 | +- [README](README.md) - Main documentation |
| 385 | +- [Configuration Guide](CONFIG.md) - All configuration options |
| 386 | +- [Demo Application](https://github.com/devondragon/SpringUserFrameworkDemoApp) - Working example |
| 387 | +- [GitHub Issues](https://github.com/devondragon/SpringUserFramework/issues) - Report problems |
0 commit comments