or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-processing.mdconfiguration-properties.mdindex.mdmonitoring.mdrequest-processing.mdresource-configuration.mdresource-model.mdspi.mdwadl.md

spi.mddocs/

0

# Service Provider Interface (SPI)

1

2

Extension points for container integration, component management, request scoping, validation, and lifecycle management. The SPI system enables deep customization of Jersey server behavior and integration with external frameworks and containers.

3

4

## Capabilities

5

6

### Container Management

7

8

Core interfaces for integrating Jersey with various container environments and managing container lifecycle.

9

10

```java { .api }

11

/**

12

* Jersey container interface providing lifecycle management and configuration access.

13

*/

14

public interface Container {

15

16

/**

17

* Reload the container with current configuration.

18

*/

19

void reload();

20

21

/**

22

* Reload the container with new configuration.

23

* @param configuration New ResourceConfig to apply

24

*/

25

void reload(ResourceConfig configuration);

26

27

/**

28

* Get the application handler for request processing.

29

* @return ApplicationHandler instance

30

*/

31

ApplicationHandler getApplicationHandler();

32

33

/**

34

* Get the current container configuration.

35

* @return ResourceConfig for this container

36

*/

37

ResourceConfig getConfiguration();

38

}

39

40

/**

41

* Container provider SPI for creating container instances.

42

*/

43

public interface ContainerProvider {

44

45

/**

46

* Create a container instance of specified type.

47

* @param type Container type to create

48

* @param application JAX-RS application

49

* @return Container instance of requested type or null if not supported

50

*/

51

<T> T createContainer(Class<T> type, Application application);

52

}

53

54

/**

55

* Container lifecycle listener for monitoring container events.

56

*/

57

public interface ContainerLifecycleListener {

58

59

/**

60

* Called when container is started.

61

* @param container Container that was started

62

*/

63

void onStartup(Container container);

64

65

/**

66

* Called when container is reloaded.

67

* @param container Container that was reloaded

68

*/

69

void onReload(Container container);

70

71

/**

72

* Called when container is shut down.

73

* @param container Container that was shut down

74

*/

75

void onShutdown(Container container);

76

}

77

78

/**

79

* Container response writer for writing HTTP responses.

80

*/

81

public interface ContainerResponseWriter {

82

83

/**

84

* Write response headers and status.

85

* @param contentLength Content length or -1 if unknown

86

* @param containerResponse Response to write

87

* @return OutputStream for writing response entity

88

*/

89

OutputStream writeResponseStatusAndHeaders(long contentLength, ContainerResponse containerResponse);

90

91

/**

92

* Suspend the response writer for asynchronous processing.

93

* @param timeOut Timeout value

94

* @param timeUnit Time unit for timeout

95

* @param timeoutHandler Handler called on timeout

96

* @return true if successfully suspended

97

*/

98

boolean suspend(long timeOut, TimeUnit timeUnit, TimeoutHandler timeoutHandler);

99

100

/**

101

* Set suspend timeout handler.

102

* @param timeoutHandler Handler for timeout events

103

*/

104

void setSuspendTimeout(long time, TimeUnit timeUnit);

105

106

/**

107

* Commit the response (make it immutable).

108

*/

109

void commit();

110

111

/**

112

* Enable response buffering if supported.

113

* @return true if buffering was enabled

114

*/

115

boolean enableResponseBuffering();

116

117

/**

118

* Failure callback called when response writing fails.

119

* @param error Error that occurred

120

*/

121

void failure(Throwable error);

122

}

123

```

124

125

**Usage Examples:**

126

127

```java

128

import org.glassfish.jersey.server.spi.*;

129

import org.glassfish.jersey.server.ApplicationHandler;

130

import org.glassfish.jersey.server.ResourceConfig;

131

132

// Custom container implementation

133

public class CustomContainer implements Container {

134

135

private ApplicationHandler applicationHandler;

136

private ResourceConfig configuration;

137

private final List<ContainerLifecycleListener> listeners = new ArrayList<>();

138

139

public CustomContainer(ResourceConfig config) {

140

this.configuration = config;

141

this.applicationHandler = new ApplicationHandler(config);

142

143

// Notify startup

144

for (ContainerLifecycleListener listener : listeners) {

145

listener.onStartup(this);

146

}

147

}

148

149

@Override

150

public void reload() {

151

reload(this.configuration);

152

}

153

154

@Override

155

public void reload(ResourceConfig configuration) {

156

this.configuration = configuration;

157

this.applicationHandler = new ApplicationHandler(configuration);

158

159

// Notify reload

160

for (ContainerLifecycleListener listener : listeners) {

161

listener.onReload(this);

162

}

163

}

164

165

@Override

166

public ApplicationHandler getApplicationHandler() {

167

return applicationHandler;

168

}

169

170

@Override

171

public ResourceConfig getConfiguration() {

172

return configuration;

173

}

174

175

public void addLifecycleListener(ContainerLifecycleListener listener) {

176

listeners.add(listener);

177

}

178

179

public void shutdown() {

180

for (ContainerLifecycleListener listener : listeners) {

181

listener.onShutdown(this);

182

}

183

}

184

}

185

186

// Custom container provider

187

public class CustomContainerProvider implements ContainerProvider {

188

189

@Override

190

public <T> T createContainer(Class<T> type, Application application) {

191

if (type == CustomContainer.class) {

192

ResourceConfig config = ResourceConfig.forApplication(application);

193

return type.cast(new CustomContainer(config));

194

}

195

return null; // Type not supported

196

}

197

}

198

```

