Merge remote-tracking branch 'origin/jetty-12.0.x' into jetty-12.1.x
This commit is contained in:
commit
f653c2f658
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: 'Release Process'
|
||||
about: 'COMMITTER ONLY: Managing the Jetty release process'
|
||||
title: 'Jetty Releases 9.4.x, 10.0.y, 11.0.y'
|
||||
title: 'Jetty Releases 9.4.x, 10.0.y, 11.0.y, 12.0.y'
|
||||
assignees: ''
|
||||
labels: Build
|
||||
|
||||
|
@ -31,10 +31,12 @@ This release process will produce releases:
|
|||
- [ ] Verify that branch `jetty-10.0.x` is merged to branch `jetty-11.0.x`.
|
||||
- [ ] Assign issue to "build manager", who will stage the releases.
|
||||
+ [ ] Create and use branches `release/<ver>` to perform version specific release work from.
|
||||
+ [ ] Ensure `git fetch --tags` (as we potentially rewrite tag when re staging local tag can be out of sync and this command will fail and so fail the release script)
|
||||
+ [ ] Ensure `VERSION.txt` additions for each release will be meaningful, descriptive, correct text.
|
||||
+ [ ] Stage 9.4 release with Java 11.
|
||||
+ [ ] Stage 10 release with Java 21.
|
||||
+ [ ] Stage 11 release with Java 21.
|
||||
+ [ ] Stage 12 release with Java 22.
|
||||
+ [ ] Push release branches `release/<ver>` to to https://github.com/eclipse/jetty.project
|
||||
+ [ ] Push release tags `jetty-<ver>` to https://github.com/eclipse/jetty.project
|
||||
+ [ ] Edit a draft release (for each Jetty release) in GitHub (https://github.com/eclipse/jetty.project/releases). Content is generated with the "changelog tool".
|
||||
|
|
18
VERSION.txt
18
VERSION.txt
|
@ -291,11 +291,13 @@ jetty-12.0.1 - 29 August 2023
|
|||
+ 10411 Review deployment of Jetty Context XML files
|
||||
+ 10416 EE9 Copies HttpFields in response
|
||||
|
||||
jetty-9.4.54.v20240208 - 08 February 2024
|
||||
+ 1256 DoSFilter leaks USER_AUTH entries
|
||||
+ 11259 HTTP/2 connection not closed after idle timeout when TCP congested
|
||||
(CVE-2024-22201)
|
||||
+ 11389 Strip default ports on ws/wss scheme uris too
|
||||
jetty-11.0.21 - 14 May 2024
|
||||
+ 10805 Jetty response with an invalid HTTP2 packet if the client set the
|
||||
hpack table size as 0
|
||||
+ 11527 Reduce ByteBuffer churning in HttpOutput
|
||||
+ 11634 Socks5Proxy does not support IP addresses with IP segments above 127
|
||||
+ 11656 Upgrade jetty-quiche-native to version 0.21.0
|
||||
+ 11782 HttpExchange retained by HttpSenderOverHTTP which caused memory leak
|
||||
|
||||
jetty-11.0.20 - 29 January 2024
|
||||
+ 11081 Dropped WebSocket messages due to race condition in WebSocket frame
|
||||
|
@ -307,6 +309,12 @@ jetty-11.0.20 - 29 January 2024
|
|||
+ 11273 Support BSD expr in startup script
|
||||
+ 11349 Update quiche to 0.20.0
|
||||
|
||||
jetty-9.4.54.v20240208 - 08 February 2024
|
||||
+ 1256 DoSFilter leaks USER_AUTH entries
|
||||
+ 11259 HTTP/2 connection not closed after idle timeout when TCP congested
|
||||
(CVE-2024-22201)
|
||||
+ 11389 Strip default ports on ws/wss scheme uris too
|
||||
|
||||
jetty-11.0.19 - 15 December 2023
|
||||
+ 9900 Improve `Request.getBeginNanoTime()` accuracy
|
||||
+ 10812 jetty-deploy has unnecessary dependency on awaitility/hamcrest pulled
|
||||
|
|
|
@ -92,7 +92,7 @@ DEPLOY_OPTS="-DskipTests -Dasciidoctor.skip=false -Dmaven.build.cache.enabled=fa
|
|||
# DEPLOY_OPTS="$DEPLOY_OPTS -DaltDeploymentRepository=intarget::default::file://$ALT_DEPLOY_DIR/"
|
||||
|
||||
# Uncomment for Java 1.7
|
||||
export MAVEN_OPTS="-Xmx2g"
|
||||
export MAVEN_OPTS="-Xmx4g"
|
||||
|
||||
echo ""
|
||||
echo "-----------------------------------------------"
|
||||
|
|
|
@ -31,7 +31,7 @@ This uniquely identifies the jetty server instance and is applied to the `Sessio
|
|||
You can either provide a value for this property, or you can allow Jetty to try and synthesize a `workerName` - the latter option is _only_ advisable in the case of a single, non-clustered deployment.
|
||||
There are two ways a default `workerName` can be synthesized:
|
||||
|
||||
* if running on Google AppEngine, the `workerName` will be formed by concatenating the values of the environment variables `JETTY_WORKER_INSTANCE` and `GAE_MODULE_INSTANCE`
|
||||
* if running on Google AppEngine, the `workerName` will be formed by concatenating the values of the environment variables `JETTY_WORKER_INSTANCE` and `GAE_INSTANCE`
|
||||
* otherwise, the `workerName` will be formed by concatenating the environment variable `JETTY_WORKER_INSTANCE` and the literal `0`.
|
||||
|
||||
So, if you're not running on Google AppEngine, and you haven't configured one, the workerName will always be: `node0`.
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
= Eclipse Jetty
|
||||
= Eclipse Jetty {page-version}
|
||||
|
||||
This section of the site contains the documentation for {page-component-title} {page-version}.
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.eclipse.jetty.io.Connection;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.Retainable;
|
||||
import org.eclipse.jetty.io.RetainableByteBuffer;
|
||||
import org.eclipse.jetty.io.WriteFlusher;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
@ -48,7 +47,7 @@ import org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HTTP2Connection extends AbstractConnection implements Parser.Listener, WriteFlusher.Listener, Connection.UpgradeTo
|
||||
public class HTTP2Connection extends AbstractConnection implements Parser.Listener, Connection.UpgradeTo
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HTTP2Connection.class);
|
||||
|
||||
|
@ -302,12 +301,6 @@ public class HTTP2Connection extends AbstractConnection implements Parser.Listen
|
|||
session.onConnectionFailure(error, reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFlushed(long bytes) throws IOException
|
||||
{
|
||||
session.onFlushed(bytes);
|
||||
}
|
||||
|
||||
protected class HTTP2Producer implements ExecutionStrategy.Producer
|
||||
{
|
||||
private final Callback fillableCallback = new FillableCallback();
|
||||
|
|
|
@ -60,7 +60,6 @@ import org.eclipse.jetty.http2.parser.Parser;
|
|||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.CyclicTimeouts;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.WriteFlusher;
|
||||
import org.eclipse.jetty.util.AtomicBiInteger;
|
||||
import org.eclipse.jetty.util.Atomics;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -1084,11 +1083,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
streamsState.onStreamDestroyed();
|
||||
}
|
||||
|
||||
public void onFlushed(long bytes) throws IOException
|
||||
{
|
||||
flusher.onFlushed(bytes);
|
||||
}
|
||||
|
||||
private void terminate(Throwable cause)
|
||||
{
|
||||
flusher.terminate(cause);
|
||||
|
@ -1263,8 +1257,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
|
||||
public abstract boolean generate(ByteBufferPool.Accumulator accumulator) throws HpackException;
|
||||
|
||||
public abstract long onFlushed(long bytes) throws IOException;
|
||||
|
||||
boolean hasHighPriority()
|
||||
{
|
||||
return false;
|
||||
|
@ -1355,16 +1347,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long onFlushed(long bytes)
|
||||
{
|
||||
long flushed = Math.min(frameBytes, bytes);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Flushed {}/{} frame bytes for {}", flushed, bytes, this);
|
||||
frameBytes -= flushed;
|
||||
return bytes - flushed;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Performs actions just before writing the frame to the network.</p>
|
||||
* <p>Some frame, when sent over the network, causes the receiver
|
||||
|
@ -1433,7 +1415,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
private class DataEntry extends Entry
|
||||
{
|
||||
private int frameBytes;
|
||||
private int frameRemaining;
|
||||
private int dataBytes;
|
||||
private int dataRemaining;
|
||||
|
||||
|
@ -1477,7 +1458,6 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
DataFrame dataFrame = (DataFrame)frame;
|
||||
int frameBytes = generator.data(accumulator, dataFrame, length);
|
||||
this.frameBytes += frameBytes;
|
||||
this.frameRemaining += frameBytes;
|
||||
|
||||
int dataBytes = frameBytes - Frame.HEADER_LENGTH;
|
||||
this.dataBytes += dataBytes;
|
||||
|
@ -1492,27 +1472,11 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long onFlushed(long bytes) throws IOException
|
||||
{
|
||||
long flushed = Math.min(frameRemaining, bytes);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Flushed {}/{} frame bytes for {}", flushed, bytes, this);
|
||||
frameRemaining -= flushed;
|
||||
// We should only forward data (not frame) bytes,
|
||||
// but we trade precision for simplicity.
|
||||
Object channel = stream.getAttachment();
|
||||
if (channel instanceof WriteFlusher.Listener)
|
||||
((WriteFlusher.Listener)channel).onFlushed(flushed);
|
||||
return bytes - flushed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
bytesWritten.addAndGet(frameBytes);
|
||||
frameBytes = 0;
|
||||
frameRemaining = 0;
|
||||
|
||||
flowControl.onDataSent(stream, dataBytes);
|
||||
dataBytes = 0;
|
||||
|
|
|
@ -293,15 +293,6 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
|
|||
return Action.SCHEDULED;
|
||||
}
|
||||
|
||||
public void onFlushed(long bytes) throws IOException
|
||||
{
|
||||
// A single EndPoint write may be flushed multiple times (for example with SSL).
|
||||
for (HTTP2Session.Entry entry : processedEntries)
|
||||
{
|
||||
bytes = entry.onFlushed(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void succeeded()
|
||||
{
|
||||
|
|
|
@ -429,8 +429,8 @@ public abstract class WriteFlusher
|
|||
if (written > 0)
|
||||
{
|
||||
Connection connection = _endPoint.getConnection();
|
||||
if (connection instanceof Listener)
|
||||
((Listener)connection).onFlushed(written);
|
||||
if (connection instanceof Listener listener)
|
||||
listener.onFlushed(written);
|
||||
}
|
||||
|
||||
if (flushed)
|
||||
|
@ -581,7 +581,10 @@ public abstract class WriteFlusher
|
|||
/**
|
||||
* <p>A listener of {@link WriteFlusher} events.
|
||||
* If implemented by a Connection class, the {@link #onFlushed(long)} event will be delivered to it.</p>
|
||||
*
|
||||
* @deprecated functionality removed, no replacement
|
||||
*/
|
||||
@Deprecated(since = "12.0.10", forRemoval = true)
|
||||
public interface Listener
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<Property name="jetty.sessionIdManager.workerName">
|
||||
<Default>node<Env name="JETTY_WORKER_INSTANCE">
|
||||
<Default>
|
||||
<Env name="GAE_MODULE_INSTANCE">
|
||||
<Env name="GAE_INSTANCE" deprecated="GAE_MODULE_INSTANCE">
|
||||
<Default>0</Default>
|
||||
</Env>
|
||||
</Default>
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.eclipse.jetty.util.component.AttributeContainerMap;
|
|||
import org.eclipse.jetty.util.component.ClassLoaderDump;
|
||||
import org.eclipse.jetty.util.component.DumpableAttributes;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.eclipse.jetty.util.component.DumpableMap;
|
||||
import org.eclipse.jetty.util.component.Environment;
|
||||
import org.eclipse.jetty.util.component.Graceful;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
@ -137,6 +138,7 @@ public class Server extends Handler.Wrapper implements Attributes
|
|||
public Server(@Name("threadPool") ThreadPool pool)
|
||||
{
|
||||
this(pool, null, null);
|
||||
installBean(new DumpableMap("System Properties", System.getProperties()));
|
||||
}
|
||||
|
||||
public Server(@Name("threadPool") ThreadPool threadPool, @Name("scheduler") Scheduler scheduler, @Name("bufferPool") ByteBufferPool bufferPool)
|
||||
|
@ -791,7 +793,7 @@ public class Server extends Handler.Wrapper implements Attributes
|
|||
*/
|
||||
public Resource getDefaultStyleSheet()
|
||||
{
|
||||
return newResource("jetty-dir.css");
|
||||
return newResource("/org/eclipse/jetty/server/jetty-dir.css");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -801,7 +803,7 @@ public class Server extends Handler.Wrapper implements Attributes
|
|||
*/
|
||||
public Resource getDefaultFavicon()
|
||||
{
|
||||
return newResource("favicon.ico");
|
||||
return newResource("/org/eclipse/jetty/server/favicon.ico");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,6 @@ import org.eclipse.jetty.io.EndPoint;
|
|||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.io.RetainableByteBuffer;
|
||||
import org.eclipse.jetty.io.RuntimeIOException;
|
||||
import org.eclipse.jetty.io.WriteFlusher;
|
||||
import org.eclipse.jetty.io.ssl.SslConnection;
|
||||
import org.eclipse.jetty.server.AbstractMetaDataConnection;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
|
@ -81,7 +80,7 @@ import static org.eclipse.jetty.http.HttpStatus.INTERNAL_SERVER_ERROR_500;
|
|||
/**
|
||||
* <p>A {@link Connection} that handles the HTTP protocol.</p>
|
||||
*/
|
||||
public class HttpConnection extends AbstractMetaDataConnection implements Runnable, WriteFlusher.Listener, Connection.UpgradeFrom, Connection.UpgradeTo, ConnectionMetaData
|
||||
public class HttpConnection extends AbstractMetaDataConnection implements Runnable, Connection.UpgradeFrom, Connection.UpgradeTo, ConnectionMetaData
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpConnection.class);
|
||||
private static final HttpField PREAMBLE_UPGRADE_H2C = new HttpField(HttpHeader.UPGRADE, "h2c");
|
||||
|
@ -336,13 +335,6 @@ public class HttpConnection extends AbstractMetaDataConnection implements Runnab
|
|||
BufferUtil.append(getRequestBuffer(), buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFlushed(long bytes) throws IOException
|
||||
{
|
||||
// TODO is this callback still needed? Couldn't we wrap send callback instead?
|
||||
// Either way, the dat rate calculations from HttpOutput.onFlushed should be moved to Channel.
|
||||
}
|
||||
|
||||
void releaseRequestBuffer()
|
||||
{
|
||||
if (_retainableByteBuffer != null && !_retainableByteBuffer.hasRemaining())
|
||||
|
|
|
@ -32,8 +32,10 @@ import org.eclipse.jetty.server.internal.HttpChannelState;
|
|||
import org.eclipse.jetty.server.internal.HttpConnection;
|
||||
import org.eclipse.jetty.util.Blocker;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.thread.Invocable;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -143,6 +145,26 @@ public class ServerTest
|
|||
assertThat(response.getContent(), is("Hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDump() throws Exception
|
||||
{
|
||||
testSimpleGET();
|
||||
((QueuedThreadPool)(_server.getThreadPool())).tryExecute(() -> {});
|
||||
String dump = _server.dump();
|
||||
assertThat(dump, containsString("oejs.Server@"));
|
||||
assertThat(dump, containsString("QueuedThreadPool"));
|
||||
assertThat(dump, containsString("+= ReservedThreadExecutor@"));
|
||||
assertThat(dump, containsString(".ArrayByteBufferPool@"));
|
||||
assertThat(dump, containsString("+- System Properties size="));
|
||||
assertThat(dump, containsString("+> java.home: "));
|
||||
assertThat(dump, containsString("+> java.runtime.version: "));
|
||||
assertThat(dump, containsString("+= oejsh.ContextHandler@"));
|
||||
assertThat(dump, containsString("+= LocalConnector@"));
|
||||
assertThat(dump, containsString("key: +-"));
|
||||
assertThat(dump, containsString("JVM: "));
|
||||
assertThat(dump, containsString(Jetty.VERSION));
|
||||
}
|
||||
|
||||
public static Stream<Arguments> completionScenarios()
|
||||
{
|
||||
List<Arguments> arguments = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.server.subpackage;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
public class ServerDefaultResourcesTest
|
||||
{
|
||||
public static Stream<Arguments> arguments()
|
||||
{
|
||||
return Stream.of(
|
||||
new Server(),
|
||||
new Server(){}
|
||||
).map(Arguments::of);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("arguments")
|
||||
public void testDefaultStyleSheet(Server server) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
assertNotNull(server.getDefaultStyleSheet());
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("arguments")
|
||||
public void testDefaultFavicon(Server server) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
server.start();
|
||||
assertNotNull(server.getDefaultFavicon());
|
||||
}
|
||||
finally
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -745,10 +745,10 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
{
|
||||
try
|
||||
{
|
||||
dump(System.err, "");
|
||||
System.err.println(Dumpable.KEY);
|
||||
Dumpable.dump(this, System.err);
|
||||
System.err.println();
|
||||
}
|
||||
catch (IOException e)
|
||||
catch (Throwable e)
|
||||
{
|
||||
LOG.warn("Unable to dump", e);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,13 @@
|
|||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
@ -23,6 +28,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.util.Jetty;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -31,7 +37,7 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
|
|||
@ManagedObject("Dumpable Object")
|
||||
public interface Dumpable
|
||||
{
|
||||
String KEY = "key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +> undefined";
|
||||
String KEY = "key: +- bean, += managed, +~ unmanaged, +? auto, +: iterable, +] array, +@ map, +> undefined\n";
|
||||
|
||||
@ManagedOperation(value = "Dump the nested Object state as a String", impact = "INFO")
|
||||
default String dump()
|
||||
|
@ -50,24 +56,55 @@ public interface Dumpable
|
|||
void dump(Appendable out, String indent) throws IOException;
|
||||
|
||||
/**
|
||||
* Utility method to implement {@link #dump()} by calling {@link #dump(Appendable, String)}
|
||||
* Utility method to dump to a {@link String}
|
||||
*
|
||||
* @param dumpable The dumpable to dump
|
||||
* @return The dumped string
|
||||
* @see #dump(Appendable, String)
|
||||
*/
|
||||
static String dump(Dumpable dumpable)
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
dump(dumpable, b);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to dump to an {@link Appendable}
|
||||
*
|
||||
* @param dumpable The dumpable to dump
|
||||
* @param out The destination of the dump
|
||||
*/
|
||||
static void dump(Dumpable dumpable, Appendable out)
|
||||
{
|
||||
try
|
||||
{
|
||||
dumpable.dump(b, "");
|
||||
dumpable.dump(out, "");
|
||||
|
||||
out.append(KEY);
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
Instant now = Instant.now();
|
||||
String zone = System.getProperty("user.timezone");
|
||||
out.append("JVM: %s %s %s; OS: %s %s %s; Jetty: %s; CPUs: %d; mem(free/total/max): %,d/%,d/%,d MiB\nUTC: %s; %s: %s".formatted(
|
||||
System.getProperty("java.vm.vendor"),
|
||||
System.getProperty("java.vm.name"),
|
||||
System.getProperty("java.vm.version"),
|
||||
System.getProperty("os.name"),
|
||||
System.getProperty("os.arch"),
|
||||
System.getProperty("os.version"),
|
||||
Jetty.VERSION,
|
||||
runtime.availableProcessors(),
|
||||
runtime.freeMemory() / (1024 * 1024),
|
||||
runtime.totalMemory() / (1024 * 1024),
|
||||
runtime.maxMemory() / (1024 * 1024),
|
||||
DateTimeFormatter.ISO_DATE_TIME.format(now.atOffset(ZoneOffset.UTC)),
|
||||
zone,
|
||||
DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(now.atZone(ZoneId.of(zone)))));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
b.append(e.toString());
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
b.append(KEY);
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,7 +338,7 @@ public interface Dumpable
|
|||
* interface to allow it to refine which of its beans can be
|
||||
* dumped.
|
||||
*/
|
||||
public interface DumpableContainer extends Dumpable
|
||||
interface DumpableContainer extends Dumpable
|
||||
{
|
||||
default boolean isDumpable(Object o)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.util.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
public class DumpableMap implements Dumpable
|
||||
{
|
||||
private final String _name;
|
||||
private final Map<?, ?> _map;
|
||||
|
||||
public DumpableMap(String name, Map<?, ?> map)
|
||||
{
|
||||
_name = name;
|
||||
_map = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
Object[] array = _map.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey(Comparator.comparing(String::valueOf)))
|
||||
.map(e -> Dumpable.named(String.valueOf(e.getKey()), e.getValue())).toArray(Object[]::new);
|
||||
Dumpable.dumpObjects(out, indent, _name + " size=" + array.length, array);
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ import org.eclipse.jetty.util.MemoryUtils;
|
|||
import org.eclipse.jetty.util.ProcessorUtils;
|
||||
import org.eclipse.jetty.util.TypeUtil;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.DumpableCollection;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -236,8 +235,12 @@ public class ThreadIdPool<E> implements Dumpable
|
|||
int capacity = capacity();
|
||||
List<Object> slots = new ArrayList<>(capacity);
|
||||
for (int i = 0; i < capacity; i++)
|
||||
slots.add(_items.get(toSlot(i)));
|
||||
Dumpable.dumpObjects(out, indent, this, new DumpableCollection("items", slots));
|
||||
{
|
||||
E slot = _items.get(toSlot(i));
|
||||
if (slot != null)
|
||||
slots.add(Dumpable.named(Integer.toString(i), slot));
|
||||
}
|
||||
Dumpable.dumpObjects(out, indent, this, slots.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -833,8 +833,6 @@ public class QueuedThreadPoolTest extends AbstractThreadPoolTest
|
|||
assertThat(count(dump, " - STARTED"), is(3));
|
||||
assertThat(dump, containsString(",3<=3<=4,i=1,r=2,"));
|
||||
assertThat(dump, containsString("[ReservedThreadExecutor@"));
|
||||
assertThat(count(dump, "> ReservedThread@"), is(1));
|
||||
assertThat(count(dump, "> null"), is(1));
|
||||
assertThat(count(dump, "QueuedThreadPoolTest.lambda$testDump$"), is(0));
|
||||
|
||||
pool.setDetailedDump(true);
|
||||
|
|
|
@ -125,14 +125,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
|||
if (_out == null)
|
||||
{
|
||||
handler.dumpStdErr();
|
||||
System.err.println(Dumpable.KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.dump(_out);
|
||||
_out.println(Dumpable.KEY);
|
||||
Dumpable.dump(handler, _out);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-Description>javax.websocket.server Implementation</Bundle-Description>
|
||||
<Export-Package>org.eclipse.jetty.websocket.javax.server.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"</Export-Package>
|
||||
<Export-Package>org.eclipse.jetty.ee8.websocket.javax.server.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"</Export-Package>
|
||||
<Require-Capability>osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional</Require-Capability>
|
||||
<Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.eclipse.jetty.ee8.webapp.Configuration,osgi.serviceloader;osgi.serviceloader=javax.servlet.ServletContainerInitializer,osgi.serviceloader;osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator</Provide-Capability>
|
||||
</instructions>
|
||||
|
|
|
@ -121,14 +121,12 @@ public class DebugListener extends AbstractLifeCycle implements ServletContextLi
|
|||
if (_out == null)
|
||||
{
|
||||
handler.dumpStdErr();
|
||||
System.err.println(Dumpable.KEY);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.dump(_out);
|
||||
_out.println(Dumpable.KEY);
|
||||
Dumpable.dump(handler, _out);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue