or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-execution.mdexception-handling.mdindex.mdlifecycle-management.mdplugin-system.mdproject-management.mdrepository-system.md

lifecycle-management.mddocs/

0

# Lifecycle Management

1

2

Maven Core lifecycle management provides APIs for orchestrating build lifecycles, managing execution plans, and coordinating the execution of build phases and goals. The lifecycle system is responsible for determining which plugins and goals to execute and in what order.

3

4

## Core Lifecycle Execution

5

6

### LifecycleExecutor Interface

7

8

Primary interface for lifecycle execution and planning.

9

10

```java { .api }

11

public interface LifecycleExecutor {

12

/**

13

* Calculate execution plan for specified tasks and projects.

14

*

15

* @param session Maven session containing projects and configuration

16

* @param tasks array of tasks (phases/goals) to execute

17

* @return execution plan containing ordered mojo executions

18

* @throws PluginNotFoundException if required plugin cannot be found

19

* @throws PluginResolutionException if plugin resolution fails

20

* @throws LifecyclePhaseNotFoundException if phase is not defined

21

* @throws LifecycleNotFoundException if lifecycle is not found

22

* @throws InvalidPluginDescriptorException if plugin descriptor is invalid

23

*/

24

MavenExecutionPlan calculateExecutionPlan(MavenSession session, String... tasks)

25

throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,

26

LifecycleNotFoundException, InvalidPluginDescriptorException;

27

28

/**

29

* Calculate execution plan for specific projects.

30

*

31

* @param session Maven session

32

* @param projects list of projects to plan for

33

* @param tasks array of tasks to execute

34

* @return execution plan

35

*/

36

MavenExecutionPlan calculateExecutionPlan(MavenSession session, List<MavenProject> projects, String... tasks)

37

throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException,

38

LifecycleNotFoundException, InvalidPluginDescriptorException;

39

40

/**

41

* Execute the Maven session.

42

*

43

* @param session Maven session to execute

44

*/

45

void execute(MavenSession session);

46

47

/**

48

* Execute forked executions for a mojo.

49

*

50

* @param mojoExecution mojo execution that requires forked executions

51

* @param session Maven session

52

* @return list of projects from forked executions

53

* @throws LifecycleExecutionException if execution fails

54

*/

55

List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)

56

throws LifecycleExecutionException;

57

}

58

```

59

60

**Lifecycle Execution Example:**

61

```java

62

import org.apache.maven.lifecycle.LifecycleExecutor;

63

import org.apache.maven.lifecycle.MavenExecutionPlan;

64

65

@Component

66

private LifecycleExecutor lifecycleExecutor;

67

68

public void executeLifecyclePhases(MavenSession session) throws Exception {

69

// Calculate execution plan for compile phase

70

MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(

71

session, "clean", "compile", "test");

72

73

System.out.println("Execution plan contains " + plan.size() + " mojo executions:");

74

for (MojoExecution execution : plan.getMojoExecutions()) {

75

System.out.println(" " + execution.getLifecyclePhase() + ": " +

76

execution.getPlugin().getArtifactId() + ":" + execution.getGoal());

77

}

78

79

// Execute the session (this will execute the calculated plan)

80

lifecycleExecutor.execute(session);

81

}

82

83

public void analyzeExecutionPlan(MavenSession session, String... goals) throws Exception {

84

MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(session, goals);

85

86

// Group executions by lifecycle phase

87

Map<String, List<MojoExecution>> executionsByPhase = new LinkedHashMap<>();

88

89

for (MojoExecution execution : plan) {

90

String phase = execution.getLifecyclePhase();

91

executionsByPhase.computeIfAbsent(phase, k -> new ArrayList<>()).add(execution);

92

}

93

94

// Display execution plan by phase

95

System.out.println("Execution Plan Analysis:");

96

for (Map.Entry<String, List<MojoExecution>> entry : executionsByPhase.entrySet()) {

97

System.out.println("Phase: " + entry.getKey());

98

for (MojoExecution execution : entry.getValue()) {

99

Plugin plugin = execution.getPlugin();

100

System.out.println(" -> " + plugin.getGroupId() + ":" +

101

plugin.getArtifactId() + ":" + execution.getGoal() +

102

" [" + execution.getExecutionId() + "]");

103

}

104

}

105

}

106

```

