| # Jetty 12 Migration Guide | |
| ## Overview | |
| Apache Drill has been upgraded from Jetty 9 to Jetty 12 to address security vulnerabilities and maintain compatibility with modern Java versions. | |
| ## What Changed | |
| ### Core API Changes | |
| 1. **Servlet API Migration**: `javax.servlet.*` → `jakarta.servlet.*` | |
| 2. **Package Restructuring**: Servlet components moved to `org.eclipse.jetty.ee10.servlet.*` | |
| 3. **Handler API Redesign**: New `org.eclipse.jetty.server.Handler` interface | |
| 4. **Authentication APIs**: New `LoginService.login()` and authenticator signatures | |
| ### Modified Files | |
| #### Key Changes | |
| - **WebServer.java**: Updated resource loading, handler configuration, and security handler setup | |
| - **DrillHttpSecurityHandlerProvider.java**: Refactored from `Handler.Wrapper` to extend `ee10.servlet.security.ConstraintSecurityHandler` for proper session management | |
| - **DrillSpnegoAuthenticator.java**: Updated to Jetty 12 APIs with new `validateRequest(Request, Response, Callback)` signature | |
| - **DrillSpnegoLoginService.java**: Updated `login()` method signature | |
| - **DrillErrorHandler.java**: Migrated to use `generateAcceptableResponse()` for content negotiation | |
| - **YARN WebServer.java**: Updated for Jetty 12 APIs and `IdentityService.newUserIdentity()` | |
| #### Authentication Architecture | |
| The authentication system was redesigned for Jetty 12: | |
| - **DrillHttpSecurityHandlerProvider** now extends `ConstraintSecurityHandler` (previously `Handler.Wrapper`) | |
| - Implements a `RoutingAuthenticator` that delegates to child authenticators (SPNEGO, FORM, BASIC) | |
| - Handles session caching manually since delegated authenticators require explicit session management | |
| - Properly integrated with `ServletContextHandler` via `setSecurityHandler()` | |
| ## Known Limitations | |
| ### Hadoop MiniDFSCluster Test Incompatibility | |
| **Issue**: Tests using Hadoop's MiniDFSCluster cannot run due to Jetty version conflicts (Hadoop 3.x uses Jetty 9). | |
| **Affected Tests** (temporarily disabled): | |
| - `TestImpersonationDisabledWithMiniDFS.java` | |
| - `TestImpersonationMetadata.java` | |
| - `TestImpersonationQueries.java` | |
| - `TestInboundImpersonation.java` | |
| **Resolution**: Tests will be re-enabled when Apache Hadoop 4.x or a Hadoop 3.x maintenance release upgrades to Jetty 12 (tracked in [HADOOP-19625](https://issues.apache.org/jira/browse/HADOOP-19625)). | |
| ## Developer Guidelines | |
| ### Writing New Web Server Code | |
| 1. Use Jakarta EE 10 imports: | |
| ```java | |
| import jakarta.servlet.http.HttpServletRequest; | |
| import org.eclipse.jetty.ee10.servlet.ServletContextHandler; | |
| ``` | |
| 2. Use Jetty constants: | |
| ```java | |
| import org.eclipse.jetty.security.Authenticator; | |
| String authMethod = Authenticator.SPNEGO_AUTH; // Not "SPNEGO" | |
| ``` | |
| 3. For custom error handling, use `generateAcceptableResponse()`: | |
| ```java | |
| @Override | |
| protected void generateAcceptableResponse(ServletContextRequest baseRequest, | |
| HttpServletRequest request, | |
| HttpServletResponse response, | |
| int code, String message, | |
| String contentType) { | |
| // Use contentType parameter, not request path | |
| } | |
| ``` | |
| ### Writing Authentication Code | |
| When implementing custom authenticators: | |
| 1. Extend `LoginAuthenticator` and implement `validateRequest(Request, Response, Callback)` | |
| 2. Use `Request.as(request, ServletContextRequest.class)` to access servlet APIs from core Request | |
| 3. Return `AuthenticationState` (CHALLENGE, SEND_SUCCESS, or UserAuthenticationSucceeded) | |
| 4. Use `Response.writeError()` to properly send challenges with callback completion | |
| Example: | |
| ```java | |
| public class CustomAuthenticator extends LoginAuthenticator { | |
| @Override | |
| public AuthenticationState validateRequest(Request request, Response response, Callback callback) { | |
| ServletContextRequest servletRequest = Request.as(request, ServletContextRequest.class); | |
| // ... authentication logic ... | |
| if (authFailed) { | |
| response.getHeaders().put(HttpHeader.WWW_AUTHENTICATE, "Bearer"); | |
| Response.writeError(request, response, callback, HttpStatus.UNAUTHORIZED_401); | |
| return AuthenticationState.CHALLENGE; | |
| } | |
| return new UserAuthenticationSucceeded(getAuthenticationType(), userIdentity); | |
| } | |
| } | |
| ``` | |
| ### Writing Tests | |
| 1. **Use integration tests**: Test with real Drill server and `OkHttpClient`, not mocked servlets | |
| ```java | |
| public class MyWebTest extends ClusterTest { | |
| @Test | |
| public void testEndpoint() throws Exception { | |
| String url = String.format("http://localhost:%d/api/endpoint", port); | |
| Request request = new Request.Builder().url(url).build(); | |
| try (Response response = httpClient.newCall(request).execute()) { | |
| assertEquals(200, response.code()); | |
| } | |
| } | |
| } | |
| ``` | |
| 2. **Avoid MiniDFSCluster** in tests that start Drill's HTTP server | |
| 3. **Session cookie names**: Tests should accept both "JSESSIONID" and "Drill-Session-Id" | |
| ## Dependency Management | |
| Drill's parent POM includes the Jetty 12 BOM: | |
| ```xml | |
| <dependencyManagement> | |
| <dependencies> | |
| <dependency> | |
| <groupId>org.eclipse.jetty</groupId> | |
| <artifactId>jetty-bom</artifactId> | |
| <version>12.0.16</version> | |
| <type>pom</type> | |
| <scope>import</scope> | |
| </dependency> | |
| </dependencies> | |
| </dependencyManagement> | |
| ``` | |
| ## Migration Checklist for Future Updates | |
| - [ ] Update Jetty BOM version in parent POM | |
| - [ ] Run full test suite including integration tests | |
| - [ ] Verify checkstyle compliance | |
| - [ ] Check HADOOP-19625 status for MiniDFSCluster test re-enablement | |
| - [ ] Update this document with any new changes | |
| ## References | |
| - [Jetty 12 Migration Guide](https://eclipse.dev/jetty/documentation/jetty-12/migration-guide/index.html) | |
| - [Jakarta EE 10 Documentation](https://jakarta.ee/specifications/platform/10/) | |
| - [HADOOP-19625: Upgrade Jetty to 12.x](https://issues.apache.org/jira/browse/HADOOP-19625) |