199

200

### Component Management

201

202

SPI for custom component providers and dependency injection integration.

203

204

```java { .api }

205

/**

206

* Server-side component provider extending the base ComponentProvider.

207

* Enables custom dependency injection and component management.

208

*/

209

public interface ComponentProvider extends org.glassfish.jersey.spi.ComponentProvider {

210

211

/**

212

* Initialize the component provider with injection manager.

213

* @param injectionManager Injection manager instance

214

*/

215

void initialize(InjectionManager injectionManager);

216

217

/**

218

* Bind components and services.

219

* @param injectionManager Injection manager for binding

220

*/

221

void bind(InjectionManager injectionManager);

222

223

/**

224

* Called when component provider is being shut down.

225

* @param injectionManager Injection manager instance

226

*/

227

void done(InjectionManager injectionManager);

228

}

229

```

230

231

### Request Scope Management

232

233

External request scope management for integrating with external scoping mechanisms.

234

235

```java { .api }

236

/**

237

* External request scope interface for custom request scoping.

238

* Extends AutoCloseable for proper resource management.

239

*/

240

public interface ExternalRequestScope<T> extends AutoCloseable {

241

242

/**

243

* Open a new request scope context.

244

* @return ExternalRequestContext for the opened scope

245

*/

246

ExternalRequestContext<T> open();

247

248

/**

249

* Close the request scope and clean up resources.

250

*/

251

@Override

252

void close();

253

}

254

255

/**

256

* External request context representing an active request scope.

257

*/

258

public static class ExternalRequestContext<T> {

259

260

/**

261

* Create external request context.

262

* @param scopeInstance Scope instance

263

*/

264

public ExternalRequestContext(T scopeInstance);

265

266

/**

267

* Get the scope instance.

268

* @return Scope instance

269

*/

270

public T getInstance();

271

272

/**

273

* Release the context and associated resources.

274

*/

275

public void release();

276

}

277

278

/**

279

* Request scoped initializer for custom initialization logic.

280

*/

281

public interface RequestScopedInitializer {

282

283

/**

284

* Initialize request-scoped components.

285

* @param injectionManager Injection manager instance

286

*/

287

void initialize(InjectionManager injectionManager);

288

}

289

```

290

291

**Usage Examples:**

292

293

```java

294

import org.glassfish.jersey.server.spi.ExternalRequestScope;

295

import org.glassfish.jersey.server.spi.ExternalRequestContext;

296

import org.glassfish.jersey.server.spi.RequestScopedInitializer;

297

298

// Custom external request scope implementation

299

public class CustomRequestScope implements ExternalRequestScope<CustomScopeData> {

300

301

private final ThreadLocal<CustomScopeData> scopeData = new ThreadLocal<>();

302

303

@Override

304

public ExternalRequestContext<CustomScopeData> open() {

305

CustomScopeData data = new CustomScopeData();

306

scopeData.set(data);

307

return new ExternalRequestContext<>(data);

308

}

309

310

@Override

311

public void close() {

312

scopeData.remove();

313

}

314

315

public CustomScopeData getCurrentScope() {

316

return scopeData.get();

317

}

318

}

319

320

// Custom request-scoped initializer

321

public class CustomRequestScopedInitializer implements RequestScopedInitializer {

322

323

@Override

324

public void initialize(InjectionManager injectionManager) {

325

// Initialize request-scoped components

326

injectionManager.register(new AbstractBinder() {

327

@Override

328

protected void configure() {

329

bindFactory(CustomRequestScopedFactory.class)

330

.to(CustomService.class)

331

.in(RequestScoped.class);

332

}

333

});

334

}

335

}

336

337

// Usage in resource

338

@Path("/scoped")

339

public class ScopedResource {

340

341

@Inject

342

private CustomRequestScope requestScope;

343

344

@GET

345

public String getScopedData() {

346

try (ExternalRequestContext<CustomScopeData> context = requestScope.open()) {

347

CustomScopeData data = context.getInstance();

348

return "Scoped data: " + data.getValue();

349

}

350

}

351

}

352

```

353

354

### Validation Integration

355

356

SPI for custom validation interceptors and validation framework integration.

357

358

