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
42 changes: 42 additions & 0 deletions SPRING_MIGRATION_UNADDRESSED.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Spring Migration Rules - Unaddressed Issues

This document lists issues from the `spring-migration/6` label that were **not addressed** in this PR, along with the reasons.

## Issues Assigned to Other Contributors

The following issues are assigned to other contributors and were skipped to avoid duplication of effort:

| Issue | Title | Assignee | Notes |
|-------|-------|----------|-------|
| #145 | Create rules for EclipseLink | billwheatley | In progress by assignee |
| #152 | Create rules for controller detection | jmle | In progress by assignee |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Self-referential assignee in "Other Contributors" table

Issue #152 lists jmle as the assignee under the "Issues Assigned to Other Contributors" section, but jmle is the author of this very PR. Either this issue is genuinely being deferred (in which case the note should explain why it was skipped despite being self-assigned), or it should be moved to a different category.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SPRING_MIGRATION_UNADDRESSED.md` at line 12, The table row for issue `#152` in
SPRING_MIGRATION_UNADDRESSED.md incorrectly lists the PR author "jmle" under the
"Issues Assigned to Other Contributors" section; either move the row to the
appropriate "Assigned to PR Authors" category or change the assignee and add a
brief explanatory note — update the table entry for issue "#152" (the row with
"Create rules for controller detection") to reflect the correct assignee or add
a parenthetical note like "(self-assigned; deferred — see reason)" so the
listing is not self-referential and the document accurately reflects why it was
skipped or reassigned.


## Issues Already Covered by Existing or New Rules

The following issues are already addressed by rules in this PR or existing rulesets:

| Issue | Title | Covered By |
|-------|-------|------------|
| #133 | Create rule for minimum usage of Java17 and JakartaEE 9+ | Existing baseline rules |
| #136 | Create rules for removed `org.springframework.cache.ehcache` package | removed-apis-00001 |
| #138 | Create rules for bean property determination | core-container-00001 |
| #144 | Create rules for Hibernate Validator upgrade | data-access-00060 (new) |
| #148 | Create rules for backwards compatibility with database-specific error codes | data-access-00030 |
| #151 | Create rules for the trailing slash matching configuration | web-applications-00001 |
| #154 | Create rules for RestTemplate Apache HttpClient 5 requirement | Related to #175 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

"Covered By" entry for #154 is ambiguous

Related to #175`` reads as a cross-reference, not as evidence that #154 is actually covered. Consider replacing this with the specific rule ID that addresses it (e.g., `httpclient-00010` / `web-applications-00020`) so the traceability is unambiguous.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@SPRING_MIGRATION_UNADDRESSED.md` at line 26, The "Covered By" entry for item
`#154` is ambiguous because it uses "Related to `#175`" as a cross-reference; update
the entry for "#154" so it lists the exact rule ID(s) that implement or cover it
(e.g., replace "Related to `#175`" with the concrete rule identifier(s) such as
"httpclient-00010" or "web-applications-00020"), ensuring traceability by
referencing the specific rule ID(s) that address `#154` rather than a generic
related-ticket reference.

| #156 | Create rules for `SourceHttpMessageConverter` | web-applications-00030 |
| #166 | Create rules for migration to Hibernate 5.6 | data-access-00001 |

## Parent/Tracking Issues

| Issue | Title | Notes |
|-------|-------|-------|
| #161 | Support migration of Spring Framework 5->6 | Parent tracking issue - not actionable |

## Summary

- **Total issues with spring-migration/6 label:** 23
- **Issues addressed in this PR:** 11
- **Issues assigned to other contributors:** 2
- **Issues already covered by existing or new rules:** 9
- **Parent/tracking issues:** 1
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,116 @@
- title: 'Spring 6.0 migration guide'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#core-container

- ruleID: spring-framework-5.x-to-6.0-core-container-00040
category: mandatory
effort: 1
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
java.referenced:
pattern: javax.inject.Inject
location: ANNOTATION
Comment on lines +171 to +174

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Detection gap: javax.inject.Named not covered

The when condition only matches javax.inject.Inject at ANNOTATION location, but javax.inject.Named (also moving to jakarta.inject.Named) is called out in the rule message without being detected. Projects that use @Named without @Inject will never be flagged.

Consider extending the when clause to an or block:

🔧 Proposed fix
   when:
