Skip to content

Commit

Permalink
Merge branch 'jetty-12.1.x' into fix/jetty-12.1.x/errorDispatch
Browse files Browse the repository at this point in the history
  • Loading branch information
gregw committed May 22, 2024
2 parents f116fb3 + f684b69 commit 9243b91
Show file tree
Hide file tree
Showing 153 changed files with 30,312 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// ========================================================================
// 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
// ========================================================================
//

[[og-module-state-tracking]]
===== Module `state-tracking`

The `state-tracking` Jetty module inserts the `StateTrackingHandler` at the beginning of the Handler chain.

`StateTrackingHandler` is a xref:og-troubleshooting[troubleshooting] `Handler` that tracks usages of `Handler`/`Request`/`Response` asynchronous APIs, and logs at warning level invalid usages of the APIs that may lead to blockages, deadlocks, or missing completion of ``Callback``s.

This module can be enabled to troubleshoot web applications that do not behave as expected, for example:

* That consume a lot of threads (possibly because they block).
* That do not send responses (or send only partial responses) to clients.
* That timeout when apparently they have received or have sent all data.

The module properties are:

----
include::{jetty-home}/modules/state-tracking.mod[tags=documentation]
----
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ include::module-console-capture.adoc[]
include::module-core-deploy.adoc[]
include::module-cross-origin.adoc[]
include::module-eeN-deploy.adoc[]
include::module-eeN-webapp.adoc[]
include::module-http.adoc[]
include::module-http2.adoc[]
include::module-http2c.adoc[]
Expand All @@ -34,9 +35,9 @@ include::module-rewrite.adoc[]
include::module-server.adoc[]
include::module-ssl.adoc[]
include::module-ssl-reload.adoc[]
include::module-state-tracking.adoc[]
include::module-test-keystore.adoc[]
include::module-threadpool.adoc[]
include::module-threadpool-virtual.adoc[]
include::module-threadpool-virtual-preview.adoc[]
include::module-eeN-webapp.adoc[]
include::module-well-known.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[[og-troubleshooting]]
=== Troubleshooting

To troubleshoot Jetty when used as a production server, there are two main tools: the Jetty Server Dump and enabling DEBUG level logging.
To troubleshoot Jetty when used as a standalone server, there are two main tools: the Jetty Server Dump and enabling DEBUG level logging.

Jetty is based on components organized as a tree, with the `Server` instance at the root of the tree.

Expand All @@ -36,3 +36,4 @@ IMPORTANT: Make sure you read about how to secure the access to Jetty when using
include::troubleshooting-dump.adoc[]
include::troubleshooting-logging.adoc[]
include::troubleshooting-debugging.adoc[]
include::troubleshooting-handlers.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[[og-troubleshooting-dump]]
==== Server Dump

The Jetty Server Dump is obtained by invoking, via JMX, the `Server.dump()` operation, as shown below.
The Jetty Server Dump is obtained by invoking, via JMX, the `Server.dump()` operation, as shown below using link:https://adoptium.net/jmc.html[Java Mission Control (JMC)]:

image::jmc-server-dump.png[]

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// ========================================================================
// 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
// ========================================================================
//

[[og-troubleshooting-handlers]]
==== Troubleshooting Handlers

[[og-troubleshooting-handlers-state-tracking]]
===== `StateTrackingHandler`

Jetty's `StateTrackingHandler` (described in xref:og-module-state-tracking[this module]) can be used to troubleshoot problems in web applications.

`StateTrackingHandler` tracks the usages of `Handler`/`Request`/`Response` asynchronous APIs by web applications, emitting events (logged at warning level) when an invalid usage of the APIs is detected.

In conjunction with xref:og-troubleshooting-dump[dumping the Jetty component tree], it dumps the state of current requests, detailing whether they have reads or writes that are pending, whether callbacks have been completed, along with thread stack traces (including virtual threads) of operations that have been started but not completed, or are stuck in blocking code.

You need to enable the `state-tracking` Jetty module, and configure it to track what you are interested in tracking (for more details, see the link:{javadoc-url}/org/eclipse/jetty/server/handler/StateTrackingHandler.html[javadocs]).

// TODO: add a section about DebugHandler.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ Here's an example of setting up the `HashLoginService` for a webapp:
<loginService implementation="org.eclipse.jetty.security.HashLoginService">
<name>Test Realm</name>
<config implementation="org.eclipse.jetty.maven.MavenResource">
<resourceAsString>${basedir}/src/etc/realm.properties</resourceAsString>
<resourceAsString>${project.basedir}/src/etc/realm.properties</resourceAsString>
</config>
</loginService>
</loginServices>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,34 @@ If the application deployed in the cross domain requires cookies or authenticati

