---
title: Web server data
description: What BxLens can read from inside a running BoxLang about MiniServer, CommandBox and servlet containers, with the source of each fact.
icon: lucide:network
---

# Web server data

What the [Web server](../console/web-server.md) page can read, on which runtime, and where each fact comes from. It was found by reading the sources and by running MiniServer. Nothing is guessed: a value a runtime does not report is shown as "not reported".

How it was checked:

| Runtime | How | Status |
|---|---|---|
| MiniServer | Source of `ortus-boxlang/boxlang-miniserver` (commit `739b45e`) and a running MiniServer 1.19.0 (JMX and reflection from a template) | Verified |
| CommandBox | Source of `Ortus-Solutions/commandbox` (`4471d2b`) and `Ortus-Solutions/runwar` (`bd9e829`). No CommandBox was started. | Read from source, not run |
| Servlet containers (Tomcat, Jetty, WildFly) | Public behavior of those products, not their source | Unverified |

## Which runtime is this

| Runtime | How BxLens tells | Evidence |
|---|---|---|
| MiniServer | The main class is `ortus.boxlang.web.MiniServer` (the `sun.java.command` property starts with it), or the class loads and `MiniServer.getServerInstance()` is not null. | `MiniServer.java:96` (class), `:400` (`getServerInstance`). Running: `sun.java.command` was `ortus.boxlang.web.MiniServer --webroot ... --host ... --port ...`. The class loads from the module class loader. |
| CommandBox | The JVM is started as `java ... -cp <jars> runwar.Start <serverInfo.json>`, so `sun.java.command` starts with `runwar.Start`; the class `runwar.Server` is also on the class path. | `ServerService.cfc:1497` appends `runwar.Start` and the `serverInfo.json` path to the argument list; `Start.java:37` reads that single argument. |
| Servlet container | Tomcat: property `catalina.base` or `catalina.home`. Jetty: `jetty.home` or `jetty.base`. WildFly: `jboss.home.dir`. Other: the servlet API class is present and a web request was seen. | Property names are the ones those products document. Not verified here. |
| CLI | None of the above and no web request seen. | |

CommandBox does not tell the server process its own version. The page shows the Runwar version (`runwar.Server.getVersion()`, `Server.java:727`).

## What is readable, per runtime

| Fact | MiniServer | CommandBox (Runwar) | Servlet container |
|---|---|---|---|
| Server name | not available (MiniServer has no server name) | `name` key of `serverInfo.json` | not read |
| Version | `MiniServer.getVersionInfo()`, key `version` (`MiniServer.java:728`) | Runwar version only | Tomcat `ServerInfo.getServerNumber()`, Jetty `Jetty.VERSION` (unverified) |
| Listeners, bind address, connection count | XNIO MXBeans, see below | same MXBeans (same XNIO library, not run) | none from XNIO; Tomcat has its own MBeans, not read |
| Protocol of a listener (http or https) | `Undertow.ListenerInfo.getProtcol()` via `MiniServer.getServerInstance()` | ports under `listeners.http` and `listeners.ssl` of `serverInfo.json` | not read |
| Ports | from the bind addresses | from the bind addresses | not read |
| Web root | `MiniServer.resourceManager` (`MiniServer.java:121`) when it is a `PathResourceManager`: `getBasePath()`. Not available when URL aliases wrap it in an `AliasResourceManager`. | `webroot` key of `serverInfo.json` | not read |
| Rewrites | not readable (see below) | `rewritesEnable` key of `serverInfo.json` | not read |
| Started at | not available | not read (`serverInfo.json` has a CFML date string, not parsed) | not read |
| Worker threads, queue | XNIO worker MXBean | same MXBean (not run) | not read |
| Busy worker threads | not reported (the MXBean answers -1) | not reported (same library) | not read |
| Bytes sent | `ConnectorStatistics.getBytesSent()` through the listener info, summed | not reachable (see below) | not read |
| Requests, 5xx, slowest, active, per second | BxLens counters | BxLens counters | BxLens counters |

The request numbers of BxLens count the requests that reached BoxLang. The bytes sent of MiniServer count everything the connector served, static files included, so the two do not match.

## MiniServer

Everything below was seen on a running MiniServer 1.19.0.

