or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdapplication-context.mdbean-definition.mdbean-factory.mdbean-processing.mdbean-providers.mdenvironment-config.mdevents.mdexceptions.mdindex.mdscoping.md

exceptions.mddocs/

0

# Exception Handling

1

2

Micronaut Inject provides a comprehensive exception hierarchy for handling dependency injection errors, bean resolution failures, and configuration issues. Understanding these exceptions is crucial for proper error handling and debugging.

3

4

## Exception Hierarchy

5

6

### BeanContextException

7

8

Base exception for all bean context related errors.

9

10

```java { .api }

11

public class BeanContextException extends RuntimeException {

12

public BeanContextException(String message);

13

public BeanContextException(String message, Throwable cause);

14

}

15

```

16

17

### NoSuchBeanException

18

19

Thrown when a required bean cannot be found in the context.

20

21

```java { .api }

22

public class NoSuchBeanException extends BeanContextException {

23

public NoSuchBeanException(Class<?> beanType);

24

public NoSuchBeanException(Class<?> beanType, Qualifier<?> qualifier);

25

public NoSuchBeanException(String message);

26

27

public Class<?> getBeanType();

28

public Qualifier<?> getQualifier();

29

}

30

```

31

32

### NonUniqueBeanException

33

34

Thrown when multiple beans match a type but only one is expected.

35

36

```java { .api }

37

public class NonUniqueBeanException extends BeanContextException {

38

public NonUniqueBeanException(Class<?> beanType, Collection<BeanDefinition<?>> possibleCandidates);

39

40

public Class<?> getBeanType();

41

public Collection<BeanDefinition<?>> getPossibleCandidates();

42

}

43

```

44

45

### BeanInstantiationException

46

47

Thrown when bean instantiation fails.

48

49

```java { .api }

50

public class BeanInstantiationException extends BeanContextException {

51

public BeanInstantiationException(String message);

52

public BeanInstantiationException(String message, Throwable cause);

53

public BeanInstantiationException(BeanDefinition<?> beanDefinition, Throwable cause);

54

55

public BeanDefinition<?> getBeanDefinition();

56

}

57

```

58

59

### DependencyInjectionException

60

61

Thrown when dependency injection fails.

62

63

```java { .api }

64

public class DependencyInjectionException extends BeanContextException {

65

public DependencyInjectionException(String message);

66

public DependencyInjectionException(String message, Throwable cause);

67

public DependencyInjectionException(BeanDefinition<?> beanDefinition, Argument<?> argument, String message);

68

69

public BeanDefinition<?> getBeanDefinition();

70

public Argument<?> getArgument();

71

}

72

```

73

74

## Configuration Exceptions

75

76

### ConfigurationException

77

78

Thrown when configuration-related errors occur.

79

80

```java { .api }

81

public class ConfigurationException extends RuntimeException {

82

public ConfigurationException(String message);

83

public ConfigurationException(String message, Throwable cause);

84

}

85

```

86

87

## Common Error Scenarios

88

89

### Missing Bean Errors

90

91

```java

92

import io.micronaut.context.ApplicationContext;

93

import io.micronaut.context.exceptions.NoSuchBeanException;

94

95

public class MissingBeanExample {

96

public static void main(String[] args) {

97

try (ApplicationContext context = ApplicationContext.run()) {

98

99

try {

100

// This will throw NoSuchBeanException if UserService is not registered

101

UserService service = context.getBean(UserService.class);

102

service.createUser("John");

103

104

} catch (NoSuchBeanException e) {

105

System.err.println("Bean not found: " + e.getBeanType().getSimpleName());

106

System.err.println("Available alternatives:");

107

108

// Try to find similar beans

109

context.getBeanDefinitions(Object.class).stream()

110

.filter(def -> def.getBeanType().getSimpleName().contains("Service"))

111

.forEach(def -> System.err.println(" - " + def.getBeanType().getName()));

112

}

113

}

114

}

115

}

116

```

117

118

### Multiple Bean Candidates

119

120

```java

121

import io.micronaut.context.ApplicationContext;

122

import io.micronaut.context.exceptions.NonUniqueBeanException;

123

import io.micronaut.inject.qualifiers.Qualifiers;

124

125

// Multiple implementations

126

@Singleton

127

public class EmailNotificationService implements NotificationService {

128

// Email implementation

129

}

130

131

@Singleton

132

public class SmsNotificationService implements NotificationService {

133

// SMS implementation

134

}

135

136

public class NonUniqueBeanExample {

137

public static void main(String[] args) {

138

try (ApplicationContext context = ApplicationContext.run()) {

139

140

try {

141

// This will throw NonUniqueBeanException

142

NotificationService service = context.getBean(NotificationService.class);

143

144

} catch (NonUniqueBeanException e) {

145

System.err.println("Multiple beans found for: " + e.getBeanType().getSimpleName());

146

System.err.println("Candidates:");

147

148

for (BeanDefinition<?> candidate : e.getPossibleCandidates()) {

149

System.err.println(" - " + candidate.getBeanType().getName());

150

}

151

152

// Resolve using qualifier

153

NotificationService emailService = context.getBean(

154

NotificationService.class,

155

Qualifiers.byName("email")

156

);

157

}

158

}

159

}

160

}

161

```

162

163

### Bean Instantiation Failures

164

165

```java

166

import io.micronaut.context.ApplicationContext;

167

import io.micronaut.context.exceptions.BeanInstantiationException;

168

169

@Singleton

170

public class ProblematicService {

171

172

public ProblematicService() {

173

// This constructor throws an exception

174

if (System.currentTimeMillis() % 2 == 0) {

175

throw new RuntimeException("Random initialization failure");

176

}

177

}

178

}

179

180

public class InstantiationErrorExample {

181

public static void main(String[] args) {

182

try (ApplicationContext context = ApplicationContext.run()) {

183

184

try {

185

ProblematicService service = context.getBean(ProblematicService.class);

186

187

} catch (BeanInstantiationException e) {

188

System.err.println("Failed to create bean: " + e.getBeanDefinition().getBeanType());

189

System.err.println("Cause: " + e.getCause().getMessage());

190

191

// Log full stack trace for debugging

192

e.printStackTrace();

193

}

194

}

195

}

196

}

197

```

198

199

### Dependency Injection Failures

200

201

```java

202

import io.micronaut.context.ApplicationContext;

203

import io.micronaut.context.exceptions.DependencyInjectionException;

204

205

@Singleton

206

public class ServiceWithDependency {

207

208

@Inject

209

public ServiceWithDependency(NonExistentService dependency) {

210

// This will fail because NonExistentService doesn't exist

211

}

212

}

213

214

public class DependencyInjectionErrorExample {

215

public static void main(String[] args) {

216

try (ApplicationContext context = ApplicationContext.run()) {

217

218

try {

219

ServiceWithDependency service = context.getBean(ServiceWithDependency.class);

220

221

} catch (DependencyInjectionException e) {

222

System.err.println("Dependency injection failed for: " +

223

e.getBeanDefinition().getBeanType().getSimpleName());

224

225

if (e.getArgument() != null) {

226

System.err.println("Failed argument: " + e.getArgument().getName() +

227

" (" + e.getArgument().getType().getSimpleName() + ")");

228

}

229

230

System.err.println("Reason: " + e.getMessage());

231

}

232

}

233

}

234

}

235

```

236

237

## Configuration Error Handling

238

239

### Property Resolution Errors

240

241

```java

242

import io.micronaut.context.ApplicationContext;

243

import io.micronaut.context.exceptions.ConfigurationException;

244

import io.micronaut.context.env.Environment;

245

246

public class ConfigurationErrorExample {

247

public static void main(String[] args) {

248

try (ApplicationContext context = ApplicationContext.run()) {

249

Environment env = context.getEnvironment();

250

251

try {

252

// This will throw ConfigurationException if property is missing

253

String requiredValue = env.getRequiredProperty("required.property", String.class);

254

255

} catch (ConfigurationException e) {

256

System.err.println("Configuration error: " + e.getMessage());

257

258

// Show available properties for debugging

259

System.err.println("Available properties:");

260

env.getPropertySources().forEach(source -> {

261

System.err.println(" Source: " + source.getName());

262

});

263

}

264

}

265

}

266

}

267

```

268

269

### Configuration Properties Validation

270

271