```java { .api }

359

/**

360

* Validation interceptor SPI for custom validation logic.

361

*/

362

public interface ValidationInterceptor {

363

364

/**

365

* Called before validation occurs.

366

* @param context Validation context

367

*/

368

void onValidate(ValidationInterceptorContext context);

369

}

370

371

/**

372

* Validation interceptor context providing access to validation information.

373

*/

374

public interface ValidationInterceptorContext {

375

376

/**

377

* Get the object being validated.

378

* @return Object to validate

379

*/

380

Object getValidatedObject();

381

382

/**

383

* Get the validation groups.

384

* @return Array of validation groups

385

*/

386

Class<?>[] getGroups();

387

388

/**

389

* Get the resource method being validated.

390

* @return ResourceMethod instance

391

*/

392

ResourceMethod getResourceMethod();

393

394

/**

395

* Get validation constraint violations.

396

* @return Set of constraint violations

397

*/

398

Set<ConstraintViolation<Object>> getConstraintViolations();

399

400

/**

401

* Set validation constraint violations.

402

* @param violations Set of violations to set

403

*/

404

void setConstraintViolations(Set<ConstraintViolation<Object>> violations);

405

}

406

```

407

408

### Error Handling

409

410

SPI for custom error mapping and response error handling.

411

412

```java { .api }

413

/**

414

* Response error mapper SPI for custom error handling.

415

*/

416

public interface ResponseErrorMapper {

417

418

/**

419

* Map an error to a response.

420

* @param error Error to map

421

* @param context Request context

422

* @return Response for the error or null to use default handling

423

*/

424

Response toResponse(Throwable error, ContainerRequest context);

425

426

/**

427

* Check if this mapper can handle the given error type.

428

* @param errorType Error type to check

429

* @return true if this mapper can handle the error type

430

*/

431

boolean isMappable(Class<? extends Throwable> errorType);

432

}

433

```

434

435

### Web Server Integration

436

437

SPI for integrating Jersey with various web server implementations.

438

439

```java { .api }

440

/**

441

* Web server interface for Jersey integration.

442

*/

443

public interface WebServer {

444

445

/**

446

* Start the web server.

447

*/

448

void start();

449

450

/**

451

* Stop the web server.

452

*/

453

void stop();

454

455

/**

456

* Get server port.

457

* @return Server port number

458

*/

459

int getPort();

460

461

/**

462

* Check if server is running.

463

* @return true if server is running

464

*/

465

boolean isRunning();

466

}

467

468

/**

469

* Web server provider SPI for creating web server instances.

470

*/

471

public interface WebServerProvider {

472

473

/**

474

* Create a web server instance.

475

* @param application JAX-RS application

476

* @param configuration Server configuration

477

* @return WebServer instance or null if not supported

478

*/

479

WebServer createServer(Application application, Map<String, Object> configuration);

480

481

/**

482

* Get the server type name.

483

* @return Server type identifier

484

*/

485

String getServerType();

486

}

487

```

488

489

**Usage Examples:**

490

491

```java

492

import org.glassfish.jersey.server.spi.WebServer;

493

import org.glassfish.jersey.server.spi.WebServerProvider;

494

495

// Custom web server implementation

496

public class CustomWebServer implements WebServer {

497

498

private final Application application;

499

private final int port;

500

private boolean running = false;

501

502

public CustomWebServer(Application application, int port) {

503

this.application = application;

504

this.port = port;

505

}

506

507

@Override

508

public void start() {

509

if (!running) {

510

// Start server implementation

511

startServerImplementation();

512

running = true;

513

}

514

}

515

516

@Override

517

public void stop() {

518

if (running) {

519

// Stop server implementation

520

stopServerImplementation();

521

running = false;

522

}

523

}

524

525

@Override

526

public int getPort() {

527

return port;

528

}

529

530

@Override

531

public boolean isRunning() {

532

return running;

533

}

534

}

535

536

// Custom web server provider

537

public class CustomWebServerProvider implements WebServerProvider {

538

539

@Override

540

public WebServer createServer(Application application, Map<String, Object> configuration) {

541

Integer port = (Integer) configuration.get("server.port");

542

if (port == null) {

543

port = 8080; // Default port

544

}

545

546

return new CustomWebServer(application, port);

547

}

548

549

@Override

550

public String getServerType() {

551

return "custom";

552

}

553

}

554

555

// Usage

556

public class ServerLauncher {

557

558

public static void main(String[] args) {

559

ResourceConfig config = new ResourceConfig()

560

.packages("com.example.resources");

561

562

Map<String, Object> serverConfig = new HashMap<>();

563

serverConfig.put("server.port", 9090);

564

565

CustomWebServerProvider provider = new CustomWebServerProvider();

566

WebServer server = provider.createServer(config, serverConfig);

567

568

server.start();

569

System.out.println("Server started on port " + server.getPort());

570

571

// Shutdown hook

572

Runtime.getRuntime().addShutdownHook(new Thread(server::stop));

573

}

574

}

575

```