107

108

## Execution Plans

109

110

### MavenExecutionPlan Class

111

112

Represents an ordered sequence of mojo executions for a build.

113

114

```java { .api }

115

public class MavenExecutionPlan implements Iterable<MojoExecution> {

116

/**

117

* Get all mojo executions in the plan.

118

*

119

* @return list of mojo executions in execution order

120

*/

121

public List<MojoExecution> getMojoExecutions();

122

123

/**

124

* Get iterator over mojo executions.

125

*

126

* @return iterator for executions

127

*/

128

public Iterator<MojoExecution> iterator();

129

130

/**

131

* Get number of executions in the plan.

132

*

133

* @return number of mojo executions

134

*/

135

public int size();

136

137

/**

138

* Check if plan is empty.

139

*

140

* @return true if no executions in plan

141

*/

142

public boolean isEmpty();

143

144

/**

145

* Find mojo executions by plugin key.

146

*

147

* @param pluginKey plugin key (groupId:artifactId)

148

* @return list of matching executions

149

*/

150

public List<MojoExecution> getMojoExecutions(String pluginKey);

151

152

/**

153

* Get last mojo execution for a plugin.

154

*

155

* @param pluginKey plugin key

156

* @return last execution or null if not found

157

*/

158

public MojoExecution findLastInPhase(String pluginKey);

159

}

160

```

161

162

**Execution Plan Usage:**

163

```java

164

public void processExecutionPlan(MavenExecutionPlan plan) {

165

System.out.println("Processing execution plan with " + plan.size() + " executions");

166

167

// Iterate through all executions

168

for (MojoExecution execution : plan) {

169

Plugin plugin = execution.getPlugin();

170

System.out.println("Will execute: " + plugin.getArtifactId() +

171

":" + execution.getGoal() +

172

" in phase: " + execution.getLifecyclePhase());

173

}

174

175

// Find specific plugin executions

176

List<MojoExecution> compilerExecutions = plan.getMojoExecutions("org.apache.maven.plugins:maven-compiler-plugin");

177

if (!compilerExecutions.isEmpty()) {

178

System.out.println("Found " + compilerExecutions.size() + " compiler plugin executions:");

179

for (MojoExecution execution : compilerExecutions) {

180

System.out.println(" " + execution.getGoal() + " [" + execution.getExecutionId() + "]");

181

}

182

}

183

184

// Check for test execution

185

MojoExecution lastSurefireExecution = plan.findLastInPhase("org.apache.maven.plugins:maven-surefire-plugin");

186

if (lastSurefireExecution != null) {

187

System.out.println("Tests will be executed by: " + lastSurefireExecution.getExecutionId());

188

}

189

}

190

```

191

192

## Lifecycle Definitions

193

194

### Lifecycle Class

195

196

Represents a complete lifecycle definition with phases and default bindings.

197

198