For more `CrossOriginHandler` configuration options, refer to the link:{javadoc-url}/org/eclipse/jetty/server/handler/CrossOriginHandler.html[`CrossOriginHandler` javadocs].

[[pg-server-http-handler-use-state-tracking]]
====== StateTrackingHandler

`StateTrackingHandler` is a xref:pg-troubleshooting[troubleshooting] `Handler` that tracks whether `Handler`/`Request`/`Response` asynchronous APIs are properly used by applications.</p>

Asynchronous APIs are notoriously more difficult to troubleshoot than blocking APIs, and may be subject to restrictions that applications need to respect (a typical case is that they cannot perform blocking operations).

For example, a `Handler` implementation whose `handle(\...)` method returns `true` _must_ eventually complete the callback passed to `handle(\...)` (for more details on the `Handler` APIs, see xref:pg-server-http-handler-impl[this section]).

When an application forgets to complete the callback passed to `handle(\...)`, the HTTP response may not be sent to the client, but it will be difficult to troubleshoot why the client is not receiving responses.

`StateTrackingHandler` helps with this troubleshooting because it tracks the callback passed to `handle(\...)` and emits an event if the callback is not completed within a configurable timeout:

[source,java,indent=0]
----
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=stateTrackingHandle]
----

By default, events are logged at warning level, but it is possible to specify a listener to be notified of the events tracked by `StateTrackingHandler`:

[source,java,indent=0]
----
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/http/HTTPServerDocs.java[tags=stateTrackingListener]
----

Other events tracked by `StateTrackingHandler` are demand callbacks that block, writes that do not complete their callbacks, or write callbacks that block.
The complete list of events is specified by the `StateTrackingHandler.Listener` class (link:{javadoc-url}/org/eclipse/jetty/server/handler/StateTrackingHandler.Listener.html[javadocs]).

[[pg-server-http-handler-use-default]]
====== DefaultHandler

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,34 @@ java -Dorg.eclipse.jetty.http2.LEVEL=DEBUG --class-path ...
=== JVM Thread Dump
TODO

[[pg-troubleshooting-state-tracking]]
=== `StateTrackingHandler`

`StateTrackingHandler` (described xref:pg-server-http-handler-use-state-tracking[here]) is a troubleshooting `Handler` that can be inserted in the `Handler` chain to track usages of `Handler`/`Request`/`Response` asynchronous APIs.

xref:pg-troubleshooting-component-dump[Dumping the Jetty component tree] will dump the `StateTrackingHandler`, which will dump the state of the current requests.

This will help detecting whether requests are not completed due to callbacks not being completed, or whether callback code is stuck while invoking blocking APIs, etc.

Thread stack traces (including virtual threads) of operations that have been started but not completed, or are stuck in blocking code are provided in the component tree dump.

[[pg-troubleshooting-component-dump]]
=== Jetty Component Tree Dump
=== Component Tree Dump

Jetty components are organized in a xref:pg-arch-bean[component tree].

At the root of the component tree there is typically a `ContainerLifeCycle` instance -- typically a `Server` instance on the server and an `HttpClient` instance on the client.

`ContainerLifeCycle` has built-in _dump_ APIs that can be invoked either directly or xref:pg-arch-jmx[via JMX].
`ContainerLifeCycle` has built-in _dump_ APIs that can be invoked either directly on the `Server` instance, or xref:pg-arch-jmx[via JMX].

You can invoke `Server.dump()` via JMX using a JMX console such as link:https://adoptium.net/jmc.html[Java Mission Control (JMC)]:

// TODO: images from JMC?
// TODO: Command line JMX will be in JMX section.
image::jmc-server-dump.png[]

TIP: You can get more details from a Jetty's `QueuedThreadPool` dump by enabling detailed dumps via `queuedThreadPool.setDetailedDump(true)`.

[[pg-troubleshooting-debugging]]
=== Debugging
=== Remote Debugging

Sometimes, in order to figure out a problem, enabling xref:pg-troubleshooting-logging[DEBUG logging] is not enough and you really need to debug the code with a debugger.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
import org.eclipse.jetty.server.handler.QoSHandler;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.server.handler.StateTrackingHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
import org.eclipse.jetty.unixdomain.server.UnixDomainServerConnector;
Expand Down Expand Up @@ -1535,6 +1536,33 @@ public void crossOriginAllowedOrigins()
// end::crossOriginAllowedOrigins[]
}

