Apache Drill has been upgraded from Jetty 9 to Jetty 12 to address security vulnerabilities and maintain compatibility with modern Java versions.
javax.servlet.* → jakarta.servlet.*org.eclipse.jetty.ee10.servlet.*org.eclipse.jetty.server.Handler interfaceLoginService.login() and authenticator signaturesHandler.Wrapper to extend ee10.servlet.security.ConstraintSecurityHandler for proper session managementvalidateRequest(Request, Response, Callback) signaturelogin() method signaturegenerateAcceptableResponse() for content negotiationIdentityService.newUserIdentity()The authentication system was redesigned for Jetty 12:
ConstraintSecurityHandler (previously Handler.Wrapper)RoutingAuthenticator that delegates to child authenticators (SPNEGO, FORM, BASIC)ServletContextHandler via setSecurityHandler()Issue: Tests using Hadoop's MiniDFSCluster cannot run due to Jetty version conflicts (Hadoop 3.x uses Jetty 9).
Affected Tests (temporarily disabled):
TestImpersonationDisabledWithMiniDFS.javaTestImpersonationMetadata.javaTestImpersonationQueries.javaTestInboundImpersonation.javaResolution: 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).
Use Jakarta EE 10 imports:
import jakarta.servlet.http.HttpServletRequest; import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
Use Jetty constants:
import org.eclipse.jetty.security.Authenticator; String authMethod = Authenticator.SPNEGO_AUTH; // Not "SPNEGO"
For custom error handling, use generateAcceptableResponse():
@Override protected void generateAcceptableResponse(ServletContextRequest baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message, String contentType) { // Use contentType parameter, not request path }
When implementing custom authenticators:
LoginAuthenticator and implement validateRequest(Request, Response, Callback)Request.as(request, ServletContextRequest.class) to access servlet APIs from core RequestAuthenticationState (CHALLENGE, SEND_SUCCESS, or UserAuthenticationSucceeded)Response.writeError() to properly send challenges with callback completionExample:
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); } }
Use integration tests: Test with real Drill server and OkHttpClient, not mocked servlets
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()); } } }
Avoid MiniDFSCluster in tests that start Drill's HTTP server
Session cookie names: Tests should accept both “JSESSIONID” and “Drill-Session-Id”
Drill's parent POM includes the Jetty 12 BOM:
<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>