SavitarC opened a new issue, #16387:
URL: https://github.com/apache/dubbo/issues/16387

   ### Pre-check
   
   - [x] I am sure that all the content I provide is in English.
   
   
   ### Search before asking
   
   - [x] I had searched in the 
[issues](https://github.com/apache/dubbo/issues?q=is%3Aissue) and found no 
similar issues.
   
   
   ### Apache Dubbo Component
   
   Java SDK (apache/dubbo)
   
   ### Dubbo Version
   
   Apache Dubbo: 3.3 branch
   Verified commit: d0bf5c36d092da8067b15a1d1d00884a8c399e8e
   Project version: 3.3.7-SNAPSHOT
   
   JDK: OpenJDK 17.0.19
   Spring Framework: 6.2.18
   Operating system: Ubuntu 24.04
   
   ### Steps to reproduce this issue
   
   The `dubbo-rest-spring` module still uses `javax.servlet` types, while the 
corresponding Spring Framework 6 APIs use `jakarta.servlet` types.
   
   The problem can be reproduced independently at both the source-compilation 
stage and the published-artifact consumption stage.
   
   ### 1. Mini reproduction using the published artifacts
   
   Download the attached reproduction:
   
   
[dubbo-rest-spring-actual-repro.zip](https://github.com/user-attachments/files/30163504/dubbo-rest-spring-actual-repro.zip)
   
   This reproduction uses the actual Maven Central artifacts rather than 
locally reimplemented adapters:
   
   ```text
   org.apache.dubbo:dubbo-rest-spring:3.3.6
   org.apache.dubbo:dubbo-triple-servlet:3.3.6
   Spring Framework 5.3.39 and 6.2.18
   ```
   
   Run it with:
   
   ```bash
   unzip dubbo-rest-spring-actual-repro.zip
   cd dubbo-rest-spring-actual-repro
   ./run-reproduction.sh
   ```
   
   The script downloads the exact artifacts from Maven Central, verifies their 
published SHA-1 values, and performs six checks:
   
   1. It extracts the real `HandlerInterceptorAdapter.java` and 
`SpringMiscArgumentResolver.java` from the published `dubbo-rest-spring:3.3.6` 
sources jar.
   2. The extracted sources compile successfully against Spring Framework 
5.3.39.
   3. The same sources fail against Spring Framework 6.2.18 at the four 
reported locations:
   
      * `HandlerInterceptorAdapter.java:71`
      * `HandlerInterceptorAdapter.java:85`
      * `HandlerInterceptorAdapter.java:92`
      * `SpringMiscArgumentResolver.java:58`
   4. A Spring Framework 6 consumer of the published `dubbo-rest-spring` binary 
compiles successfully.
   5. Passing Dubbo's real Jakarta `ServletHttpRequestAdapter` to the real 
`HandlerInterceptorAdapter` fails at line 71 because the adapter casts it to 
`javax.servlet.http.HttpServletRequest`.
   6. Passing Dubbo's real javax request implementation reaches the Spring API 
boundary and produces the expected linkage failures:
   
   ```text
   java.lang.NoSuchMethodError:
     HandlerInterceptor.preHandle(
       javax.servlet.http.HttpServletRequest,
       javax.servlet.http.HttpServletResponse,
       java.lang.Object)
     at HandlerInterceptorAdapter.java:71
   ```
   
   and:
   
   ```text
   java.lang.NoSuchMethodError:
     ServletWebRequest.<init>(
       javax.servlet.http.HttpServletRequest)
     at SpringMiscArgumentResolver.java:58
   ```
   
   The runtime output also verifies that the affected classes were loaded from 
`dubbo-rest-spring-3.3.6.jar` and that the request implementations were loaded 
from `dubbo-triple-servlet-3.3.6.jar`.
   
   Both Servlet APIs are deliberately present in the demo so that it can 
distinguish the cast failure from the deeper Spring method-descriptor 
incompatibility. On a Jakarta-only Spring Boot 3 classpath, the same 
integration may fail earlier with a missing-class error.
   
   ### 2. Repository reactor reproduction
   
   From the Dubbo repository root at commit 
d0bf5c36d092da8067b15a1d1d00884a8c399e8e, run:
   
   ```bash
   ./mvnw -P spring-6 \
     -pl dubbo-plugin/dubbo-rest-spring \
     -am \
     -Dspring-6.version=6.2.18 \
     -Dmaven.test.skip=true \
     -Dcheckstyle.skip=true \
     -Drat.skip=true \
     install
   ```
   
   Tests and selected quality checks are skipped only to isolate main-source 
compilation. This does not bypass or hide the reported failure.
   
   The command selects 54 reactor modules:
   
   * the first 53 modules succeed;
   * `dubbo-rest-spring [54/54]` fails while compiling its main sources;
   * the final result is `BUILD FAILURE`.
   
   The relevant compilation errors are:
   
   ```text
   HandlerInterceptorAdapter.java:[71,27] cannot access HttpServletRequest
     class file for jakarta.servlet.http.HttpServletRequest not found
   
   HandlerInterceptorAdapter.java:[85,35] incompatible types:
     javax.servlet.http.HttpServletRequest cannot be converted to
     jakarta.servlet.http.HttpServletRequest
   
   HandlerInterceptorAdapter.java:[92,40] incompatible types:
     javax.servlet.http.HttpServletRequest cannot be converted to
     jakarta.servlet.http.HttpServletRequest
   
   SpringMiscArgumentResolver.java:[58,41] incompatible types:
     javax.servlet.http.HttpServletRequest cannot be converted to
     jakarta.servlet.http.HttpServletRequest
   ```
   
   All four source locations are reproducible.
   
   Because the attached mini reproduction deliberately provides both Servlet 
API jars, its Spring Framework 6 compilation reports line 71 as another 
explicit `javax.servlet` to `jakarta.servlet` incompatible-types error instead 
of a missing `jakarta.servlet` class. The underlying incompatibility is the 
same.
   
   ### What you expected to happen
   
   The module set selected by the existing `spring-6` profile should be 
compilable against Spring Framework 6.
   
   The `dubbo-rest-spring` integration should either provide a Spring Framework 
6 compatible implementation using the Jakarta Servlet API, or clearly exclude 
this integration from the Spring Framework 6 compatibility scope with the 
limitation documented explicitly.
   
   The existing Spring Framework 5 / `javax.servlet` behavior and artifact 
compatibility should remain unchanged.
   
   ### Anything else
   
   ## Discovery context
   
   I found this issue while validating Apache Dubbo compatibility with Spring 
Boot 4 and its Spring Framework 7 baseline.
   
   As a compatibility baseline, I checked the repository's existing Spring 
Framework 6 build path first. Spring Framework 6 is the first Spring Framework 
major version that uses the Jakarta Servlet API, and the Dubbo repository 
already provides a `spring-6` Maven profile.
   
   Validating this baseline helps distinguish a pre-existing `javax.servlet` / 
`jakarta.servlet` compatibility gap from a regression introduced specifically 
by Spring Framework 7 or Spring Boot 4.
   
   This check showed that `dubbo-rest-spring` already fails to compile against 
Spring Framework 6.2.18 because it passes `javax.servlet` types to Spring APIs 
that require `jakarta.servlet` types.
   
   Therefore, although the issue was discovered during Spring Boot 4 
compatibility work, it is not specific to Spring Boot 4. It is independently 
reproducible with:
   
   ```text
   Spring Framework 6.2.18
   Apache Dubbo 3.3
   ```
   
   It can consequently also affect Spring Boot 3 applications that explicitly 
use this REST Spring MVC integration.
   
   The same incompatibility is relevant to Spring Boot 4 / Spring Framework 7, 
because Spring Framework 7 also uses the Jakarta Servlet API and does not 
restore the old `javax.servlet` method descriptors.
   
   ## Root-cause observation
   
   The `dubbo-rest-spring` POM currently declares:
   
   ```xml
   <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <scope>provided</scope>
   </dependency>
   ```
   
   The following classes directly use
   `javax.servlet.http.HttpServletRequest`:
   
   - 
`org.apache.dubbo.rpc.protocol.tri.rest.support.spring.HandlerInterceptorAdapter`
   - 
`org.apache.dubbo.rpc.protocol.tri.rest.support.spring.SpringMiscArgumentResolver`
   
   `HandlerInterceptorAdapter` passes `javax.servlet` request and response 
objects to these Spring MVC methods:
   
   ```text
   HandlerInterceptor.preHandle(...)
   HandlerInterceptor.postHandle(...)
   HandlerInterceptor.afterCompletion(...)
   ```
   
   `SpringMiscArgumentResolver` passes a 
`javax.servlet.http.HttpServletRequest` to:
   
   ```text
   ServletWebRequest(...)
   ```
   
   With Spring Framework 5, the relevant Spring APIs use:
   
   ```text
   javax.servlet.http.HttpServletRequest
   javax.servlet.http.HttpServletResponse
   ```
   
   With Spring Framework 6, the Spring class names remain largely unchanged, 
but the corresponding JVM method and constructor descriptors use:
   
   ```text
   jakarta.servlet.http.HttpServletRequest
   jakarta.servlet.http.HttpServletResponse
   ```
   
   A `javax.servlet.http.HttpServletRequest` is therefore not assignable to the 
Spring Framework 6 API parameter `jakarta.servlet.http.HttpServletRequest`.
   
   This is a compile-time API incompatibility, not only a difference in Maven 
dependency names.
   
   ## Impact scope
   
   Confirmed impact:
   
   - building `org.apache.dubbo:dubbo-rest-spring` sources against Spring 
Framework 6;
   - Spring Boot 3 applications that use the affected Dubbo Triple REST Spring 
MVC adapter paths;
   - repository reactor builds that include `dubbo-rest-spring` when the 
existing `spring-6` profile is enabled.
   
   The same incompatibility is also a compatibility blocker for users planning 
to continue using this integration with Spring Boot 4 / Spring Framework 7.
   
   This report does not claim that every Spring Boot starter user is affected. 
The regular Spring Boot starter does not directly depend on 
`dubbo-rest-spring`. The primary affected users are applications that 
explicitly enable or depend on the REST Spring MVC integration and use the 
affected adapter paths.
   
   ## Compatibility constraints
   
   The current implementation remains valid for Spring Framework 5 and 
`javax.servlet`.
   
   A fix should therefore preserve the following compatibility boundaries:
   
   - existing Spring Framework 5 users continue to receive the `javax.servlet`  
implementation;
   - the existing artifact should not be silently changed into a Jakarta-only  
artifact;
   - Spring Framework 6/7 support should not break the existing Java 8 / Spring 
 Framework 5 build path.
   
   ## Possible solution directions
   
   Possible directions include:
   
   1. introducing a separate Spring Framework 6 / Jakarta REST Spring adapter 
artifact;
   2. extracting code that does not depend on the Servlet namespace and keeping 
thin Spring 5/`javax` and Spring 6/`jakarta` adapters;
   3. explicitly declaring this integration unsupported on Spring Framework 
6/7, excluding the legacy module from that reactor, and documenting the 
limitation.
   
   Maintainer guidance would be appreciated on:
   
   - whether Dubbo intends to continue supporting the Triple REST Spring MVC 
adapters on Spring Framework 6/7;
   - whether the preferred strategy is a separate artifact or shared code with 
version-specific adapters;
   - how Spring Framework 5 and Spring Framework 6 artifacts should be selected 
without breaking existing users.
   
   ### Do you have a (mini) reproduction demo?
   
   - [x] Yes, I have a minimal reproduction demo to help resolve this issue 
more effectively!
   
   ### Are you willing to submit a pull request to fix on your own?
   
   - [ ] Yes I am willing to submit a pull request on my own!
   
   ### Code of Conduct
   
   - [x] I agree to follow this project's [Code of 
Conduct](https://www.apache.org/foundation/policies/conduct)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to