Improvements to the Jetty server documentation.
Added section on troubleshooting. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
13094fa912
commit
1d96dda43f
|
@ -60,3 +60,4 @@ include::.asciidoctorconfig[]
|
|||
include::client/client.adoc[]
|
||||
include::server/server.adoc[]
|
||||
include::arch.adoc[]
|
||||
include::troubleshooting.adoc[]
|
||||
|
|
|
@ -23,7 +23,7 @@ Writing HTTP applications is typically simple, especially when using blocking AP
|
|||
However, there are subtle cases where it is worth clarifying what a server application should do to obtain the desired results when run by Jetty.
|
||||
|
||||
[[eg-server-http-application-1xx]]
|
||||
==== Managing 1xx Responses
|
||||
==== Sending 1xx Responses
|
||||
|
||||
The link:https://tools.ietf.org/html/rfc7231#section-5.1.1[HTTP/1.1 RFC] allows for `1xx` informational responses to be sent before a real content response.
|
||||
Unfortunately the servlet specification does not provide a way for these to be sent, so Jetty has had to provide non-standard handling of these headers.
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
A `Connector` is the component that handles incoming requests from clients, and works in conjunction with `ConnectionFactory` instances.
|
||||
|
||||
The primary implementation is `org.eclipse.jetty.server.ServerConnector`.`ServerConnector` uses a `java.nio.channels.ServerSocketChannel` to listen to a TCP port and to accept TCP connections.
|
||||
The primary implementation is `org.eclipse.jetty.server.ServerConnector`.
|
||||
`ServerConnector` uses a `java.nio.channels.ServerSocketChannel` to listen to a TCP port and to accept TCP connections.
|
||||
|
||||
Since `ServerConnector` wraps a `ServerSocketChannel`, it can be configured in a similar way, for example the port to listen to, the network address to bind to, etc.:
|
||||
|
||||
|
@ -32,18 +33,18 @@ include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=configur
|
|||
|
||||
The _acceptors_ are threads (typically only one) that compete to accept TCP connections on the listening port.
|
||||
When a connection is accepted, `ServerConnector` wraps the accepted `SocketChannel` and passes it to the xref:eg-arch-io-selector-manager[`SelectorManager`].
|
||||
Therefore, there is a little moment where the acceptor thread is not accepting new connections because it is busy wrapping the just accepted one to pass it to the `SelectorManager`.
|
||||
Therefore, there is a little moment where the acceptor thread is not accepting new connections because it is busy wrapping the just accepted connection to pass it to the `SelectorManager`.
|
||||
Connections that are ready to be accepted but are not accepted yet are queued in a bounded queue (at the OS level) whose capacity can be configured with the `ServerConnector.acceptQueueSize` parameter.
|
||||
|
||||
If your application must withstand a very high rate of connections opened, configuring more than one acceptor thread may be beneficial: when one acceptor thread accepts one connection, another acceptor thread can take over accepting connections.
|
||||
|
||||
The _selectors_ are components that manage a set of connected sockets, implemented by xref:eg-arch-io-selector-manager[`ManagedSelector`].
|
||||
Each selector requires one thread and uses the Java NIO mechanism to efficiently handle the set of connected sockets.
|
||||
Each selector requires one thread and uses the Java NIO mechanism to efficiently handle a set of connected sockets.
|
||||
As a rule of thumb, a single selector can easily manage up to 1000-5000 sockets, although the number may vary greatly depending on the application.
|
||||
|
||||
For example, web site applications tend to use sockets for one or more HTTP requests to retrieve resources and then the socket is idle for most of the time.
|
||||
In this case a single selector may be able to manage many sockets because chances are that they will be idle most of the time.
|
||||
On the contrary, web messaging applications tend to send many small messages at a very high frequency so that the socket is rarely idle.
|
||||
On the contrary, web messaging applications tend to send many small messages at a very high frequency so that sockets are rarely idle.
|
||||
In this case a single selector may be able to manage less sockets because chances are that many of them will be active at the same time.
|
||||
|
||||
It is possible to configure more than one `ServerConnector`, each listening on a different port:
|
||||
|
|
|
@ -38,8 +38,19 @@ A client making a request to `+https://shop.domain.com/cart+` is directed by Jet
|
|||
Therefore, in general, a web application is deployed to a _context_ which can be seen as the pair `(virtual_host, context_path)`.
|
||||
In the first case the contexts were `(domain.com, /shop)` and `(domain.com, /api)`, while in the second case the contexts were `(shop.domain.com, /)` and `(api.domain.com, /)`.
|
||||
Server applications using the Jetty Server Libraries create and configure a _context_ for each web application.
|
||||
Many __context__s can be deployed together to enrich the web application offering -- for example a catalog context, a shop context, an API context, an administration context, etc.
|
||||
|
||||
[[eg-server-http-handler-use-context]]
|
||||
Web applications can be written using exclusively the Servlet APIs, since developers know well the Servlet API and because they guarantee better portability across Servlet container implementations.
|
||||
|
||||
Embedded web applications based on the Servlet APIs are described in xref:eg-server-http-handler-use-servlet[this section].
|
||||
|
||||
Embedded web applications may also require additional features such as access to Jetty specific APIs, or utility features such as redirection from HTTP to HTTPS, support for `gzip` content compression, etc.
|
||||
The Jetty Server Libraries provides a number of out-of-the-box __Handler__s that implement the most common functionalities and are described in xref:eg-server-http-handler-use-util[this section].
|
||||
|
||||
[[eg-server-http-handler-use-util]]
|
||||
==== Custom and Utility Handlers
|
||||
|
||||
[[eg-server-http-handler-use-util-context]]
|
||||
===== ContextHandler
|
||||
|
||||
`ContextHandler` is a `Handler` that represents a _context_ for a web application.
|
||||
|
@ -62,7 +73,7 @@ Server
|
|||
└── ShopHandler
|
||||
----
|
||||
|
||||
[[eg-server-http-handler-use-context-collection]]
|
||||
[[eg-server-http-handler-use-util-context-collection]]
|
||||
===== ContextHandlerCollection
|
||||
|
||||
Server applications may need to deploy to Jetty more than one web application.
|
||||
|
@ -93,63 +104,7 @@ Server
|
|||
└── RESTHandler
|
||||
----
|
||||
|
||||
[[eg-server-http-handler-use-servlet-context]]
|
||||
===== ServletContextHandler
|
||||
|
||||
``Handler``s are easy to write, but often web applications have already been written using the Servlet APIs, using ``Servlet``s and ``Filter``s.
|
||||
|
||||
`ServletContextHandler` is a `ContextHandler` that provides support for the Servlet APIs and implements the behaviors required by the Servlet specification.
|
||||
|
||||
The Maven artifact coordinates are:
|
||||
|
||||
[source,xml,subs=normal]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=servletContextHandler]
|
||||
----
|
||||
|
||||
The `Handler` and Servlet components tree structure looks like the following:
|
||||
|
||||
[source,screen,subs=normal]
|
||||
----
|
||||
Server
|
||||
└── ServletContextHandler /shop
|
||||
├── _ShopCartServlet /cart/*_
|
||||
└── _CrossOriginFilter /*_
|
||||
----
|
||||
|
||||
Note how the Servlet components (they are not ``Handler``s) are represented in _italic_.
|
||||
|
||||
Note also how adding a `Servlet` or a `Filter` returns a _holder_ object that can be used to specify additional configuration for that particular `Servlet` or `Filter`.
|
||||
|
||||
When a request arrives to `ServletContextHandler` the request URI will be matched against the ``Filter``s and ``Servlet`` mappings and only those that match will process the request, as dictated by the Servlet specification.
|
||||
|
||||
IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always calls `Request.setHandled(true)` when invoked.
|
||||
Server applications must be careful when creating the `Handler` tree to put ``ServletContextHandler``s as last ``Handler``s in a `HandlerList` or as children of `ContextHandlerCollection`.
|
||||
|
||||
[[eg-server-http-handler-use-webapp-context]]
|
||||
===== WebAppContext
|
||||
|
||||
`WebAppContext` is a `ServletContextHandler` that auto configures itself by reading a `web.xml` Servlet configuration file.
|
||||
|
||||
Server applications can specify a `+*.war+` file or a directory with the structure of a `+*.war+` file to `WebAppContext` to deploy a standard Servlet web application packaged as a `war` (as defined by the Servlet specification).
|
||||
|
||||
Where server applications using `ServletContextHandler` must manually invoke methods to add ``Servlet``s and ``Filter``s, `WebAppContext` reads `WEB-INF/web.xml` to add ``Servlet``s and ``Filter``s.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=webAppContextHandler]
|
||||
----
|
||||
|
||||
[[eg-server-http-handler-use-resource-handler]]
|
||||
[[eg-server-http-handler-use-util-resource-handler]]
|
||||
===== ResourceHandler -- Static Content
|
||||
|
||||
Static content such as images or files (HTML, JavaScript, CSS) can be sent by Jetty very efficiently because Jetty can write the content asynchronously, using direct ``ByteBuffer``s to minimize data copy, and using a memory cache for faster access to the data to send.
|
||||
|
@ -188,17 +143,6 @@ include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=multiple
|
|||
If the resource is not found, `ResourceHandler` will not call `Request.setHandled(true)` so what happens next depends on the `Handler` tree structure.
|
||||
See also xref:eg-server-http-handler-use-util-default-handler[how to use] `DefaultHandler`.
|
||||
|
||||
[[eg-server-http-handler-use-default-servlet]]
|
||||
===== DefaultServlet -- Static Content for Servlets
|
||||
|
||||
If you have a xref:eg-server-http-handler-use-servlet-context[Servlet web application], you may want to use a `DefaultServlet` instead of `ResourceHandler`.
|
||||
The features are similar, but `DefaultServlet` is more commonly used to serve static files for Servlet web applications.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=defaultServlet]
|
||||
----
|
||||
|
||||
[[eg-server-http-handler-use-util-gzip-handler]]
|
||||
===== GzipHandler
|
||||
|
||||
|
@ -372,3 +316,77 @@ In the example above, `ContextHandlerCollection` will try to match a request to
|
|||
|
||||
NOTE: `DefaultHandler` just sends a nicer HTTP `404` response in case of wrong requests from clients.
|
||||
Jetty will send an HTTP `404` response anyway if `DefaultHandler` is not used.
|
||||
|
||||
[[eg-server-http-handler-use-servlet]]
|
||||
==== Servlet API Handlers
|
||||
|
||||
[[eg-server-http-handler-use-servlet-context]]
|
||||
===== ServletContextHandler
|
||||
|
||||
``Handler``s are easy to write, but often web applications have already been written using the Servlet APIs, using ``Servlet``s and ``Filter``s.
|
||||
|
||||
`ServletContextHandler` is a `ContextHandler` that provides support for the Servlet APIs and implements the behaviors required by the Servlet specification.
|
||||
|
||||
The Maven artifact coordinates are:
|
||||
|
||||
[source,xml,subs=normal]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=servletContextHandler]
|
||||
----
|
||||
|
||||
The `Handler` and Servlet components tree structure looks like the following:
|
||||
|
||||
[source,screen,subs=normal]
|
||||
----
|
||||
Server
|
||||
└── ServletContextHandler /shop
|
||||
├── _ShopCartServlet /cart/*_
|
||||
└── _CrossOriginFilter /*_
|
||||
----
|
||||
|
||||
Note how the Servlet components (they are not ``Handler``s) are represented in _italic_.
|
||||
|
||||
Note also how adding a `Servlet` or a `Filter` returns a _holder_ object that can be used to specify additional configuration for that particular `Servlet` or `Filter`.
|
||||
|
||||
When a request arrives to `ServletContextHandler` the request URI will be matched against the ``Filter``s and ``Servlet`` mappings and only those that match will process the request, as dictated by the Servlet specification.
|
||||
|
||||
IMPORTANT: `ServletContextHandler` is a terminal `Handler`, that is it always calls `Request.setHandled(true)` when invoked.
|
||||
Server applications must be careful when creating the `Handler` tree to put ``ServletContextHandler``s as last ``Handler``s in a `HandlerList` or as children of `ContextHandlerCollection`.
|
||||
|
||||
[[eg-server-http-handler-use-webapp-context]]
|
||||
===== WebAppContext
|
||||
|
||||
`WebAppContext` is a `ServletContextHandler` that auto configures itself by reading a `web.xml` Servlet configuration file.
|
||||
|
||||
Server applications can specify a `+*.war+` file or a directory with the structure of a `+*.war+` file to `WebAppContext` to deploy a standard Servlet web application packaged as a `war` (as defined by the Servlet specification).
|
||||
|
||||
Where server applications using `ServletContextHandler` must manually invoke methods to add ``Servlet``s and ``Filter``s, `WebAppContext` reads `WEB-INF/web.xml` to add ``Servlet``s and ``Filter``s.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=webAppContextHandler]
|
||||
----
|
||||
|
||||
// TODO: add a section on Configuration (system/server classes)
|
||||
// TODO: add a section about how to setup JSP support
|
||||
// TODO: add a section on ClassLoading (see old docs)
|
||||
|
||||
[[eg-server-http-handler-use-default-servlet]]
|
||||
===== DefaultServlet -- Static Content for Servlets
|
||||
|
||||
If you have a xref:eg-server-http-handler-use-servlet-context[Servlet web application], you may want to use a `DefaultServlet` instead of `ResourceHandler`.
|
||||
The features are similar, but `DefaultServlet` is more commonly used to serve static files for Servlet web applications.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=defaultServlet]
|
||||
----
|
||||
|
|
|
@ -61,5 +61,7 @@ However, in some cases the additional features are not required, or additional c
|
|||
In these cases, implementing your own `Handler` may be a better solution.
|
||||
Refer to xref:eg-server-http-handler-implement[this section] for more information about how to write your own ``Handler``s.
|
||||
|
||||
// TODO: document ScopedHandler? Is this really necessary or just an implementation detail that application will never worry about?
|
||||
|
||||
include::server-http-handler-use.adoc[]
|
||||
include::server-http-handler-implement.adoc[]
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
[[eg-server-http-security]]
|
||||
==== Securing HTTP Server Applications
|
||||
|
||||
// TODO: ConstraintSecurityHandler and Authenticators and LoginServices
|
||||
TODO
|
||||
|
|
@ -64,7 +64,12 @@ include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=simple]
|
|||
|
||||
The example above shows the simplest HTTP/1.1 server; it has no support for HTTP sessions, for HTTP authentication, or for any of the features required by the Servlet specification.
|
||||
|
||||
All these features are provided by the Jetty Server Libraries and server applications only need to put the required components together to provide all the required features, and it is discussed in details in xref:eg-server-http-handler-use[this section].
|
||||
All these features are provided by the Jetty Server Libraries, and server applications only need to put the required components together to provide all the required features.
|
||||
|
||||
The ``Handler``s provided by the Jetty Server Libraries allow writing server applications that have functionalities similar to Apache HTTPD or Nginx (for example: URL redirection, URL rewriting, serving static content, reverse proxying, etc.), as well as generating content dynamically by processing incoming requests.
|
||||
Read xref:eg-server-http-handler[this section] for further details.
|
||||
|
||||
If you are interested in writing your server application based on the Servlet APIs, jump to xref:eg-server-http-handler-use-servlet[this section].
|
||||
|
||||
[[eg-server-http-request-processing]]
|
||||
==== Server Request Processing
|
||||
|
@ -75,15 +80,6 @@ Request handing is slightly different for each protocol; in HTTP/2 Jetty takes i
|
|||
|
||||
However, the diagram below captures the essence of request handling that is common among all protocols that carry HTTP requests.
|
||||
|
||||
First, the Jetty I/O layer emits an event that a socket has data to read.
|
||||
This event is converted to a call to `AbstractConnection.onFillable()`, where the `Connection` first reads from the `EndPoint` into a `ByteBuffer`, and then calls a protocol specific parser to parse the bytes in the `ByteBuffer`.
|
||||
|
||||
The parser emit events such that are protocol specific; the HTTP/2 parser, for example, emits events for each HTTP/2 frame that has been parsed.
|
||||
The parser events are then converted to protocol independent events such as _"request start"_, _"request headers"_, _"request content chunk"_, etc.
|
||||
that in turn are converted into method calls to `HttpChannel`.
|
||||
|
||||
When enough of the HTTP request is arrived, the `Connection` calls `HttpChannel.handle()` that calls the `Handler` chain, that eventually calls the server application code.
|
||||
|
||||
[plantuml]
|
||||
----
|
||||
skinparam backgroundColor transparent
|
||||
|
@ -109,6 +105,15 @@ HttpChannel -> Server : handle()
|
|||
Server -> Handlers : handle()
|
||||
----
|
||||
|
||||
First, the Jetty I/O layer emits an event that a socket has data to read.
|
||||
This event is converted to a call to `AbstractConnection.onFillable()`, where the `Connection` first reads from the `EndPoint` into a `ByteBuffer`, and then calls a protocol specific parser to parse the bytes in the `ByteBuffer`.
|
||||
|
||||
The parser emit events that are protocol specific; the HTTP/2 parser, for example, emits events for each HTTP/2 frame that has been parsed.
|
||||
The parser events are then converted to protocol independent events such as _"request start"_, _"request headers"_, _"request content chunk"_, etc.
|
||||
that in turn are converted into method calls to `HttpChannel`.
|
||||
|
||||
When enough of the HTTP request is arrived, the `Connection` calls `HttpChannel.handle()` that calls the `Handler` chain, that eventually calls the server application code.
|
||||
|
||||
[[eg-server-http-channel-events]]
|
||||
===== HttpChannel Events
|
||||
|
||||
|
@ -141,7 +146,7 @@ Currently, the following events are available:
|
|||
|
||||
Please refer to the `HttpChannel.Listener` link:{JDURL}/org/eclipse/jetty/server/HttpChannel.Listener.html[javadocs] for the complete list of events.
|
||||
|
||||
Server applications can register `HttpChannel.Listener` by adding them as beans to the `Connector`:
|
||||
Server applications can register `HttpChannel.Listener` by adding them as xref:eg-arch-bean[beans] to the `Connector`:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
|
@ -150,4 +155,5 @@ include::../../{doc_code}/embedded/server/http/HTTPServerDocs.java[tags=httpChan
|
|||
|
||||
include::server-http-connector.adoc[]
|
||||
include::server-http-handler.adoc[]
|
||||
include::server-http-security.adoc[]
|
||||
include::server-http-application.adoc[]
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under
|
||||
// the terms of the Eclipse Public License 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0
|
||||
//
|
||||
// This Source Code may also be made available under the following
|
||||
// Secondary Licenses when the conditions for such availability set
|
||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||
// the Apache License v2.0 which is available at
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
[appendix]
|
||||
[[eg-troubleshooting]]
|
||||
== Troubleshooting Jetty
|
||||
|
||||
[[eg-troubleshooting-logging]]
|
||||
=== Logging
|
||||
|
||||
The Jetty libraries (both client and server) use link:http://slf4j.org/[SLF4J] as logging APIs.
|
||||
You can therefore plug in any SLF4J logging implementation, and configure the logging category `org.eclipse.jetty` at the desired level.
|
||||
|
||||
When you have problems with Jetty, the first thing that you want to do is to enable DEBUG logging.
|
||||
This is helpful because by reading the DEBUG logs you get a better understanding of what is going on in the system (and that alone may give you the answers you need to fix the problem), and because Jetty developers will probably need the DEBUG logs to help you.
|
||||
|
||||
==== Jetty SLF4J Binding
|
||||
|
||||
The Jetty artifact `jetty-slf4j-impl` is a SLF4J binding, that is the Jetty implementation of the SLF4J APIs, and provides a number of easy-to-use features to configure logging.
|
||||
|
||||
The Jetty SLF4J binding only provides an appender that writes to `System.err`.
|
||||
For more advanced configurations (for example, logging to a file), use link:http://logback.qos.ch[LogBack], or link:https://logging.apache.org/log4j/2.x/[Log4J2], or your preferred SLF4J binding.
|
||||
|
||||
CAUTION: Only one binding can be present in the class-path or module-path. If you use the LogBack SLF4J binding or the Log4J2 SLF4J binding, remember to remove the Jetty SLF4J binding.
|
||||
|
||||
The Jetty SLF4J binding reads a file in the class-path (or module-path) called `jetty-logging.properties` that can be configured with the logging levels for various logger categories:
|
||||
|
||||
.jetty-logging.properties
|
||||
[source,screen]
|
||||
----
|
||||
# By default, log at INFO level all Jetty classes.
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
|
||||
# However, the Jetty client classes are logged at DEBUG level.
|
||||
org.eclipse.jetty.client.LEVEL=DEBUG
|
||||
----
|
||||
|
||||
Similarly to how you configure the `jetty-logging.properties` file, you can set the system property `org.eclipse.jetty[.<package_names>].LEVEL=DEBUG` to quickly change the logging level to DEBUG without editing any file.
|
||||
The system property can be set on the command line, or in your IDE when you run your tests or your Jetty-based application and will override the `jetty-logging.properties` file configuration.
|
||||
For example to enable DEBUG logging for all the Jetty classes (_very_ verbose):
|
||||
|
||||
[source,screen]
|
||||
----
|
||||
java -Dorg.eclipse.jetty.LEVEL=DEBUG --class-path ...
|
||||
----
|
||||
|
||||
If you want to enable DEBUG logging but only for the HTTP/2 classes:
|
||||
|
||||
[source,screen]
|
||||
----
|
||||
java -Dorg.eclipse.jetty.http2.LEVEL=DEBUG --class-path ...
|
||||
----
|
||||
|
||||
[[eg-troubleshooting-debugging]]
|
||||
=== Debugging
|
||||
|
||||
Sometimes, in order to figure out a problem, enabling xref:eg-troubleshooting-logging[DEBUG logging] is not enough and you really need to debug the code with a debugger.
|
||||
|
||||
Debugging an embedded Jetty application is most easily done from your preferred IDE, so refer to your IDE instruction for how to debug Java applications.
|
||||
|
||||
Remote debugging can be enabled in a Jetty application via command line options:
|
||||
|
||||
[source,screen]
|
||||
----
|
||||
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000 --class-path ...
|
||||
----
|
||||
|
||||
The example above enables remote debugging so that debuggers (for example, your preferred IDE) can connect to port `8000` on the host running the Jetty application to receive debugging events.
|
||||
|
||||
NOTE: More technically, remote debugging exchanges JVM Tools Interface (JVMTI) events and commands via the Java Debug Wire Protocol (JDWP).
|
Loading…
Reference in New Issue