```java { .api }

199

public class Lifecycle {

200

/**

201

* Get lifecycle identifier.

202

*

203

* @return lifecycle ID (e.g., "default", "clean", "site")

204

*/

205

public String getId();

206

207

/**

208

* Set lifecycle identifier.

209

*

210

* @param id lifecycle ID

211

*/

212

public void setId(String id);

213

214

/**

215

* Get ordered list of phases in this lifecycle.

216

*

217

* @return list of phase names in execution order

218

*/

219

public List<String> getPhases();

220

221

/**

222

* Set phases for this lifecycle.

223

*

224

* @param phases ordered list of phase names

225

*/

226

public void setPhases(List<String> phases);

227

228

/**

229

* Get default phase bindings for packaging types.

230

*

231

* @return map from packaging type to phase bindings

232

*/

233

public Map<String, LifecyclePhase> getDefaultPhases();

234

235

/**

236

* Set default phase bindings.

237

*

238

* @param defaultPhases map of packaging-specific bindings

239

*/

240

public void setDefaultPhases(Map<String, LifecyclePhase> defaultPhases);

241

242

/**

243

* Get default bindings for a specific packaging type.

244

*

245

* @param packaging packaging type (e.g., "jar", "war", "pom")

246

* @return phase bindings for the packaging type

247

*/

248

public Map<String, String> getDefaultGoals(String packaging);

249

}

250

```

251

252

### DefaultLifecycles Class

253

254

Container for standard Maven lifecycles.

255

256

```java { .api }

257

public class DefaultLifecycles {

258

/**

259

* Get all standard lifecycles.

260

*

261

* @return list of default lifecycles (default, clean, site)

262

*/

263

public List<Lifecycle> getLifeCycles();

264

265

/**

266

* Get lifecycle by ID.

267

*

268

* @param lifecycleId lifecycle identifier

269

* @return lifecycle instance or null if not found

270

*/

271

public Lifecycle get(String lifecycleId);

272

273

/**

274

* Get phases for a specific lifecycle.

275

*

276

* @param lifecycleId lifecycle identifier

277

* @return ordered list of phase names

278

*/

279

public List<String> getLifecyclePhases(String lifecycleId);

280

}

281

```

282

283

**Lifecycle Definition Example:**

284

```java

285

import org.apache.maven.lifecycle.Lifecycle;

286

import org.apache.maven.lifecycle.DefaultLifecycles;

287

288

@Component

289

private DefaultLifecycles defaultLifecycles;

290

291

public void inspectLifecycles() {

292

// Get all standard lifecycles

293

List<Lifecycle> lifecycles = defaultLifecycles.getLifeCycles();

294

295

for (Lifecycle lifecycle : lifecycles) {

296

System.out.println("Lifecycle: " + lifecycle.getId());

297

System.out.println("Phases: " + lifecycle.getPhases());

298

299

// Show default bindings for common packaging types

300

String[] packagingTypes = {"jar", "war", "pom", "maven-plugin"};

301

for (String packaging : packagingTypes) {

302

Map<String, String> bindings = lifecycle.getDefaultGoals(packaging);

303

if (!bindings.isEmpty()) {

304

System.out.println(" Default bindings for " + packaging + ":");

305

for (Map.Entry<String, String> binding : bindings.entrySet()) {

306

System.out.println(" " + binding.getKey() + " -> " + binding.getValue());

307

}

308

}

309

}

310

}

311

}

312

313

public void analyzeDefaultLifecycle() {

314

Lifecycle defaultLifecycle = defaultLifecycles.get("default");

315

if (defaultLifecycle != null) {

316

System.out.println("Default lifecycle phases:");

317

List<String> phases = defaultLifecycle.getPhases();

318

for (int i = 0; i < phases.size(); i++) {

319

System.out.println((i + 1) + ". " + phases.get(i));

320

}

321

322

// Show JAR packaging bindings

323

Map<String, String> jarBindings = defaultLifecycle.getDefaultGoals("jar");

324

System.out.println("\nDefault JAR packaging bindings:");

325

for (Map.Entry<String, String> entry : jarBindings.entrySet()) {

326

System.out.println(" " + entry.getKey() + " -> " + entry.getValue());

327

}

328

}

329

}

330

```

331

332

## Forked Executions

333

334

Forked executions allow mojos to trigger separate lifecycle executions, typically used for pre-integration testing or parallel builds.

335

336

```java { .api }

337

public interface LifecycleExecutor {

338

/**

339

* Execute forked executions for a mojo that requires them.

340

*

341

* @param mojoExecution the mojo execution requesting forked executions

342

* @param session Maven session

343

* @return list of projects resulting from forked executions

344

* @throws LifecycleExecutionException if forked execution fails

345

*/

346

List<MavenProject> executeForkedExecutions(MojoExecution mojoExecution, MavenSession session)

347

throws LifecycleExecutionException;

348

}

349

```

350

351

**Forked Execution Example:**

352

```java

353

public void handleForkedExecution(MojoExecution mojoExecution, MavenSession session) throws Exception {

354

// Check if mojo has forked executions defined

355

MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

356

357

if (mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null) {

358

System.out.println("Mojo " + mojoExecution.getGoal() + " requires forked execution");

359

360

// Execute forked executions

361

List<MavenProject> forkedProjects = lifecycleExecutor.executeForkedExecutions(

362

mojoExecution, session);

363

364

System.out.println("Forked execution completed for " + forkedProjects.size() + " projects:");

365

for (MavenProject project : forkedProjects) {

366

System.out.println(" " + project.getGroupId() + ":" + project.getArtifactId());

367

}

368

}

369

}

370

371

// Example: Integration test with forked lifecycle

372

public void runIntegrationTestsWithForking(MavenSession session) throws Exception {

373

// Find failsafe plugin execution (commonly uses forked executions)

374

MavenExecutionPlan plan = lifecycleExecutor.calculateExecutionPlan(

375

session, "pre-integration-test", "integration-test", "post-integration-test");

376

377

for (MojoExecution execution : plan) {

378

Plugin plugin = execution.getPlugin();

379

380

if ("maven-failsafe-plugin".equals(plugin.getArtifactId()) &&

381

"integration-test".equals(execution.getGoal())) {

382

383

System.out.println("Running integration tests with forked lifecycle");

384

385

// This may trigger forked executions to prepare test environment

386

List<MavenProject> forkedProjects = lifecycleExecutor.executeForkedExecutions(

387

execution, session);

388

389

if (!forkedProjects.isEmpty()) {

390

System.out.println("Forked executions prepared " + forkedProjects.size() +

391

" projects for integration testing");

392

}

393

}

394

}

395

}

396

```

397

398

## Custom Lifecycle Participants

399

400

### AbstractMavenLifecycleParticipant

401

402

Base class for creating custom lifecycle participants that can hook into the build process.

403

404

```java { .api }

405

public abstract class AbstractMavenLifecycleParticipant {

406

/**

407

* Called before projects are built. Allows modification of projects

408

* and execution request before lifecycle execution begins.

409

*

410

* @param session Maven session

411

* @throws MavenExecutionException if participant processing fails

412

*/

413

public void afterProjectsRead(MavenSession session) throws MavenExecutionException {

414

// Default implementation does nothing

415

}

416

417

/**

418

* Called after session is started but before lifecycle execution.

419

*

420

* @param session Maven session

421

* @throws MavenExecutionException if participant processing fails

422

*/

423

public void afterSessionStart(MavenSession session) throws MavenExecutionException {

424

// Default implementation does nothing

425

}

426

427

/**

428

* Called after session ends, regardless of success or failure.

429

*

430

* @param session Maven session

431

* @throws MavenExecutionException if participant processing fails

432

*/

433

public void afterSessionEnd(MavenSession session) throws MavenExecutionException {

434

// Default implementation does nothing

435

}

436

}

437

```

438

439

**Custom Lifecycle Participant Example:**

440

```java

441

import org.apache.maven.AbstractMavenLifecycleParticipant;

442

import org.apache.maven.MavenExecutionException;

443

import org.apache.maven.execution.MavenSession;

444

import org.codehaus.plexus.component.annotations.Component;

445

446

@Component(role = AbstractMavenLifecycleParticipant.class, hint = "custom-participant")

447

public class CustomLifecycleParticipant extends AbstractMavenLifecycleParticipant {

448

449

@Override

450

public void afterProjectsRead(MavenSession session) throws MavenExecutionException {

451

System.out.println("Custom lifecycle participant: projects read");

452

453

// Modify projects before build starts

454

for (MavenProject project : session.getProjects()) {

455

// Add custom properties

456

project.getProperties().setProperty("custom.build.timestamp",

457

String.valueOf(System.currentTimeMillis()));

458

459

// Modify build configuration if needed

460

if ("jar".equals(project.getPackaging())) {

461

System.out.println("Customizing JAR project: " + project.getArtifactId());

462

// Custom logic for JAR projects

463

}

464

}

465

}

466

467

@Override

468

public void afterSessionStart(MavenSession session) throws MavenExecutionException {

469

System.out.println("Custom lifecycle participant: session started");

470

471

// Log build information

472

System.out.println("Build started for " + session.getProjects().size() + " projects");

473

System.out.println("Goals: " + session.getRequest().getGoals());

474

475

// Validate build environment

476

validateBuildEnvironment(session);

477

}

478

479

@Override

480

public void afterSessionEnd(MavenSession session) throws MavenExecutionException {

481

System.out.println("Custom lifecycle participant: session ended");

482

483

// Cleanup or post-build processing

484

long buildTime = System.currentTimeMillis() - session.getRequest().getStartTime().getTime();

485

System.out.println("Total build time: " + buildTime + "ms");

486

487

// Generate custom reports or notifications

488

generateBuildReport(session);

489

}

490

491

private void validateBuildEnvironment(MavenSession session) throws MavenExecutionException {

492

// Custom validation logic

493

String javaVersion = System.getProperty("java.version");

494

if (javaVersion.startsWith("1.8")) {

495

throw new MavenExecutionException("Java 8 is not supported for this build",

496

(Throwable) null);

497

}

498

}

499

500

private void generateBuildReport(MavenSession session) {

501

// Custom reporting logic

502

System.out.println("=== Build Report ===");

503

for (MavenProject project : session.getProjects()) {

504

System.out.println("Project: " + project.getName() + " - " + project.getVersion());

505

}

506

}

507

}

508

```

509

510

## Types

511

512

```java { .api }

513

public interface LifecyclePhase {

514

List<Plugin> getPlugins();

515

void addPlugin(Plugin plugin);

516

String toString();

517

}

518

519

public class LifecyclePhaseNotFoundException extends Exception {

520

public LifecyclePhaseNotFoundException(String message);

521

public LifecyclePhaseNotFoundException(String message, Throwable cause);

522

}

523

524

public class LifecycleNotFoundException extends Exception {

525

public LifecycleNotFoundException(String message);

526

public LifecycleNotFoundException(String message, Throwable cause);

527

}

528

529

public class InvalidPluginDescriptorException extends Exception {

530

public InvalidPluginDescriptorException(String message);

531

public InvalidPluginDescriptorException(String message, Throwable cause);

532

}

533

534

public interface MojoDescriptor {

535

String getExecutePhase();

536

String getExecuteGoal();

537

String getExecuteLifecycle();

538

boolean requiresProject();

539

boolean requiresReports();

540

boolean aggregator();

541

boolean requiresDirectInvocation();

542

boolean requiresOnline();

543

boolean inheritedByDefault();

544

String getPhase();

545

String getSince();

546

String getDeprecated();

547

}

548

549

public interface LifecycleMapping {

550

Map<String, String> getPhases(String packaging);

551

List<String> getOptionalMojos(String packaging);

552

}

553

554

public interface LifecycleMappingDelegate {

555

Map<String, List<MojoExecution>> calculateLifecycleMappings(MavenSession session,

556

MavenProject project, Lifecycle lifecycle, String lifecyclePhase)

557

throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,

558

MojoNotFoundException, InvalidPluginDescriptorException;

559

}

560

```