-    java.referenced:
-      pattern: javax.inject.Inject
-      location: ANNOTATION
+    or:
+    - java.referenced:
+        pattern: javax.inject.Inject
+        location: ANNOTATION
+    - java.referenced:
+        pattern: javax.inject.Named
+        location: ANNOTATION
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
when:
java.referenced:
pattern: javax.inject.Inject
location: ANNOTATION
when:
or:
- java.referenced:
pattern: javax.inject.Inject
location: ANNOTATION
- java.referenced:
pattern: javax.inject.Named
location: ANNOTATION
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@stable/java/spring-framework/spring-framework-5.x-to-6.0-core-container.yaml`
around lines 171 - 174, The rule's when clause only detects java.referenced
pattern "javax.inject.Inject" at ANNOTATION so usages of "javax.inject.Named"
are missed; update the when block for the rule that checks java.referenced to
include an OR combining patterns for "javax.inject.Inject" and
"javax.inject.Named" (both at location ANNOTATION) so that either annotation
triggers the rule; ensure the unique symbol names "javax.inject.Inject" and
"javax.inject.Named" are added as separate alternatives under the
java.referenced condition.

description: JSR-330 @Inject annotation must be migrated to Jakarta namespace
message: |
The JSR-330 based `@Inject` annotation is to be found in `jakarta.inject` now. The `javax.inject` package
is no longer supported in Spring Framework 6.0 as part of the Jakarta EE 9+ baseline migration.
The corresponding JSR-250 based annotations `@PostConstruct` and `@PreDestroy` are to be found in `jakarta.annotation`.

**Migration Guidance:**

Update your imports from `javax.inject` to `jakarta.inject`:

**Before:**
```java
import javax.inject.Inject;
import javax.inject.Named;

@Named
public class MyService {
@Inject
private MyRepository repository;
}
```

**After:**
```java
import jakarta.inject.Inject;
import jakarta.inject.Named;

@Named
public class MyService {
@Inject
private MyRepository repository;
}
```

**Maven Dependency Update:**
```xml
<!-- Before -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

<!-- After -->
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
<version>2.0.1</version>
</dependency>
```
links:
- title: 'Spring 6.0 migration guide - Core Container'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#core-container

- ruleID: spring-framework-5.x-to-6.0-core-container-00050
category: potential
effort: 2
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
java.referenced:
pattern: org.springframework.core.LocalVariableTableParameterNameDiscoverer
description: LocalVariableTableParameterNameDiscoverer is deprecated in Spring 6
message: |
`LocalVariableTableParameterNameDiscoverer` is deprecated in Spring Framework 6.0 in favor of
`StandardReflectionParameterNameDiscoverer`.

The `LocalVariableTableParameterNameDiscoverer` reads parameter names from the debug information in
class files, which requires classes to be compiled with debug information. The new
`StandardReflectionParameterNameDiscoverer` uses the standard Java reflection API which is more
reliable and doesn't require debug symbols.

**Migration Guidance:**

**Before:**
```java
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;

LocalVariableTableParameterNameDiscoverer discoverer =
new LocalVariableTableParameterNameDiscoverer();
String[] paramNames = discoverer.getParameterNames(method);
```

**After:**
```java
import org.springframework.core.StandardReflectionParameterNameDiscoverer;