public void stateTrackingHandle()
{
// tag::stateTrackingHandle[]
StateTrackingHandler stateTrackingHandler = new StateTrackingHandler();

// Emit an event if the Handler callback is not completed with 5 seconds.
stateTrackingHandler.setHandlerCallbackTimeout(5000);
// end::stateTrackingHandle[]
}

public void stateTrackingListener()
{
// tag::stateTrackingListener[]
StateTrackingHandler stateTrackingHandler = new StateTrackingHandler(new StateTrackingHandler.Listener()
{
@Override
public void onHandlerCallbackNotCompleted(Request request, StateTrackingHandler.ThreadInfo handlerThreadInfo)
{
// Your own event handling logic.
}
});

// Emit an event if the Handler callback is not completed with 5 seconds.
stateTrackingHandler.setHandlerCallbackTimeout(5000);
// end::stateTrackingListener[]
}

public void defaultHandler() throws Exception
{
// tag::defaultHandler[]
Expand Down
2 changes: 2 additions & 0 deletions documentation/jetty/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.asciidoctorconfig
/provided-antora-playbook.yml
32 changes: 32 additions & 0 deletions documentation/jetty/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ========================================================================
// 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
// ========================================================================
//

= Jetty Documentation

This project is the root of the Jetty documentation.
The content files in this project get sourced by the Antora playbook in the playbook repository that builds the website.

In order to build the documentation locally, you first need to prepare a jetty-home directory by running the following command from the top-level folder of the Jetty project:

$ mvn install -Dcollector -Pfast -am -pl documentation/jetty

Then you can use the following command from this directory to prepare and run Antora using a preview profile:

$ mvn antora -N

If you don't run the first command, the Antora build will still succeed, but you will get warnings about missing includes for files taken from jetty-home.

The `antora:antora` goal, which the `antora` lifecycle invokes, takes advantage of the playbook provider feature so the playbook for this branch can be centrally managed in the playbook repository.

Note that this preview profile does not run the jetty blocks, so you will only see the configuration for those runs in the preview site.
If you want to build the full site, use the build in the playbook repository.
28 changes: 28 additions & 0 deletions documentation/jetty/antora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: jetty
version: '12'
title: Eclipse Jetty
asciidoc:
attributes:
javadoc-url: https://eclipse.dev/jetty/javadoc/jetty-12
jdurl: '{javadoc-url}'
jetty-home: ${jetty.home}@
version: 12.0.10-SNAPSHOT
idprefix: ''
idseparator: ''
ee-all: ee{8,9,10}
ee-current: ee10
ee-current-caps: EE 10
run-jetty-classpath: ${settings.localRepository}/org/eclipse/jetty/tests/jetty-testers/${project.version}/jetty-testers-${project.version}.jar${path.separator}${run.jetty.classpath}
nav:
- modules/operations-guide/nav.adoc
- modules/programming-guide/nav.adoc
ext:
collector:
- run:
command: mvn install -ntp -B -Dcollector -Pfast -am -pl documentation/jetty
scan:
dir: documentation/jetty/target/collector
- scan:
dir: jetty-core/jetty-server/src/main/java
files: org/eclipse/jetty/server/CustomRequestLog.java
base: modules/code/partials
24 changes: 24 additions & 0 deletions documentation/jetty/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// ========================================================================
// 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
// ========================================================================
//

= Eclipse Jetty

This section of the site contains the documentation for {page-component-title} {page-version}.

== xref:operations-guide:index.adoc[]

The Eclipse Jetty Operations Guide targets sysops, devops, and developers who want to install Eclipse Jetty as a standalone server to deploy web applications.

== xref:programming-guide:index.adoc[]

The Eclipse Jetty Programming Guide targets developers who want to use the Eclipse Jetty libraries in their applications, and advanced sysops/devops that want to customize the deployment of web applications.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[description]
JPMS Configuration Module

[ini]
--jpms

[jpms]
# Additional JPMS configuration.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[description]
JVM Options Module

[exec]
-Xmx1g
-Xlog:gc*,gc+stats=off:file=logs/gc.log:time,level,tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[description]
Postgres JDBC Driver Module

[lib]
lib/postgresql-${postgresql-version}.jar

[files]
maven://org.postgresql/postgresql/${postgresql-version}|lib/postgresql-${postgresql-version}.jar

[ini]
postgresql-version?=42.6.0

[ini-template]
## Postgres JDBC version.
# postgresql-version=42.6.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[description]
Enables remote debugging

[exec]
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
Loading

0 comments on commit 9243b91

Please sign in to comment.