# Java Jakarta Servlet reference

Package-level reference for installation, public interfaces, observation boundaries and delivery behaviour.

## Package and basic usage

Sigillum Finans Jakarta Servlet / Spring MVC


Use `io.sigillum:finans-sdk-jakarta-servlet:0.11.0` for `jakarta.servlet` 5/6
applications. The adapter targets Java 8 bytecode; the application container
and framework still determine their minimum runtime (Spring 6 requires Java 17).
For legacy javax Servlet 3.1/4 applications, use `finans-sdk-servlet` and
`io.sigillum.finans.SigillumServletFilter` instead. Install only the
adapter matching the application's Servlet namespace.

The core SDK, private OpenTelemetry and its normal dependencies are resolved
through Maven. The application/container provides its Servlet API.



## Spring Boot / Spring MVC


Use the application's normal dependency injection and filter registration:

```java
@Bean(destroyMethod = "close")
public Sigillum sigillum() {
    return Sigillum.start(Paths.get(".sigillum/config.json").toAbsolutePath());
}

@Bean
public FilterRegistrationBean<SigillumJakartaServletFilter> sigillumFilter(Sigillum sdk) {
    FilterRegistrationBean<SigillumJakartaServletFilter> registration =
        new FilterRegistrationBean<>(new SigillumJakartaServletFilter(sdk));
    registration.setAsyncSupported(true);
    registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC,
        DispatcherType.ERROR);
    registration.addUrlPatterns("/*");
    return registration;
}
```

Imports are `io.sigillum.finans.Sigillum`,
`io.sigillum.finans.SigillumJakartaServletFilter`, `java.nio.file.Paths`,
`jakarta.servlet.DispatcherType`, `org.springframework.context.annotation.Bean`
and `org.springframework.boot.web.servlet.FilterRegistrationBean`.

For Boot 3+ / Jakarta MVC, replace the filter class and `javax.servlet` import
with the Jakarta equivalents. The registration pattern and data contract are
the same. Set the filter order before the component whose consumed request
and response should be observed; do not replace authentication/security
filters or the framework's executors.



## Standard WAR without a helper class


The public no-argument constructor supports ordinary `web.xml` registration:

```xml
<filter>
  <filter-name>sigillum</filter-name>
  <filter-class>io.sigillum.finans.SigillumJakartaServletFilter</filter-class>
  <async-supported>true</async-supported>
  <init-param>
    <param-name>configPath</param-name>
    <param-value>/app/.sigillum/config.json</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>sigillum</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>ASYNC</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>
```

Use the configuration's real absolute path. Missing, malformed or unavailable
configuration disables observation; it does not prevent the application from
starting or serving requests. The filter closes only an SDK that it created.
Use the DI registration above when application code also needs the same SDK
instance for explicit AI/custom facts.



## Captured facts and precise boundaries


The filter observes configured roots or authenticated continuations. It
captures method, URI, repeated headers, the observed response status, consumed
binary request bytes, successful binary response writes, asynchronous dispatch
and completion, native stream errors and the SDK's private OTEL lifecycle.
Application-excluded services propagate a valid context without creating their
own spans or records. No request body is eagerly read, rewound or buffered for
application use, and no application stream is automatically flushed.

Servlet `Reader` / `PrintWriter` access is reported as `applicationText` with
`contentEncoding=UTF-16BE`, `sourceCharacterEncoding`, and
`byteCoordinate=storedContent`. These are exact observed UTF-16 code units,
including split or unpaired surrogates; they are not claimed to be wire bytes.
The content descriptor is `text/plain;charset=UTF-16BE`. Completeness describes
the observed logical content, not network delivery to the remote client.

Native `PrintWriter` methods, auto-flush behavior, exceptions and fluent return
values are preserved. Opaque `Object` / `Formattable` conversions are not run
twice, and `printf`/`format` are not replayed by a second formatter. Such output,
fluent calls that return the original writer, discarded buffers, native
parameter/multipart parsing, skipped input and line readers that hide line
separators are explicitly partial rather than invented complete content.

`AsyncContext.start`, nonblocking read/write listeners, repeated async cycles
and Spring MVC `Callable` work bind and restore only the SDK's own context.
The ready Spring hook uses Spring's public `WebAsyncManager` interceptor API
when Spring is present. It does not change executors, other interceptors,
global OpenTelemetry or thread scheduling. For an independently scheduled
task / externally produced `DeferredResult`, use the existing `sdk.wrap(...)`
at that real scheduling boundary; the SDK cannot infer a missing context.

All observation, capture and callback failures are contained. Delivery and
profile refresh run on the SDK workers, independently of the native request.
Closing this filter never flushes or waits for durable custody or delivery.

