You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/09/19 17:18:52 UTC
(maven-project-info-reports-plugin) branch master updated: Replace the Jetty 6 test server with the JDK HTTP server
This is an automated email from the ASF dual-hosted git repository.
slachiewicz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-project-info-reports-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new 59dea5d Replace the Jetty 6 test server with the JDK HTTP server
59dea5d is described below
commit 59dea5df90c7296bacf9389ec71b9b0b616992c6
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Sat Sep 19 18:42:33 2026 +0200
Replace the Jetty 6 test server with the JDK HTTP server
org.mortbay.jetty:jetty:6.1.26 (2010) is the last release of that
coordinate and has no upgrade path (#652). The only consumer is the
fixture in ProjectInfoReportUtilsTest, which needs plain HTTP, HTTPS and
basic auth; com.sun.net.httpserver covers all three on Java 8.
---
pom.xml | 8 +-
.../projectinfo/ProjectInfoReportUtilsTest.java | 159 +++++++++++----------
src/test/resources/realm.properties | 19 ---
3 files changed, 84 insertions(+), 102 deletions(-)
diff --git a/pom.xml b/pom.xml
index a7fa81b..96f4012 100644
--- a/pom.xml
+++ b/pom.xml
@@ -323,12 +323,6 @@ under the License.
<version>4.11.0</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>jetty</artifactId>
- <version>6.1.26</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-impl</artifactId>
@@ -401,7 +395,7 @@ under the License.
</plugins>
</pluginManagement>
<plugins>
- <!-- To use Jetty SSL in tests -->
+ <!-- Key pair for the HTTPS server in ProjectInfoReportUtilsTest -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>keytool-maven-plugin</artifactId>
diff --git a/src/test/java/org/apache/maven/report/projectinfo/ProjectInfoReportUtilsTest.java b/src/test/java/org/apache/maven/report/projectinfo/ProjectInfoReportUtilsTest.java
index 244f8c1..8cc9c10 100644
--- a/src/test/java/org/apache/maven/report/projectinfo/ProjectInfoReportUtilsTest.java
+++ b/src/test/java/org/apache/maven/report/projectinfo/ProjectInfoReportUtilsTest.java
@@ -18,9 +18,26 @@
*/
package org.apache.maven.report.projectinfo;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+
import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
import java.net.URL;
-
+import java.nio.file.Files;
+import java.security.KeyStore;
+
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import com.sun.net.httpserver.HttpsConfigurator;
+import com.sun.net.httpserver.HttpsServer;
import org.apache.maven.model.DeploymentRepository;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
@@ -28,17 +45,6 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Handler;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.handler.DefaultHandler;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.security.Constraint;
-import org.mortbay.jetty.security.ConstraintMapping;
-import org.mortbay.jetty.security.HashUserRealm;
-import org.mortbay.jetty.security.SecurityHandler;
-import org.mortbay.jetty.security.SslSocketConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
import static org.apache.maven.api.plugin.testing.MojoExtension.getBasedir;
import static org.apache.maven.report.projectinfo.ProjectInfoReportUtils.getArchiveServer;
@@ -52,13 +58,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
* @version $Id$
*/
class ProjectInfoReportUtilsTest {
- private static final int MAX_IDLE_TIME = 30000;
-
private int port = -1;
private Settings settingsStub;
- private Server jettyServer;
+ private HttpServer httpServer;
@BeforeEach
void setUp() throws Exception {
@@ -108,7 +112,7 @@ class ProjectInfoReportUtilsTest {
assertTrue(content.contains("Свобода всем народам!"));
// http + no auth
- startJetty(false, false);
+ startServer(false, false);
url = new URL("http://localhost:" + port + "/project-info-reports.properties");
@@ -116,10 +120,10 @@ class ProjectInfoReportUtilsTest {
assertNotNull(content);
assertTrue(content.contains("Licensed to the Apache Software Foundation"));
- stopJetty();
+ stopServer();
// http + auth
- startJetty(false, true);
+ startServer(false, true);
url = new URL("http://localhost:" + port + "/project-info-reports.properties");
@@ -127,10 +131,10 @@ class ProjectInfoReportUtilsTest {
assertNotNull(content);
assertTrue(content.contains("Licensed to the Apache Software Foundation"));
- stopJetty();
+ stopServer();
// https + no auth
- startJetty(true, false);
+ startServer(true, false);
url = new URL("https://localhost:" + port + "/project-info-reports.properties");
@@ -138,10 +142,10 @@ class ProjectInfoReportUtilsTest {
assertNotNull(content);
assertTrue(content.contains("Licensed to the Apache Software Foundation"));
- stopJetty();
+ stopServer();
// https + auth
- startJetty(true, true);
+ startServer(true, true);
url = new URL("https://localhost:" + port + "/project-info-reports.properties");
@@ -149,7 +153,7 @@ class ProjectInfoReportUtilsTest {
assertNotNull(content);
assertTrue(content.contains("Licensed to the Apache Software Foundation"));
- stopJetty();
+ stopServer();
// TODO need to test with a proxy
}
@@ -191,72 +195,75 @@ class ProjectInfoReportUtilsTest {
assertEquals("maven.announce.markmail.org", getArchiveServer("http://maven.announce.markmail.org"));
}
- private void startJetty(boolean isSSL, boolean withAuth) throws Exception {
- jettyServer = new Server();
- jettyServer.setStopAtShutdown(true);
-
- Connector connector = (isSSL ? getSSLConnector() : getDefaultConnector());
- jettyServer.setConnectors(new Connector[] {connector});
-
- WebAppContext webapp = new WebAppContext();
- webapp.setContextPath("/");
- webapp.setResourceBase(getBasedir() + "/target/classes/");
+ /**
+ * Starts a local server on an ephemeral port that serves the files under {@code target/classes}, the same
+ * document root the Jetty fixture used before, optionally over TLS with the key pair that
+ * {@code keytool-maven-plugin} generates at {@code target/jetty.jks} and optionally behind basic auth for
+ * the {@code admin} user that {@link #setUp()} puts into the settings stub.
+ */
+ private void startServer(boolean isSSL, boolean withAuth) throws Exception {
+ InetSocketAddress address = new InetSocketAddress("localhost", 0);
+ if (isSSL) {
+ HttpsServer httpsServer = HttpsServer.create(address, 0);
+ httpsServer.setHttpsConfigurator(new HttpsConfigurator(createSslContext()));
+ httpServer = httpsServer;
+ } else {
+ httpServer = HttpServer.create(address, 0);
+ }
- webapp.setServer(jettyServer);
+ final File documentRoot = new File(getBasedir(), "target/classes");
+ HttpHandler handler = new HttpHandler() {
+ @Override
+ public void handle(HttpExchange exchange) throws IOException {
+ File file = new File(documentRoot, exchange.getRequestURI().getPath());
+ if (!file.isFile()) {
+ exchange.sendResponseHeaders(404, -1);
+ exchange.close();
+ return;
+ }
+ byte[] body = Files.readAllBytes(file.toPath());
+ exchange.sendResponseHeaders(200, body.length);
+ try (OutputStream out = exchange.getResponseBody()) {
+ out.write(body);
+ }
+ }
+ };
+ HttpContext context = httpServer.createContext("/", handler);
if (withAuth) {
- Constraint constraint = new Constraint();
- constraint.setName(Constraint.__BASIC_AUTH);
- constraint.setRoles(new String[] {"user", "admin"});
- constraint.setAuthenticate(true);
-
- ConstraintMapping cm = new ConstraintMapping();
- cm.setConstraint(constraint);
- cm.setPathSpec("/*");
-
- SecurityHandler sh = new SecurityHandler();
- sh.setUserRealm(new HashUserRealm("MyRealm", getBasedir() + "/src/test/resources/realm.properties"));
- sh.setConstraintMappings(new ConstraintMapping[] {cm});
-
- webapp.addHandler(sh);
+ context.setAuthenticator(new BasicAuthenticator("MyRealm") {
+ @Override
+ public boolean checkCredentials(String username, String password) {
+ return "admin".equals(username) && "admin".equals(password);
+ }
+ });
}
- DefaultHandler defaultHandler = new DefaultHandler();
- defaultHandler.setServer(jettyServer);
-
- Handler[] handlers = new Handler[2];
- handlers[0] = webapp;
- handlers[1] = defaultHandler;
- jettyServer.setHandlers(handlers);
+ httpServer.start();
- jettyServer.start();
-
- port = connector.getLocalPort();
+ port = httpServer.getAddress().getPort();
}
- private void stopJetty() throws Exception {
- if (jettyServer != null) {
- jettyServer.stop();
+ private void stopServer() {
+ if (httpServer != null) {
+ httpServer.stop(0);
- jettyServer = null;
+ httpServer = null;
port = -1;
}
}
- private Connector getDefaultConnector() {
- Connector connector = new SelectChannelConnector();
- connector.setMaxIdleTime(MAX_IDLE_TIME);
- return connector;
- }
-
- private Connector getSSLConnector() {
- SslSocketConnector connector = new SslSocketConnector();
- connector.setKeystore(getBasedir() + "/target/jetty.jks");
- connector.setPassword("apache");
- connector.setKeyPassword("apache");
- connector.setTruststore(getBasedir() + "/target/jetty.jks");
- connector.setTrustPassword("apache");
- return connector;
+ private SSLContext createSslContext() throws Exception {
+ char[] password = "apache".toCharArray();
+ KeyStore keyStore = KeyStore.getInstance("JKS");
+ try (InputStream in = new FileInputStream(new File(getBasedir(), "target/jetty.jks"))) {
+ keyStore.load(in, password);
+ }
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, password);
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
+ return sslContext;
}
}
diff --git a/src/test/resources/realm.properties b/src/test/resources/realm.properties
deleted file mode 100644
index 5eca8a5..0000000
--- a/src/test/resources/realm.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-admin: admin,admin
-user: user,read-only