- **Public static accessors** (`MiniServer.java`): `getServerInstance()` returns the `io.undertow.Undertow`, `getWorker()` the `XnioWorker`, `getActiveRequests()` a count of every request in the handler chain, `getMetricsHandler()` the `MetricsHandler`, `getVersionInfo()` the version. BxLens calls the first, the version and the `resourceManager` field by reflection, with no compile dependency.
- **Connector statistics are on.** `MiniServerConfig.java:128` puts `ENABLE_STATISTICS = true` in the default Undertow options, "required for connector statistics exposed by health checks". The `ConnectorStatistics` object is reached through `getServerInstance().getListenerInfo().get(i).getConnectorStatistics()`. It has request count, error count, bytes sent and received, active connections and active requests. Undertow does not publish it over JMX, so reflection on `MiniServer` is the only way. A user can switch it off in `miniserver.json` (`undertowOptions`), then the object is null and "bytes sent" is not reported.
- **MXBeans** (name, then the attributes read):
  - `org.xnio:type=Xnio,provider="nio",worker="XNIO-1"`: `IoThreadCount` 4, `CoreWorkerPoolSize` 32, `MaxWorkerPoolSize` 32, `WorkerPoolSize` 1, `WorkerQueueSize` 0, `BusyWorkerThreadCount` -1.
  - `org.xnio:type=Xnio,provider="nio",worker="XNIO-1",address="/127.0.0.1:8130"`: `BindAddress`, `ConnectionCount`, `ConnectionLimitHighWater` and `ConnectionLimitLowWater` (both 2147483647, which means unlimited).
  - `jboss.threads:name="XNIO-1",type=thread-pool`: `PoolSize`, `CorePoolSize`, `MaximumPoolSize`, `QueueSize`, `MaximumQueueSize` (2147483647, unbounded); `ActiveCount`, `CompletedTaskCount`, `LargestPoolSize`, `SubmittedTaskCount` and `RejectedTaskCount` are -1.
  - `org.xnio:type=Xnio,provider="nio"`: provider name and XNIO version (3.8.16.Final).
- **Busy workers are not readable.** `BusyWorkerThreadCount` is -1 on the `nio` provider and so is `ActiveCount` on the pool. MiniServer's own health endpoint (`HealthCheckHandler.java:196`) reports the same -1 as `busy`. BxLens shows "not reported" and never fills it in from the in-flight list.
- **Rewrites are not readable.** The configuration (`MiniServerConfig`) is a local variable of `main` and is not kept; the rewrite handler is wrapped into the handler chain at `MiniServer.java:560` and nothing exposes it. The `--rewrites` flag is on the command line only when it was given there, and its absence proves nothing (`miniserver.json` can enable it).
- **No server name, no start time.** `HealthCheckHandler` keeps its own start time in an instance field. The JVM start time is on the JVM page and is not the server start.

## CommandBox (Runwar), read from source

CommandBox starts the server as a separate JVM (`ServerService.cfc:1480-1500`), so the BoxLang in it runs inside the Runwar process.

- **Connector statistics are off and not reachable.** Runwar never sets `ENABLE_STATISTICS` (a search of `runwar/src/main` finds no use of `ENABLE_STATISTICS` or `ConnectorStatistics`). A user can add it in `server.json` under `runwar.undertowOptions` (`ConfigParser.java:288`), which Runwar applies with `setServerOption` (`Server.java:459`). Either way the `Undertow` object is the private instance field `Server.undertow` (`Server.java:78`) of an object that only `Start.main` holds, so it cannot be reached from the application. Bytes sent is not reported.
- **MXBeans.** Runwar builds its listeners with `Undertow.builder()`, so XNIO registers the same worker and listener MXBeans as under MiniServer. Not run. Runwar creates a second worker, `XNIO-2`, for the access log when access logging is on (`SiteDeployment.java:299`); it has no listener, and BxLens takes the worker that owns the listeners.
- **Worker size.** Left to Undertow unless `maxRequests` is set in `server.json` (`Server.java:292`, `setWorkerThreads`).
- **The `serverInfo.json` file.** Its path is the only argument of `runwar.Start`. It holds the server definition and also secrets (`SSLKeyPass`, `AJPSecret`, `ModCFMLSharedKey`, `basicAuthUsers`). BxLens reads it only when the command line is a `runwar.Start` line, up to 2 MB, and copies out `name`, `webroot`, `rewritesEnable` and the `port` of each entry under `listeners.http` and `listeners.ssl`. Every other key is dropped before anything is kept. The keys exist in `ServerService.cfc` (the defaults at lines 3540-3660) and `ConfigParser.java`.
- **Servlet context.** Runwar names the deployment `WildFly / Undertow` (`Server.java:321`), which is what `ServletContext.getServerInfo()` reports. BxLens does not use it, because it needs a servlet request.

## What is not readable anywhere

| Fact | Why |
|---|---|
| Busy worker threads (MiniServer, and so CommandBox) | The XNIO `nio` provider and jboss-threads report -1. |
| Connection limit | Unlimited by default (2147483647). It is shown only when a real limit is set. |
| Rewrites, on MiniServer | Not kept by the server. |
| Start time of the server | Neither server exposes it. |
| Bytes sent on CommandBox | Statistics are off by default and the Undertow object is private. |
| CommandBox version | Not passed to the server process. |
| Anything of Tomcat, Jetty or WildFly beyond name and version | Not read. Tomcat has MBeans (`Catalina:type=ThreadPool`, `Catalina:type=GlobalRequestProcessor`) that a later version can read the same way as XNIO's; they were not checked. |