```java

272

import io.micronaut.context.ApplicationContext;

273

import io.micronaut.context.exceptions.BeanInstantiationException;

274

import jakarta.validation.ConstraintViolationException;

275

276

@ConfigurationProperties("database")

277

public class DatabaseConfig {

278

279

@NotBlank

280

private String url;

281

282

@Min(1)

283

@Max(100)

284

private int maxConnections;

285

286

// Getters and setters

287

}

288

289

public class ValidationErrorExample {

290

public static void main(String[] args) {

291

// Run without proper configuration

292

try (ApplicationContext context = ApplicationContext.run()) {

293

294

try {

295

DatabaseConfig config = context.getBean(DatabaseConfig.class);

296

297

} catch (BeanInstantiationException e) {

298

if (e.getCause() instanceof ConstraintViolationException) {

299

ConstraintViolationException validationError =

300

(ConstraintViolationException) e.getCause();

301

302

System.err.println("Configuration validation failed:");

303

validationError.getConstraintViolations().forEach(violation -> {

304

System.err.println(" " + violation.getPropertyPath() +

305

": " + violation.getMessage());

306

});

307

}

308

}

309

}

310

}

311

}

312

```

313

314

## Error Recovery Strategies

315

316

### Graceful Degradation

317

318

```java

319

import io.micronaut.context.ApplicationContext;

320

import io.micronaut.context.exceptions.NoSuchBeanException;

321

322

@Singleton

323

public class ResilientService {

324

325

private final NotificationService notificationService;

326

private final boolean notificationEnabled;

327

328

@Inject

329

public ResilientService(ApplicationContext context) {

330

// Try to get notification service, fall back to null if not available

331

NotificationService service = null;

332

boolean enabled = false;

333

334

try {

335

service = context.getBean(NotificationService.class);

336

enabled = true;

337

} catch (NoSuchBeanException e) {

338

System.warn.println("Notification service not available, continuing without notifications");

339

}

340

341

this.notificationService = service;

342

this.notificationEnabled = enabled;

343

}

344

345

public void processOrder(Order order) {

346

// Core processing always works

347

order.setStatus(OrderStatus.PROCESSED);

348

349

// Optional notification

350

if (notificationEnabled && notificationService != null) {

351

try {

352

notificationService.sendOrderConfirmation(order);

353

} catch (Exception e) {

354

System.err.println("Failed to send notification, but order was processed: " + e.getMessage());

355

}

356

}

357

}

358

}

359

```

360

361

### Optional Dependencies

362

363

```java

364

import io.micronaut.context.ApplicationContext;

365

import java.util.Optional;

366

367

@Singleton

368

public class FlexibleService {

369

370

private final Optional<CacheService> cacheService;

371

private final Optional<MetricsService> metricsService;

372

373

@Inject

374

public FlexibleService(ApplicationContext context) {

375

this.cacheService = context.findBean(CacheService.class);

376

this.metricsService = context.findBean(MetricsService.class);

377

}

378

379

public String getData(String key) {

380

// Try cache first if available

381

if (cacheService.isPresent()) {

382

String cached = cacheService.get().get(key);

383

if (cached != null) {

384

metricsService.ifPresent(metrics -> metrics.increment("cache.hit"));

385

return cached;

386

}

387

}

388

389

// Fetch from database

390

String data = fetchFromDatabase(key);

391

392

// Cache if service available

393

cacheService.ifPresent(cache -> cache.put(key, data));

394

metricsService.ifPresent(metrics -> metrics.increment("cache.miss"));

395

396

return data;

397

}

398

}

399

```

400

401

### Retry and Fallback

402

403

```java

404

import io.micronaut.context.ApplicationContext;

405

import io.micronaut.context.exceptions.BeanInstantiationException;

406

407

@Singleton

408

public class RetryableService {

409

410

private ExternalService externalService;

411

private final int maxRetries = 3;

412

413

@PostConstruct

414

public void initialize() {

415

// Retry bean creation with backoff

416

for (int attempt = 1; attempt <= maxRetries; attempt++) {

417

try {

418

this.externalService = createExternalService();

419

break;

420

} catch (BeanInstantiationException e) {

421

System.err.println("Attempt " + attempt + " failed: " + e.getMessage());

422

423

if (attempt == maxRetries) {

424

System.err.println("All attempts failed, using fallback service");

425

this.externalService = new FallbackExternalService();

426

} else {

427

// Wait before retry

428

try {

429

Thread.sleep(1000 * attempt);

430

} catch (InterruptedException ie) {

431

Thread.currentThread().interrupt();

432

break;

433

}

434

}

435

}

436

}

437

}

438

}

439

```