StandardReflectionParameterNameDiscoverer discoverer =
new StandardReflectionParameterNameDiscoverer();
String[] paramNames = discoverer.getParameterNames(method);
```

**Note:** Ensure your code is compiled with the `-parameters` flag to retain parameter names
in the bytecode for reflection access.
links:
- title: 'Spring 6.0 migration guide - Core Container'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#core-container

Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,170 @@
links:
- title: 'Spring 6.0 migration guide'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#data-access-and-transactions

- ruleID: spring-framework-5.x-to-6.0-data-access-00040
category: potential
effort: 1
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
or:
- java.referenced:
pattern: org.springframework.dao.CannotSerializeTransactionException
- java.referenced:
pattern: org.springframework.dao.DeadlockLoserDataAccessException
description: Deprecated data access exceptions detected in Spring 6
message: |
`CannotSerializeTransactionException` and `DeadlockLoserDataAccessException` are deprecated as of
Spring Framework 6.0.3 due to their inconsistent JDBC semantics.

**Migration Guidance:**

Replace usage of these deprecated exceptions with the `PessimisticLockingFailureException` base class
or its common `CannotAcquireLockException` subclass, which provides consistent semantics aligned with
JPA/Hibernate in all default exception translation scenarios.

**Before:**
```java
try {
// database operation
} catch (CannotSerializeTransactionException e) {
// handle serialization failure
} catch (DeadlockLoserDataAccessException e) {
// handle deadlock
}
```

**After:**
```java
try {
// database operation
} catch (CannotAcquireLockException e) {
// handle lock acquisition failure (includes serialization and deadlock scenarios)
}
// Or use the base class for broader catch:
catch (PessimisticLockingFailureException e) {
// handle any pessimistic locking failure
}
```
links:
- title: 'Spring 6.0 migration guide - Data Access'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#data-access-and-transactions

- ruleID: spring-framework-5.x-to-6.0-data-access-00050
category: potential
effort: 2
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
or:
- java.referenced:
pattern: org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
- java.referenced:
pattern: org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
- java.referenced:
pattern: org.springframework.jdbc.support.SQLExceptionTranslator
description: JDBC exception translator default has changed in Spring 6
message: |
Spring Framework 6.0 has changed the default JDBC exception translator to `SQLExceptionSubclassTranslator`.
This translator detects JDBC driver subclasses and common SQL state indications without database product
name resolution at runtime.

**Key Changes:**
- Default translator is now `SQLExceptionSubclassTranslator` (JDBC 4 based)
- Common SQL state check for `DuplicateKeyException` is now included
- Database product name resolution is no longer done at runtime by default

**Impact Assessment:**

If your code explicitly uses or extends these classes:
- `SQLStateSQLExceptionTranslator`
- `SQLErrorCodeSQLExceptionTranslator`
- `SQLExceptionTranslator`

Review if the behavior change affects your exception handling logic.

**For backwards compatibility:**
If you need the legacy behavior, explicitly configure `SQLErrorCodeSQLExceptionTranslator`:

```java
@Bean
public SQLExceptionTranslator exceptionTranslator(DataSource dataSource) {
return new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
```
links:
- title: 'Spring 6.0 migration guide - Data Access'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#data-access-and-transactions

- ruleID: spring-framework-5.x-to-6.0-data-access-00060
category: mandatory
effort: 3
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
or:
- java.dependency:
name: org.hibernate.validator.hibernate-validator
upperbound: 6.99.99
- java.referenced:
pattern: javax.validation*
location: IMPORT
description: Hibernate Validator must be upgraded to 7.0+ for Spring 6
Comment on lines +307 to +323

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid duplicate Hibernate Validator upgrade incidents.

Rule 00060 overlaps existing 00010 on dependency-based detection, which can emit duplicate findings and conflicting guidance paths for the same project.

🔧 Proposed narrowing for 00060
-  when:
-    or:
-    - java.dependency:
-        name: org.hibernate.validator.hibernate-validator
-        upperbound: 6.99.99
-    - java.referenced:
-        pattern: javax.validation*
-        location: IMPORT
+  when:
+    java.referenced:
+      pattern: javax.validation.*
+      location: IMPORT
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- ruleID: spring-framework-5.x-to-6.0-data-access-00060
category: mandatory
effort: 3
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
or:
- java.dependency:
name: org.hibernate.validator.hibernate-validator
upperbound: 6.99.99
- java.referenced:
pattern: javax.validation*
location: IMPORT
description: Hibernate Validator must be upgraded to 7.0+ for Spring 6
- ruleID: spring-framework-5.x-to-6.0-data-access-00060
category: mandatory
effort: 3
labels:
- konveyor.io/source=spring5
- konveyor.io/target=spring6+
- konveyor.io/source=spring-boot2
- konveyor.io/target=spring-boot3+
when:
java.referenced:
pattern: javax.validation.*
location: IMPORT
description: Hibernate Validator must be upgraded to 7.0+ for Spring 6
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@stable/java/spring-framework/spring-framework-5.x-to-6.0-data-access.yaml`
around lines 307 - 323, The rule ruleID
spring-framework-5.x-to-6.0-data-access-00060 currently duplicates rule 00010 by
checking the same dependency; update rule 00060's when clause to avoid overlap
by removing or narrowing the dependency-based trigger (the java.dependency block
for org.hibernate.validator.hibernate-validator) and keep only the import-based
detection (the java.referenced pattern javax.validation* with location IMPORT),
or alternatively add a negation so 00060 only fires when java.dependency does
NOT match the vulnerable range; reference ruleID
spring-framework-5.x-to-6.0-data-access-00060 and the java.dependency /
java.referenced conditions when making the change.

message: |
Spring Framework 6.0 requires Hibernate Validator 7.0.x or later due to the Jakarta EE 9+ baseline.
Hibernate Validator 7.0 is the first version to use the `jakarta.validation` namespace instead of
`javax.validation`.

**Migration Guidance:**

**Update Dependencies:**
```xml
<!-- Remove Hibernate Validator 6.x -->
<!-- <dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.x.x</version>
</dependency> -->

<!-- Add Hibernate Validator 7.0+ -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.5.Final</version>
</dependency>
```

**Update Imports:**
```java
// Before
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

// After
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
```

**Key Changes in Hibernate Validator 7.0:**
- All `javax.validation.*` → `jakarta.validation.*`
- `javax.el` → `jakarta.el` for Expression Language
- Compatible with Jakarta EE 9+
links:
- title: 'Spring 6.0 migration guide - Data Access and Transactions'
url: https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-6.0-Release-Notes#data-access-and-transactions
- title: 'Hibernate Validator 7.0 Release Announcement'
url: https://in.relation.to/2020/12/08/hibernate-validator-700-62-cr1-released/
- title: 'Hibernate Validator Migration Guide'
url: https://hibernate.org/validator/documentation/migration-guide/
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# RestTemplate / HttpComponentsClientHttpRequestFactory now requires Apache HttpClient 5.
# That case is covered by spring-framework-5.x-to-6.0-web-applications-00020 in
# spring-framework-5.x-to-6.0-web-applications.yaml (see PR #174).
[]
Loading
Loading