440

441

## Debugging Bean Issues

442

443

### Bean Resolution Debugging

444

445

```java

446

import io.micronaut.context.ApplicationContext;

447

import io.micronaut.inject.BeanDefinition;

448

449

public class BeanDebuggingUtils {

450

451

public static void debugBeanResolution(ApplicationContext context, Class<?> beanType) {

452

System.out.println("Debugging bean resolution for: " + beanType.getSimpleName());

453

454

// Check if bean exists

455

boolean exists = context.containsBean(beanType);

456

System.out.println("Bean exists: " + exists);

457

458

if (!exists) {

459

// Show similar beans

460

System.out.println("Similar beans:");

461

context.getBeanDefinitions(Object.class).stream()

462

.filter(def -> def.getBeanType().getSimpleName().contains(beanType.getSimpleName()))

463

.forEach(def -> System.out.println(" - " + def.getBeanType().getName()));

464

} else {

465

// Show bean details

466

Collection<BeanDefinition<?>> definitions = context.getBeanDefinitions(beanType);

467

System.out.println("Found " + definitions.size() + " bean(s):");

468

469

for (BeanDefinition<?> def : definitions) {

470

System.out.println(" Bean: " + def.getBeanType().getName());

471

System.out.println(" Scope: " + (def.isSingleton() ? "Singleton" : "Prototype"));

472

System.out.println(" Constructor args: " + def.getConstructorArguments().size());

473

System.out.println(" Injected methods: " + def.getInjectedMethods().size());

474

System.out.println(" Injected fields: " + def.getInjectedFields().size());

475

}

476

}

477

}

478

479

public static void listAllBeans(ApplicationContext context) {

480

System.out.println("All registered beans:");

481

482

context.getBeanDefinitions(Object.class).stream()

483

.sorted((a, b) -> a.getBeanType().getName().compareTo(b.getBeanType().getName()))

484

.forEach(def -> {

485

System.out.println(" " + def.getBeanType().getName() +

486

" [" + (def.isSingleton() ? "Singleton" : "Prototype") + "]");

487

});

488

}

489

}

490

```

491

492

### Exception Chaining Analysis

493

494

```java

495

import io.micronaut.context.exceptions.BeanContextException;

496

497

public class ExceptionAnalyzer {

498

499

public static void analyzeBeanException(BeanContextException e) {

500

System.err.println("=== Bean Exception Analysis ===");

501

System.err.println("Exception type: " + e.getClass().getSimpleName());

502

System.err.println("Message: " + e.getMessage());

503

504

// Analyze specific exception types

505

if (e instanceof NoSuchBeanException) {

506

NoSuchBeanException nsbe = (NoSuchBeanException) e;

507

System.err.println("Missing bean type: " + nsbe.getBeanType());

508

if (nsbe.getQualifier() != null) {

509

System.err.println("Required qualifier: " + nsbe.getQualifier());

510

}

511

512

} else if (e instanceof NonUniqueBeanException) {

513

NonUniqueBeanException nube = (NonUniqueBeanException) e;

514

System.err.println("Ambiguous bean type: " + nube.getBeanType());

515

System.err.println("Candidates (" + nube.getPossibleCandidates().size() + "):");

516

nube.getPossibleCandidates().forEach(candidate ->

517

System.err.println(" - " + candidate.getBeanType().getName()));

518

519

} else if (e instanceof BeanInstantiationException) {

520

BeanInstantiationException bie = (BeanInstantiationException) e;

521

if (bie.getBeanDefinition() != null) {

522

System.err.println("Failed bean: " + bie.getBeanDefinition().getBeanType());

523

}

524

}

525

526

// Show cause chain

527

Throwable cause = e.getCause();

528

int level = 1;

529

while (cause != null) {

530

System.err.println("Cause " + level + ": " + cause.getClass().getSimpleName() +

531

" - " + cause.getMessage());

532

cause = cause.getCause();

533

level++;

534

}

535

}

536

}

537

```